for explanation about
-StAX specification). As such, reader and writer instances are usually
-created using STaX factory methods; this is the recommended method.
-
-StAX specification defines couple of methods for specifying which StAX
-implementation to use (properties file, service entries in jar file,
-System properties); in each case you have to basically define 3 classes:
-one that implements XMLInputFactory, one that implements XMLOutputFactory,
-and third one that implements XMLEventFactory (to potentially be used by
-XMLInputFactory implementation).
-[sidenote: current version of Woodstox really only needs first two for
- correct operation; internally it does not make use of the event factory].
-
-For Woodstox classes are, respectively:
-
-com.ctc.wstx.stax.WstxInputFactory
-com.ctc.wstx.stax.WstxOutputFactory
-com.ctc.wstx.stax.WstxEventFactory
-
-Woodstox jar files include service entries that will effectively also
-specify Stax implementation classes, instead of system properties
-(although note that system properties have preference over service
-entries). This works well if you only include a single Stax implementation
-jar in the classpath.
-
-However, if you have multiple StAX implementations, you may have to
-specifically set/override system properties to point to the implementation
-you want: from Java code it can be done by calling:
-
-System.setProperty("javax.xml.stream.XMLInputFactory",
- "com.ctc.wstx.stax.WstxInputFactory");
-System.setProperty("javax.xml.stream.XMLOutputFactory",
- "com.ctc.wstx.stax.WstxOutputFactory");
-System.setProperty("javax.xml.stream.XMLEventFactory",
- "com.ctc.wstx.stax.WstxEventFactory");
-
-when your application starts (or the class that access factories is
-initialised). Alternatively, you can also set system properties via command
-line switches when starting your application
-(-Djavax.xml.stream.XMLInputFactory=javax.xml.stream.XMLInputFactory
- and so on).
-
-And of course the simplest possible way is to just refer to the Woodstox
-implementations of the input factories directly:
-
- XMLInputFactory ifact = new WstxInputFactory();
-
-
-== Using Woodstox XML parser without StAX ==
-
-It is also possible to directly instantiate objects (specifically,
-Woodstox implementations of Stax factories), but the API (class
-names, constructors, factory methods) is not guaranteed to remain
-static between major releases.
-It is possible that in future some public factory methods will be added,
-to allow creating more specialized instances, to overcome some of
-StAX API limitations.
-
-It is NOT possible to use Woodstox without having StAX classes
-available, since many Woodstox classes implement or extend
-StAX interfaces/abstract classes.
-
-
-== Dependencies ==
-
-Due to implementing StAX API, Woodstox has dependency to StAX API JAR
-file. For up to JDK 1.5.0, StAX is not (yet?) part of J2SE or J2EE, so you
-have to download StAX jar separately.
-
-Woodstox version up to 3.0 can be run on JDKs 1.2 and up.
-Some of features of later JDKs are optionally used if available;
-these generally are "nice-to-have"
-features, such as chained Exceptions (1.4+), order-retaining definitions
-for entities and notations (1.4+) and so on.
-The only caveat is that compiling Woodstox has to be done using javac
-with 1.4 libs, or alternatively, by modifying Ant build.xml to ignore
-the few class files that refer to 1.3/1.4 features (found in
-com.ctc.wstx.compat package).
-
-Woodstox version after 3.0.x will require JDK 1.4 or higher as the
-baseline. There are no plans to require JDK 1.5 currently.
-
-
-== Performance ==
-
-Full discussion on best practices for good performance needs to be done
-outside scope of a simple document, but here are some basic things regarding
- performance:
-
-* For optimal performance, factory instances should be reused whenever
- possible.
- Since factory objects (XMLInputFactory, XMLOutputFactory) are thread-safe
- after being initialized and configured, there is no risk sharing
- them (but only after proper initialization!). It is thus often possible
- to share a single input and single output factory instances for the
- whole application. The reasons why factory reusing is very important
- for performance are:
- o There is significant overhead in constructing new factories when
- using Stax interface (but note: no significant overhead when just
- instantiating Woodstox factories themselves)
- o Most caching is done on per-factory basis: specifically, symbol
- tables are cached this way. Similarly DTD caches are per-factory.
-* It is important to CLOSE XMLStreamReader and XMLStreamWriter instances
- after they are no longer needed. This allows readers/writers to
- release internal buffers they use -- this is especially important when
- processing small documents, since relative overhead of buffer allocation
- is most significant for these use cases.
-* Many input factory configuration settings do have effect on performance.
- For obtaining highest performance, there is a specific profile that can
- be set when 100% XML specs compatibility is not needed (default settings
- support 100% XML compatibility).
diff -Nru libwoodstox-java-4.1.3/release-notes/VERSION libwoodstox-java-5.1.0/release-notes/VERSION
--- libwoodstox-java-4.1.3/release-notes/VERSION 2012-04-24 04:38:20.000000000 +0000
+++ libwoodstox-java-5.1.0/release-notes/VERSION 2018-03-31 01:33:28.000000000 +0000
@@ -1,641 +1,41 @@
-Version: 4.1.3
-
-Release date: 23-Apr-2012
-
-Description:
- Third patch release for 4.1
-
-Problems fixed:
-
-* [WSTX-271] DOMWrappingWriter.writeComment() creating CDATASection, not Comment
- (reported by Martin V)
-* [WSTX-276] 'InputConfigFlags.CFG_NORMALIZE_LFS' flag conflicts with 'CFG_AUTO_CLOSE_INPUT'
- (reported by Andreas V)
+Project: woodstox
------------------------------------------------------------------------
-== History: ==
+=== Releases ===
------------------------------------------------------------------------
-4.1.2 [27-Aug-2011]
-
-Problems fixed:
-
-* [WSTX-267] P_NORMALIZE_LFS mis-mapped
- (reported by Mike S)
-* [WSTX-268] Missing namespace information when unmarshalling from DOMSource
- (reported by Blaise D)
-* [WSTX-270] Allow changing whether prefix for default namespace
- is returned as "" (4.x default) or null (which apparently is what
- latest Stax spec says) using WstxInputProperties.
- (requested by Ivan)
-
-4.1.1 [27-Jan-2011]
-
-Problems fixed:
-
-- All fixes from 4.0.x up to 4.0.10
-
-4.1.0 [13-Dec-2010]
-
-Problems fixed:
-
-* [WSTX-201]: XMLStreamReader.isCharacters() can return inconsistent
- value compared to XMLStreamReader.getEventType()
- (reported by Andreas V)
-* [WSTX-254]: Stax2ReaderAdapter2.getDepth() incorrect after calling
- getElementAs (from StaxMate bug)
-
-Improvements:
-
-* [WSTX-237] Add size limit to InternCache
-* [WSTX-248] Java URL.hashCode() cause issues with DTD caching
- (reported by Christophe C)
-* [WSTX-251] Improve extensibility of XMLStreamWriter construction
- (suggested by Eric D)
-* [WSTX-252] Add EmptyElementHandler to allow customizing whether
- empty elements can be written, on per-tag basis
- (suggested by Eric D)
-* Rewrote attribute parsing/collection part to use separate wrapper
- classes (instead of primitive arrays); to support easier modifications
- and custom additions to collected attribute information.
-
-4.0.9 [08-Oct-2010]
-
-Problems fixed:
-
-* [WSTX-244] DOMWrappingReader sometimes duplicates text content
- (reported by Laszlo V)
-* [WSTX-246] DOMWrappingReader returns null Location
-* [WSTX-249] TextAccumulator had a bug corrupting text
- (reported by Habib C)
-
-4.0.8 [05-May-2010]
-
- Improvements:
-
- * [WSTX-206] Provide a way to configure SAX parser with all config
- settings available to Stax readers (add WstxSAXParser.getStaxConfig())
- (suggested by StŽphane C)
- * [WSTX-234] Restore feature WstxInputProperties.NORMALIZE_LFS; add
- WstxInputProperties.TREAT_CHAR_REFS_AS_ENTS
- (requested by Peter S)
-
- Problems fixed:
-
- * [WSTX-220]: Issues in cases where excessive intern()ing causes
- synchronization problems; reduce contention by splitting sync block
- (reported by Rajeswar R)
- * [WSTX-226]: SAX parser was ignoring passed encoding.
- (reported by Andreas V)
- * [WSTX-228]: Property WstxOutputProperties.P_OUTPUT_ESCAPE_CR
- not used for attribute content
- (reported by Brian S)
- * [WSTX-236]: Make WstxInputLocation Serializable
- (suggested by Myles B)
-
-4.0.7 [16-Dec-2009]
-
- * [WSTX-224]: getElementAsBinary() fails when reading large amounts of
- data (in coalescing mode)
- (reported by Alexander R)
-
-4.0.6 [01-Oct-2009]
-
- Problems fixed:
-
- * [WSTX-211]: Failure to parse long CDATA section properly when
- using XMLStreamReader.getElementText(), non-coalescing
- (reported by Kevin B)
-
-4.0.5 [09-Jun-2009]
-
- Problems fixed:
-
- * [WSTX-207]: Schema factory failing to load schema if filename has
- characters that need to be escaped when converted to URL
- (reported by Arun K)
- * [WSTX-208]: Value of default attributes not found using
- XMLStreamReader.getAttributeValue(String,String)
- (reported by Jack R)
- * [WSTX-209]: Validation issues not reported to validation problem reporter
- (reported and fixed by Benson M)
-
-4.0.4 [07-May-2009]
+5.1.0 (31-Mar-2018)
- Problems fixed:
+#23: Text content is not validated correctly when copying events to `XmlStreamWriter`
+ (reported by hxc9@github)
+#43: `CompactStartElement` appears to incorrectly classify attributes as default
+ (reported by Jonathan T)
+- Add `Automatic-Module-Name` indicator in jar metadata, for Java 9
+- Upgrade `stax2-api` dependency to 4.1 (from 3.1)
- * [WSTX-200]: NPE when validating partial documents (sub-trees)
- (reported by Benson M)
- * [WSTX-202]: BijectiveNsMap#findPrefixByUri doesn't handle masked
- namespace declarations correctly
- (reported by Andreas V)
- * [WSTX-204] Custom entity resolver setting was not working with
- SAX API (due to JDK impl idiocy)
- (reported by Stéphane Claret)
+5.0.3 (23-Aug-2016)
-4.0.3 [04-Mar-2009]
+#13: `BasicStreamReader.getElementText()` behavior doesn't match Java documentation
+ (reported by Caleb-An@github)
+#15: `BasicStreamReader` should use `WstxUnexpectedCharException` instead of WstxParsingException
+ (reported by dima-kapustin@github)
+#16: Incorrect validation error(s) only using Stax2 writer
+ (reported by hxc9@github)
+#21: 500 characters limit when calling XMLStreamReader#getText() after CDATA event
+ (reported by elrodro83@github)
- Problems fixed:
+5.0.2 (10-Dec-2015)
- * [WSTX-191] Validation failure with W3C Schema, empty text
- (reported by Yves M)
+#10: Stax 4.0.0 is not compatible with Woodstox 5.0.1
+ (reported by naveengopi@github)
-4.0.2 [25-Feb-2009]
+5.0.1 (02-Apr-2015)
- Problems fixed:
+#3: Initial 5.0.0 release did not contain class files (d'oh!)
+ (reported by norrisjeremy@github)
+#4: Fix validation of text for an XMLStreamWriter
+ (reported by Wilco G, wgreven-ibr@github)
- * [WSTX-188] Could get an ArrayIndexOutOfBounds exception for
- StartElement.getAttributeByName() under specific conditions
- (reported by Roger W)
- * [WSTX-190]: NPE with DTD validator, missing attribute.
- (reported by Andreas V)
-
-4.0.1 [29-Jan-2009]
-
- Problems fixed:
-
- * A bug in Stax2 RI CharArrayBase64Decoder was skipping part of
- input under certain conditions; did not occur in stax2 test
- suite, but did happen for another Stax2 implementation.
- * There were many problems with Maven dependencies; specifically it looks
- like support for version ranges is hard to make work with somewhat
- manual release process in use now. Thus changed dependencies to use
- exact versions for now (until 5.0?)
-
-4.0.0 [01-Jan-2009]
-
- The first official release: no major changes over 3.9.9-3.
- However, here is a summary of work since 3.2.
- (For details refer to release notes for preceding release candidates)
-
- Major new functionality:
-
- * W3C Schema Validation support
- * Typed Access API (org.codehaus.stax2.typed.*), including:
- * TypedXMLStreamReader, TypedXMLStreamWriter (reading and writing)
- * Types based on W3C Schema Datatypes, supporting:
- * Simple values (int, long, float, double, boolean, QName)
- * Array values of integral numeric types
- * Binary support for base64 encoded content
- * Additional extension methods for efficient custom decoding.
-
- Interoperability improvements:
-
- * DOM-compatibility: Namespace-repairing mode implemented for DOM-backed
- stream writers (ones built for DOMResult)
- * OSGi: Woodstox jars are now OSGi bundles (as well as supporting MSV
- jars when needed for validation)
- * Maven: split core woodstox jar and stax2 api jar, relationship now
- properly modelled (including dependencies to MSV jars)
-
- New configuration properties:
-
- * WstxOutputProperties.P_ADD_SPACE_AFTER_EMPTY_ELEM: whether to add space
- between name of empty tag and following "/>".
- * WstxOutputProperties.P_AUTOMATIC_END_ELEMENTS: whether stream writers
- closes open xml tree upon stream writer close:
- * WstxOutputProperties.P_OUTPUT_INVALID_CHAR_HANDLER to allow for
- replacing "invalid XML characters" on output.
-
- Other improvements:
-
- * Implement XMLEvent.equals() and .hashCode() to allow for reliable
- comparisons of event objects.
- * Add direct support for Stax2ByteArraySource for improved performance
- when used instead of ByteArrayInputStream.
-
- Compatibility changes:
-
- * JDK: minimum required now 1.4
- * Stax 1.0 API:
- * All empty/missing namespace/prefix values now reported as "", not null
- * WstxInputFactory.IS_COALESCING defaults to 'false' (was erroneously
- defaulting to 'true')
- * Removed deprecated properties P_NORMALIZE_LFS and P_NORMALIZE_ATTR_VALUES
-
-------------------------------------------------------------------------
-
-3.9.9-3 [26-Dec-2008]
-
- API changes:
-
- * Changed passing of Base64Variant argument: since it's an optional argument
- it should come after mandatory ones (wasn't with earlier RCs).
-
- Problems fixed:
-
- * [WSTX-182], StreamResult with only SystemId did not work.
- (reported by Christoper P-S)
- * [WSTX-183] Trying to create DOM-backed writer with DOM Element (as opposed
- to Document) failed, due to trying to attach the element.
- (reported by Christoper P-S)
-
-3.9.9-2 [17-Dec-2008]
-
- Problems fixed:
-
- * [WSTX-177] Added support for accessing Stax2 factories (input, output,
- validation schema) through OSGi services interface.
- * [WSTX-178] Source code distribution did not have an intervening "[artifact]-[version]"
- directory, which means that when unexpanding, contents may spill in unexpected places
- * [WTSX-179] Problem with XMLStreamReader.getElementText(), where
- data may be corrupt under some situations (could also affect
- typed access methods similarly).
-
-3.9.9-1 [21-Nov-2008]
-
- Problems fixed:
-
- * [WTSX-121] Ordering of NOTATION definitions and ATTLIST references
- should not matter
- * [WTSX-142] Ordering of NOTATION definitions and ENTITY references
- should not matter
- * [WSTX-154] XMLStreamReader, XMLStreamWriter implementations were
- quietly discarding XMLStreamException thrown by XMLReporter.
-
- New functionality:
-
- * [WSTX-50] Improve handling of base URIs; notation and entity declarations, doc property.
- * [WSTX-148] Implement XMLEvent.equals() and .hashCode() to allow
- for easy comparisons.
- (requested by Sylvain L)
- * [WSTX-150] Add stream reader AND writer delegates for Stax2.
- * [WSTX-151] Generic typed access methods (getElementAs(), getAttributeAs())
- added to TypedXMLStreamReader.
- * [WSTX-152] Add OSGi headers to the jar manifest.
- (requested by Romain D)
- * [WSTX-157] Add XMLReporter2 to allow for extended access to
- information about non-fatal problems (including validation probs)
- * [WSTX-163] Add XMLStreamWriter2.closeCompletely()
- * [WSTX-165] Add property (WstxOutputProperties.P_AUTOMATIC_END_ELEMENTS)
- to allow enabling/disabling automatic addition of end elements
- when closing stream writer
- (requested by Ian B)
- * [WSTX-166] Add direct support for Stax2ByteArraySource for improved
- performance. Measured speedup 5-10% compared to using ByteArrayInputStream.
- * [WSTX-167] Add new property (WstxOutputProperties.P_OUTPUT_INVALID_CHAR_HANDLER)
- which can be used to replace invalid characters (such as Ascii control
- characters) from within content to output.
- * [WSTX-169] Add support for alternative (non-standard) Base64 encoding
- variants.
- * [WSTX-175] Add OSGi support for bundled MSV jars.
-
-3.9.2 [06-May-2008]
-3.9.1 [16-Mar-2008]
-3.9.0 [23-Nov-2007]
-
- New functionality (major):
-
- * [WSTX-137] Add W3C Schema validation support using MSV.
- * Reference implementation of Stax2 API now included under
- org.codehaus.stax2.ri (implements classes that can be implemented
- in generic way, making use of existing Stax 1.0 implementation
- or other Stax2 classes)
- * Partial/preliminary Stax2 Typed Access API, implementation (including
- configurable value encoder): supports booleans, ints, longs, for
- element and attribute content.
-
- New functionality (minor):
-
- * [WSTX-125] Adding of space between empty element, and closing
- "/>" is now optional, configurable using
- 'WstxOutputProperties.P_ADD_SPACE_AFTER_EMPTY_ELEM'.
- * Converted Woodstox-specific property WstxInputProperties.P_LAZY_PARSING
- to XMLInputFactory2.P_LAZY_PARSING (stax2 API).
- * More complete Stax2 API ref. impl, adding generic XMLEventReader
- implementation.
-
- Problems fixed:
-
- * [WSTX-120] By default, content fixing is now disabled, to
- maximize interoperability, and to follow "principle of least
- surprise" (i.e. avoid confusion arising from the stream writer
- outsmarting developer)
- * [WSTX-139] DOMWrappingWriter now implements repairing mode.
- * [WSTX-140] Default settings for WstxInputFactory.IS_COALESCING
- changed to Boolean.FALSE as per Stax specs; was defaulting to
- true by accident
-
- Clean-up:
-
- * Removed compatibility classes from under com.ctc.wstx.compat,
- since baseline JDK requirement is now 1.4, and workarounds are
- not needed (for now?)
- * Removed deprecated properties P_NORMALIZE_LFS and
- P_NORMALIZE_ATTR_VALUES, and needed code support.
- * [WSTX-105] Transformed the only existing input-side feature
- (FEAT_DTD_OVERRIDE) into matching input-side property
- (XMLInputFactoty2.P_OVERRIDE_DTD).
- * [WSTX-127] Stax API specification compatibility improvements:
- (also resolves [WSTX-57])
- * Missing prefixes now reported as "", not nulls.
- * "No namespace" now reported as "", not null.
- * Changing behavior of XMLStreamReader.getProperty() slightly (but within
- constraints of Stax 1.0 API specification): requesting value of
- an unknown property will now return null, instead of throwing an
- exception.
-
-------------------------------------------------------------------------
-
-3.2.8 [26-Dec-2008]
-
- Problems fixed:
-
- * [WSTX-172] WstxInputFactory and WstxOutputFactory were final, should not be.
- * [WSTX-174] Some old App servers have broken QName impl, are missing
- 3-arg constructor
- (requested by Arash A)
-
-3.2.7 [02-Sep-2008]
-
- Problems fixed:
-
- * [WSTX-145] DOMWrappingReader was not implementing coalescing mode.
- (reported by David C)
- * [WSTX-156] Pass XMLValidationProblem as 'relatedInformation' object
- in call XMLReporter.report(...)
- * [WSTX-158] XMLStreamReader.isWhiteSpace() returns potentially incorrect
- value when text segments starts with an entity
- (reported by Daniel R)
- * [WSTX-162] Name/namespace-URI interning not enabled for DOM-backed
- readers, getProperty() claims they are
- (reported by Pawel L)
- * Stax2ReaderAdapter.getDepth() was off by one (too low) for
- END_ELEMENT (causing problems for StaxMate)
- * [WSTX-164] Some XMLStreamReader.getAttributeXxx() methods were not
- properly checking validity of passed-in index argument.
-
-3.2.6 [01-Jun-2008]
-
- Problems fixed:
-
- * [WSTX-144] Problem when trying to output namespace declaration using
- a DOMResult-backed writer.
- (reported by Martin V)
- * [WSTX-153] XMLReporter not getting called for non-fatal validation errors
- (reported by Eduardo R-R)
- * [WSTX-155] NPE after reporting a missing #REQUIRED attribute.
- (reported by Eduardo R-R)
-
-3.2.5 [23-Apr-2008]
-
- Problems fixed:
-
- * [WSTX-146] XMLStreamWriter implementation was using encoding
- returned by OutputStreamWriter as is; and JDK was reporting
- legacy encodings. Needed to normalize encoding.
- (reported by Jim A)
-
- Improvements:
-
- * Added support for property:
- "http://java.sun.com/xml/stream/properties/implementation-name"
- it is now recognized as a synonym of XMLStreamProperties2.XSP_IMPLEMENTATION_NAME
-
-3.2.4 [17-Jan-2008]
-
- Problems fixed:
-
- * [WSTX-141]: Copying of CDATA events, using XMLEventWriter, was
- producing garbled output.
- (reported by Frank B)
- * [WSTX-143]: UTF8Reader had a bug in handling of DEL (127) character
- at buffer boundary.
- (report by Matt G)
-
-3.2.3 [14-Nov-2007]
-
- Problems fixed:
-
- * [WSTX-132]: NPE in BaseNsStreamWriter if event writer managed to
- pass in null namespace URI.
- * [WSTX-134]: Bug in DOMWrappingReader.isWhiteSpace implementation
- (reported by Yoon-Je C)
- * [WSTX-135]: Incorrect namespace binding for parent element, for
- repairing namespace writer.
- (reported by Yoon-Je C)
- * [WSTX-138]: Sub-optimal error messaging for incompatible encoding
- declaration, physical encoding used (EBCDIC vs UTF-x)
- (reported by Wouter C)
-
-3.2.2 [26-Sep-2007]
-
-Description:
- Second patch release for 3.2.
-
- Problems fixed:
-
- * [WSTX-104] Added missing support for outputting to a DOM tree (via
- XMLOutputFactory.createXMLStreamWriter(DOMSource)).
-
- Newfunctionality:
-
- * [WSTX-122] Adding support for EBCDIC encoding(s), using a
- simple bootstrapper to process xml declaration, then use
- JDK default codec.
-
-3.2.1 [03-Apr-2007]
-
- Problems fixed:
-
- * Added deprecation marker for Wstx properties that will not be
- supported in 4.0
- * [WSTX-106] Descriptions missing from many wrapped IOExceptions;
- specifically obscuring some character validity failures
- (reported by Sami D)
- * [WSTX-108] Maven pom files were missing info (license, org etc)
- (reported by Daniel K)
- * [WSTX-109], a bug in xml declaration handling in multi-doc mode
- (reported by Abde S)
- * [WSTX-110] Exception chaining would itself cause an exception,
- on some platforms.
- (reported by Erik Bergersjö)
- * [WSTX-111] (Stax 1.0 TCK incompliancy): Filtered stream reader was
- not initialized to point to first accepted event. This is different
- from expectations of Stax TCK (although identical to behavior of
- Stax RI).
- (reported by Santiago P-G)
- * [WSTX-113]: problems with DOMSource when DOM parsed in
- non-namespace mode)
- (reported by Daniel K)
- * [WSTX-114] Handling of ID attribute uniqueness check was failing
- in non-namespace mode: last character was dropped, leading to
- false collisions
- (reported by Linus E)
-
- Newfunctionality:
-
- * [WSTX-112] Added access to underlying output stream/writer, via
- XMLStreamReader.getProperty(). Properties added are
- 'WstxOutputProperties.P_OUTPUT_UNDERLYING_STREAM' and
- 'WstxOutputProperties.P_OUTPUT_UNDERLYING_WRITER'.
-
-3.2.0 [28-Dec-2006]
-
- Problems fixed:
-
- * [WSTX-70] External parsed entity references were not resolved using
- correct path context
- (reported by Michael K)
- * [WSTX-86] Maven group id wrong: was "woodstox", should be
- "org.codehaus.woodstox"
- * [WSTX-89] Line number information was not properly updated in
- some cases (boundary condition with Windows, \r\n, linefeeds)
- (reported by Frank B)
- * [WSTX-96] Beginning part of comments (for longer comments)
- was sometimes duplicated by the XMLStreamWriter implementation
- (reported by Wolfgang H)
- * [WSTX-97] Character offsets (for XMLStreamReader.getLocation())
- were sometimes decremented; fixed, and added a unit test
- (reported by Frank B)
- * [WSTX-99] Encoding problems with XMLStreamWriter.
- * [WSTX-102] WStartDocument construction resulted in NPE, when using
- DOM source.
- (reported by Werner D)
- * [WSTX-103] Repairing writer had a bug that could result in wrong
- prefix being reported/output.
- (reported by Michael A)
- * StartElement.writeUsing() was not properly outputting attributes.
-
- Improvements:
-
- * [WSTX-90] Xml writing improved by 5-10% by consistenly using
- System.arraycopy (and String.getChars() which uses it) where
- possible.
- (reported by Davanum S., submitted patch suggesting optimization
- that was included)
- (also note that this fix resulted in regression, WSTX-91, fixed)
- * [WSTX-92] Improved speed of XMLStreamWriter.writeCharacters, by
- using intermediate char[] buffer for longer String.
- (suggested by Davanum S, submitted a patch)
- * [WSTX-93] System id part of Location reported for expanded external
- entities was not a valid (resolved) URI, now is.
-
- New functionality:
-
- * [WSTX-33] Woodstox now implements SAX2 interface natively. So, it
- is fair to say that Woodstox is now StAX/SAX implementation.
- (also, note that there were transient problems related to this
- feature, in trunk, such as WSTX-95, WSTX-101
- * [WSTX-94] Added new property (WstxOutputProperties.P_OUTPUT_ESCAPE_CR;
- default is Boolean.TRUE), which determines whether \r in textual
- content to be written will be escaped by the default stream writer
- serializers. The default is to escape \r characters, to ensure
- clean round-trippability.
- (requested by Brett P)
-
-3.1.0 [02-Nov-2006]
-
- Problems fixed:
-
- * [WSTX-23] xml:space attribute DTD type (should be enumeration as per
- xml 1.0 specification) was not checked
-
- Improvements:
-
- * [WSTX-42] SPACE events were not returned in DTD-aware non-validating mode.
- * [WSTX-68] XMLStreamWriter.writeNamespace() was ignored in repairing mode
- (but not any more). Similarly, prefix was only used if no existing binding
- was found: now will try to honor prefix even at expense of reusing
- existing bindings.
-
- Newfunctionality:
-
- * [WSTX-22] Basic xml:id (typing) support added. Will only validate
- uniqueness of xml:id attribute values in DTD-validating mode, for now.
-
-3.0.2 [27-Sep-2006]
-
- Problems fixed:
-
- * [WSTX-81] Character/byte offset for Location not correctly calculated
- (reported by Mickael G)
- * [WTSX-82] URL handling had problems on Windows platform, with file-based
- URLs that refer to network drives
- (reported by Christian B)
- * [WSTX-83] One more NPE in ElemAttrs for namespace URI checks.
- (reported by Oleg R)
-
-3.0.1 [29-Aug-2006]
-
- Problems fixed:
-
- * [WSTX-69] Incorrect types returned by XMLStreamReader, when
- notations/entities are requested.
- (report by Michael K)
- * [WSTX-72] Closing of output streams/writers in cases where that should
- not be done (plus similar problems on input side)
- (reported by Matt S)
- * [WSTX-74] Woodstox wasn't throwing NoSuchElementException at the end
- (reported by Lucian H)
- * [WSTX-77] Bug in DTDValidator.validateAttribute() passing wrong args
- to StringUtil.matches()
- (reported by Vim D R)
- * [WSTX-81] Character/byte offset for Location not correctly calculated
- (reported by Mickael G)
- * [WTSX-82] URL handling had problems on Windows platform, with file-based
- URLs that refer to network drives
- (reported by Christian B)
-
-3.0.0 (final) [07-Aug-2006]
-
- Problems fixed:
-
- * A NullPointerException with StartElement.getAttributeByName() (apparently
- only happening when creating Attributes via Event Factory)
- * [WSTX-64]: CompactNsContext.outputNamespaceDeclarations NPE.
- (reported by Wolfgang H)
- * Fixed a problem with XMLEventReader.nextTag(), when peek() was called
- to access StartDocument event first.
- (reported by Lucian H)
- * Fixed a minor non-conformance issue with StartDocument, was not defaulting
- version pseudo-attribute to '1.0' (returned null if no xml declaration,
- ie. same as what XMLStreamReader returns).
- * [WSTX-65]: Fixed multiple problems with repairing stream writer, and
- the handling of automatic namespace declarations.
-
-3.0rc1, 3.0rc2 [08-Jun-2006], [21-Jul-2006]
-
- Problems fixed:
-
- * [WTSX-38], [WSTX-56]: Filtered event reader was not filtering events
- correctly. Now should work much better.
- * [WSTX-54]: Added method XMLStreamWriter2.getEncoding, which allows for
- accessing encoding of the underlying output stream/writer (if such
- info available to the stream writer).
- * [WSTX-55]: XMLStreamWriter.flush() is now once again side-effect
- free (rule of minimal surprise)
- * [WSTX-57]: (partial fix) getNamespaceURI(int) will now return "" for
- 'no namespace', instead of null. Value will thus be the exact lexival
- value from the declaration.
- * [WSTX-58]: a problem with DOMWrappingReader throwing an NPE, when
- accessing attribute properties of an element with only ns declarations.
- * [WSTX-59]: Stream writer trying to quote \r and \t in prolog/epilog.
- * [WSTX-60]: No pom file was generated for woodstox jar distributions;
- added generation, and dependencies to stax api jar generated by ref. impl.
- * [WSTX-61]: Using non-woodstox XMLStreamReader with the default
- event allocator fails.
-
- Improvements:
-
- * More significant parsing speed improvements, related to white space and
- linefeed handling.
- * Significant optimizations on the output side: adding BufferedWriter
- increases output speed very significantly (i.e. non-buffering basic
- OutputStreamWriter was dead slow for almost all use cases).
- Also, added simple buffer recycling, similar to reader side.
-
- New functionality:
-
- * [WSTX-25]: Added Stax2 interface ValidationProblemHandler, and associated
- methods to XMLStreamReader2 and XMLStreamWriter2: this allows for
- custom validation error handling, overriding default logic.
- * [WSTX-52]: Added a set of basic Stax2Source and Stax2Result
- implementations: these allow for more efficient and accurate source/result
- identification, and possible later optimizations.
-
-------------------------------------------------------------------------
-End of History (as we know it)
-------------------------------------------------------------------------
+5.0.0 (earlier)
-(changes for versions prior to 3.0.0 are not included)
+Attempted initial release -- unfortunately, as per #3 (see above), not a working jar.
diff -Nru libwoodstox-java-4.1.3/release-notes/xml-compatibility.txt libwoodstox-java-5.1.0/release-notes/xml-compatibility.txt
--- libwoodstox-java-4.1.3/release-notes/xml-compatibility.txt 2012-04-24 04:38:20.000000000 +0000
+++ libwoodstox-java-5.1.0/release-notes/xml-compatibility.txt 1970-01-01 00:00:00.000000000 +0000
@@ -1,30 +0,0 @@
-Version: 3.1
-
-Current version is very close to complete XML 1.0 compliance; and also
-mostly XML 1.1 compliant. In addition to the core xml specification,
-Woodstox implements following specifications:
-
-* Xml Namespaces (1.0 and 1.1)
-* Xml:id
-
-Known issues regarding strict XML-conformance checking are:
-
-XML 1.0:
-
-* Surrogate pairing checks for identifiers (element and attribute names,
- PI targets) is slightly incomplete, resulting in 4 failing XMLTest test
- cases.
-* Validity checks for characters 0xFFFE and 0xFFFF does not work for
- UTF-16 encoding (need to implement custom reader). Results in 2 failing
- XMLTest test cases.
-* Namespace declaration pseudo-attributes are always dealt as being
- type CDATA, even if DTD declares otherwise: this means that the white
- space included will not be normalized (one failing XMLTest test cases)
-
-XML 1.0:
-
-[no known 1.0 specific additional problems]
-
-XML 1.1:
-
-[no known 1.1 specific additional problems]
diff -Nru libwoodstox-java-4.1.3/src/java/com/ctc/wstx/api/CommonConfig.java libwoodstox-java-5.1.0/src/java/com/ctc/wstx/api/CommonConfig.java
--- libwoodstox-java-4.1.3/src/java/com/ctc/wstx/api/CommonConfig.java 2012-04-24 04:38:20.000000000 +0000
+++ libwoodstox-java-5.1.0/src/java/com/ctc/wstx/api/CommonConfig.java 1970-01-01 00:00:00.000000000 +0000
@@ -1,245 +0,0 @@
-package com.ctc.wstx.api;
-
-import java.util.*;
-
-import org.codehaus.stax2.XMLStreamProperties;
-
-import com.ctc.wstx.util.DataUtil;
-
-/**
- * Shared common base class for variour configuration container implementations
- * for public factories Woodstox uses: implementations of
- * {@link javax.xml.stream.XMLInputFactory},
- * {@link javax.xml.stream.XMLOutputFactory} and
- * {@link org.codehaus.stax2.validation.XMLValidationSchemaFactory}.
- * Implements basic settings for some shared settings, defined by the
- * shared property interface {@link XMLStreamProperties}.
- */
-abstract class CommonConfig
- implements XMLStreamProperties
-{
- /*
- ///////////////////////////////////////////////////////////////////////
- // Implementation info
- ///////////////////////////////////////////////////////////////////////
- */
-
- protected final static String IMPL_NAME = "woodstox";
-
- /* !!! TBI: get from props file or so? Or build as part of Ant
- * build process?
- */
- /**
- * This is "major.minor" version used for purposes of determining
- * the feature set. Patch level is not included, since those should
- * not affect API or feature set. Using applications should be
- * prepared to take additional levels, however, just not depend
- * on those being available.
- */
- protected final static String IMPL_VERSION = "4.1";
-
- /*
- ///////////////////////////////////////////////////////////////////////
- // Internal constants
- ///////////////////////////////////////////////////////////////////////
- */
-
- final static int PROP_IMPL_NAME = 1;
- final static int PROP_IMPL_VERSION = 2;
-
- final static int PROP_SUPPORTS_XML11 = 3;
- final static int PROP_SUPPORT_XMLID = 4;
-
- final static int PROP_RETURN_NULL_FOR_DEFAULT_NAMESPACE = 5;
-
- /**
- * Map to use for converting from String property ids to enumeration
- * (ints). Used for faster dispatching.
- */
- final static HashMap sStdProperties = new HashMap(16);
- static {
- // Basic information about the implementation:
- sStdProperties.put(XMLStreamProperties.XSP_IMPLEMENTATION_NAME,
- DataUtil.Integer(PROP_IMPL_NAME));
- sStdProperties.put(XMLStreamProperties.XSP_IMPLEMENTATION_VERSION,
- DataUtil.Integer(PROP_IMPL_VERSION));
-
- // XML version support:
- sStdProperties.put(XMLStreamProperties.XSP_SUPPORTS_XML11,
- DataUtil.Integer(PROP_SUPPORTS_XML11));
-
- // Xml:id support:
- sStdProperties.put(XMLStreamProperties.XSP_SUPPORT_XMLID,
- DataUtil.Integer(PROP_SUPPORT_XMLID));
-
- sStdProperties.put(WstxInputProperties.P_RETURN_NULL_FOR_DEFAULT_NAMESPACE,
- DataUtil.Integer(PROP_RETURN_NULL_FOR_DEFAULT_NAMESPACE));
-
- /* 23-Apr-2008, tatus: Additional interoperability property,
- * one that Sun implementation uses. Can map tor Stax2
- * property quite easily.
- */
- sStdProperties.put("http://java.sun.com/xml/stream/properties/implementation-name",
- DataUtil.Integer(PROP_IMPL_NAME));
-
- }
-
- protected CommonConfig() { }
-
- /*
- ///////////////////////////////////////////////////////////////////////
- // Public API, generic StAX config methods
- ///////////////////////////////////////////////////////////////////////
- */
-
- public Object getProperty(String propName)
- {
- /* Related to [WSTX-243]; would be nice to not to have to throw an
- * exception; but Stax spec suggests that we do need to indicate
- * unrecognized property by exception.
- */
- int id = findPropertyId(propName);
- if (id >= 0) {
- return getProperty(id);
- }
- id = findStdPropertyId(propName);
- if (id < 0) {
- reportUnknownProperty(propName);
- return null;
- }
- return getStdProperty(id);
- }
-
- public boolean isPropertySupported(String propName)
- {
- return (findPropertyId(propName) >= 0)
- || (findStdPropertyId(propName) >= 0);
- }
-
- /**
- * @return True, if the specified property was succesfully
- * set to specified value; false if its value was not changed
- */
- public boolean setProperty(String propName, Object value)
- {
- int id = findPropertyId(propName);
- if (id >= 0) {
- return setProperty(propName, id, value);
- }
- id = findStdPropertyId(propName);
- if (id < 0) {
- reportUnknownProperty(propName);
- return false;
- }
- return setStdProperty(propName, id, value);
- }
-
- protected void reportUnknownProperty(String propName)
- {
- // see [WSTX-243] for discussion on whether to throw...
- throw new IllegalArgumentException("Unrecognized property '"+propName+"'");
- }
-
- /*
- ///////////////////////////////////////////////////////////////////////
- // Additional methods used by Woodstox core
- ///////////////////////////////////////////////////////////////////////
- */
-
- public final Object safeGetProperty(String propName)
- {
- int id = findPropertyId(propName);
- if (id >= 0) {
- return getProperty(id);
- }
- id = findStdPropertyId(propName);
- if (id < 0) {
- return null;
- }
- return getStdProperty(id);
- }
-
- /**
- * Method used to figure out the official implementation name
- * for input/output/validation factories.
- */
- public static String getImplName() { return IMPL_NAME; }
-
- /**
- * Method used to figure out the official implementation version
- * for input/output/validation factories.
- */
- public static String getImplVersion() { return IMPL_VERSION; }
-
- /*
- ///////////////////////////////////////////////////////////////////////
- // Interface sub-classes have to implement / can override
- ///////////////////////////////////////////////////////////////////////
- */
-
- /**
- * @return Internal enumerated int matching the String name
- * of the property, if one found: -1 to indicate no match
- * was found.
- */
- protected abstract int findPropertyId(String propName);
-
- protected boolean doesSupportXml11() {
- /* Woodstox does support xml 1.1 ... but sub-classes can
- * override it if/as necessary (validator factories might not
- * support it?)
- */
- return true;
- }
-
- protected boolean doesSupportXmlId() {
- /* Woodstox does support Xml:id ... but sub-classes can
- * override it if/as necessary.
- */
- return true;
- }
-
- protected boolean returnNullForDefaultNamespace() {
- return Boolean.getBoolean(WstxInputProperties.P_RETURN_NULL_FOR_DEFAULT_NAMESPACE);
- }
-
- protected abstract Object getProperty(int id);
-
- protected abstract boolean setProperty(String propName, int id, Object value);
-
- /*
- ///////////////////////////////////////////////////////////////////////
- // Internal methods
- ///////////////////////////////////////////////////////////////////////
- */
-
- protected int findStdPropertyId(String propName)
- {
- Integer I = (Integer) sStdProperties.get(propName);
- return (I == null) ? -1 : I.intValue();
- }
-
- protected boolean setStdProperty(String propName, int id, Object value)
- {
- // None of the current shared properties are settable...
- return false;
- }
-
- protected Object getStdProperty(int id)
- {
- switch (id) {
- case PROP_IMPL_NAME:
- return IMPL_NAME;
- case PROP_IMPL_VERSION:
- return IMPL_VERSION;
- case PROP_SUPPORTS_XML11:
- return doesSupportXml11() ? Boolean.TRUE : Boolean.FALSE;
- case PROP_SUPPORT_XMLID:
- return doesSupportXmlId() ? Boolean.TRUE : Boolean.FALSE;
- case PROP_RETURN_NULL_FOR_DEFAULT_NAMESPACE:
- return returnNullForDefaultNamespace() ? Boolean.TRUE : Boolean.FALSE;
- default: // sanity check, should never happen
- throw new IllegalStateException("Internal error: no handler for property with internal id "+id+".");
- }
- }
-}
diff -Nru libwoodstox-java-4.1.3/src/java/com/ctc/wstx/api/EmptyElementHandler.java libwoodstox-java-5.1.0/src/java/com/ctc/wstx/api/EmptyElementHandler.java
--- libwoodstox-java-4.1.3/src/java/com/ctc/wstx/api/EmptyElementHandler.java 2012-04-24 04:38:20.000000000 +0000
+++ libwoodstox-java-5.1.0/src/java/com/ctc/wstx/api/EmptyElementHandler.java 1970-01-01 00:00:00.000000000 +0000
@@ -1,81 +0,0 @@
-package com.ctc.wstx.api;
-
-import java.util.Set;
-import java.util.TreeSet;
-
-/**
- * Optional handler used to determine if a specific empty element (by name) should
- * be allowed to use the self-closing syntax instead of having a separate end tag.
- *
- * @since 4.1
- */
-public interface EmptyElementHandler
-{
- /**
- * @param prefix The element's namespace prefix, null if not set
- * @param localName The element's local name
- * @param nsURI The elements's namespace URI, null if not set
- * @param allowEmpty The allow empty setting specified by the caller.
- * @return True if the empty element can be self-closing. False if a separate end tag should be written.
- */
- public boolean allowEmptyElement(String prefix, String localName, String nsURI, boolean allowEmpty);
-
- /**
- * Handler that uses a Set of Strings. If the local part of the element's QName is contained
- * in the Set the element is allowed to be empty.
- *
- * Users of this class are encouraged to use a {@link TreeSet} with the {@link String#CASE_INSENSITIVE_ORDER}
- * comparator if case-insensitive comparison is needed (like when dealing with HTML tags).
- */
- public static class SetEmptyElementHandler
- implements EmptyElementHandler
- {
- final protected Set mEmptyElements;
-
- public SetEmptyElementHandler(Set emptyElements)
- {
- mEmptyElements = emptyElements;
- }
-
- public boolean allowEmptyElement(String prefix, String localName, String nsURI, boolean allowEmpty)
- {
- return mEmptyElements.contains(localName);
- }
- }
-
- /**
- * HTML specific empty element handler.
- * Extends the {@link SetEmptyElementHandler} and configures
- * the HTML elements that must be self-closing according to the W3C:
- * http://www.w3.org/TR/html4/index/elements.html
- *
- * Note that element name comparison is case-insensitive as required
- * by HTML specification.
- */
- public static class HtmlEmptyElementHandler
- extends SetEmptyElementHandler
- {
- private final static HtmlEmptyElementHandler sInstance = new HtmlEmptyElementHandler();
-
- public static HtmlEmptyElementHandler getInstance() { return sInstance; }
-
- protected HtmlEmptyElementHandler()
- {
- super(new TreeSet(String.CASE_INSENSITIVE_ORDER));
- mEmptyElements.add("area");
- mEmptyElements.add("base");
- mEmptyElements.add("basefont");
- mEmptyElements.add("br");
- mEmptyElements.add("col");
- mEmptyElements.add("frame");
- mEmptyElements.add("hr");
- mEmptyElements.add("input");
- mEmptyElements.add("img");
- mEmptyElements.add("isindex");
- mEmptyElements.add("link");
- mEmptyElements.add("meta");
- mEmptyElements.add("param");
- }
- }
-}
-
diff -Nru libwoodstox-java-4.1.3/src/java/com/ctc/wstx/api/InvalidCharHandler.java libwoodstox-java-5.1.0/src/java/com/ctc/wstx/api/InvalidCharHandler.java
--- libwoodstox-java-4.1.3/src/java/com/ctc/wstx/api/InvalidCharHandler.java 2012-04-24 04:38:20.000000000 +0000
+++ libwoodstox-java-5.1.0/src/java/com/ctc/wstx/api/InvalidCharHandler.java 1970-01-01 00:00:00.000000000 +0000
@@ -1,91 +0,0 @@
-package com.ctc.wstx.api;
-
-import java.io.IOException;
-
-/**
- * Simple converter interface designed to be used with stream writer property
- * {@link WstxOutputProperties#P_OUTPUT_INVALID_CHAR_HANDLER}.
- * The idea is that it should be easy to have a way to convert invalid
- * characters such as Ascii control characters into something that
- * is legal to include in XML content. This only allows for simple
- * char-by-char replacements, instead of something more advanced such
- * as escaping. If escaping is needed, check out
- * {@link org.codehaus.stax2.XMLOutputFactory2#P_TEXT_ESCAPER} instead.
- *
- * Note about exceptions: choice of only allowing throwing of
- * {@link IOException}s is due to the way Woodstox stream writer
- * backend works; XmlWriter
can only throw IOExceptions.
- */
-public interface InvalidCharHandler
-{
- public char convertInvalidChar(int invalidChar) throws IOException;
-
- /**
- * This handler implementation just throws an exception for
- * all invalid characters encountered. It is the default handler
- * used if nothing else has been specified.
- */
- public static class FailingHandler
- implements InvalidCharHandler
- {
- public final static int SURR1_FIRST = 0xD800;
- public final static int SURR1_LAST = 0xDBFF;
- public final static int SURR2_FIRST = 0xDC00;
- public final static int SURR2_LAST = 0xDFFF;
-
- private final static FailingHandler sInstance = new FailingHandler();
-
- protected FailingHandler() { }
-
- public static FailingHandler getInstance() { return sInstance; }
-
- public char convertInvalidChar(int c) throws IOException
- {
- /* 17-May-2006, TSa: Would really be useful if we could throw
- * XMLStreamExceptions; esp. to indicate actual output location.
- * However, this causes problem with methods that call us and
- * can only throw IOExceptions (when invoked via Writer proxy).
- * Need to figure out how to resolve this.
- */
- if (c == 0) {
- throw new IOException("Invalid null character in text to output");
- }
- if (c < ' ' || (c >= 0x7F && c <= 0x9F)) {
- String msg = "Invalid white space character (0x"+Integer.toHexString(c)+") in text to output (in xml 1.1, could output as a character entity)";
- throw new IOException(msg);
- }
- if (c > 0x10FFFF) {
- throw new IOException("Illegal unicode character point (0x"+Integer.toHexString(c)+") to output; max is 0x10FFFF as per RFC 3629");
- }
- /* Surrogate pair in non-quotable (not text or attribute value)
- * content, and non-unicode encoding (ISO-8859-x, Ascii)?
- */
- if (c >= SURR1_FIRST && c <= SURR2_LAST) {
- throw new IOException("Illegal surrogate pair -- can only be output via character entities, which are not allowed in this content");
- }
- throw new IOException("Invalid XML character (0x"+Integer.toHexString(c)+") in text to output");
- }
- }
-
- /**
- * Alternative to the default handler, this handler converts all invalid
- * characters to the specified output character. That character will
- * not be further verified or modified by the stream writer.
- */
- public static class ReplacingHandler
- implements InvalidCharHandler
- {
- final char mReplacementChar;
-
- public ReplacingHandler(char c)
- {
- mReplacementChar = c;
- }
-
- public char convertInvalidChar(int c) throws IOException
- {
- return mReplacementChar;
- }
- }
-}
-
diff -Nru libwoodstox-java-4.1.3/src/java/com/ctc/wstx/api/package.html libwoodstox-java-5.1.0/src/java/com/ctc/wstx/api/package.html
--- libwoodstox-java-4.1.3/src/java/com/ctc/wstx/api/package.html 2012-04-24 04:38:20.000000000 +0000
+++ libwoodstox-java-5.1.0/src/java/com/ctc/wstx/api/package.html 1970-01-01 00:00:00.000000000 +0000
@@ -1,7 +0,0 @@
-
-Package that contains subset of Woodstox classes that are considered to be
-its public API (in addition to regular Stax 1.0 -- javax.xml.stream.* -- and
-Stax2 -- org.codehaus.stax2.*). This means that application code can rely
-on these classes, and effort is made to keep them backwards compatible
-between releases.
-
diff -Nru libwoodstox-java-4.1.3/src/java/com/ctc/wstx/api/ReaderConfig.java libwoodstox-java-5.1.0/src/java/com/ctc/wstx/api/ReaderConfig.java
--- libwoodstox-java-4.1.3/src/java/com/ctc/wstx/api/ReaderConfig.java 2012-04-24 04:38:20.000000000 +0000
+++ libwoodstox-java-5.1.0/src/java/com/ctc/wstx/api/ReaderConfig.java 1970-01-01 00:00:00.000000000 +0000
@@ -1,1547 +0,0 @@
-package com.ctc.wstx.api;
-
-import java.lang.ref.SoftReference;
-import java.net.URL;
-import java.util.*;
-
-import javax.xml.stream.*;
-
-import org.codehaus.stax2.XMLInputFactory2; // for property consts
-import org.codehaus.stax2.XMLStreamProperties; // for property consts
-import org.codehaus.stax2.validation.DTDValidationSchema;
-
-import com.ctc.wstx.api.WstxInputProperties;
-import com.ctc.wstx.cfg.InputConfigFlags;
-import com.ctc.wstx.dtd.DTDEventListener;
-import com.ctc.wstx.ent.IntEntity;
-import com.ctc.wstx.ent.EntityDecl;
-import com.ctc.wstx.io.BufferRecycler;
-import com.ctc.wstx.util.ArgUtil;
-import com.ctc.wstx.util.DataUtil;
-import com.ctc.wstx.util.SymbolTable;
-
-/**
- * Simple configuration container class; passed by reader factory to reader
- * instance created.
- *
- * In addition to its main task as a configuration container, this class
- * also acts as a wrapper around simple buffer recycling functionality.
- * The reason is that while conceptually this is a separate concern,
- * there are enough commonalities with the life-cycle of this object to
- * make this a very convenience place to add that functionality...
- * (that is: conceptually this is not right, but from pragmatic viewpoint
- * it just makes sense)
- */
-public final class ReaderConfig
- extends CommonConfig
- implements InputConfigFlags
-{
- /*
- ///////////////////////////////////////////////////////////////////////
- // Constants for reader properties:
- ///////////////////////////////////////////////////////////////////////
- */
-
- // // First, standard StAX properties:
-
- // Simple flags:
- final static int PROP_COALESCE_TEXT = 1;
- final static int PROP_NAMESPACE_AWARE = 2;
- final static int PROP_REPLACE_ENTITY_REFS = 3;
- final static int PROP_SUPPORT_EXTERNAL_ENTITIES = 4;
- final static int PROP_VALIDATE_AGAINST_DTD = 5;
- final static int PROP_SUPPORT_DTD = 6;
-
- // Object type properties
- public final static int PROP_EVENT_ALLOCATOR = 7;
- final static int PROP_WARNING_REPORTER = 8;
- final static int PROP_XML_RESOLVER = 9;
-
- // // Then StAX2 standard properties:
-
- // Simple flags:
- final static int PROP_INTERN_NS_URIS = 20;
- final static int PROP_INTERN_NAMES = 21;
- final static int PROP_REPORT_CDATA = 22;
- final static int PROP_REPORT_PROLOG_WS = 23;
- final static int PROP_PRESERVE_LOCATION = 24;
- final static int PROP_AUTO_CLOSE_INPUT = 25;
-
- // Enum / Object type properties:
- final static int PROP_SUPPORT_XMLID = 26; // shared with WriterConfig
- final static int PROP_DTD_OVERRIDE = 27;
-
- // // // Constants for additional Wstx properties:
-
- // Simple flags:
-
- /**
- * Note: this entry was deprecated for 4.0 versions up until
- * and including 4.0.7; was brought back for 4.0.8 (and will
- * be retained for 4.1)
- */
- final static int PROP_NORMALIZE_LFS = 40;
-
- /* This entry was deprecated for 3.2 and removed in 4.0
- * version. There are no plans to bring it back.
- */
- //final static int PROP_NORMALIZE_ATTR_VALUES = 41;
-
- final static int PROP_CACHE_DTDS = 42;
- final static int PROP_CACHE_DTDS_BY_PUBLIC_ID = 43;
- final static int PROP_LAZY_PARSING = 44;
- final static int PROP_SUPPORT_DTDPP = 45;
- final static int PROP_TREAT_CHAR_REFS_AS_ENTS = 46;
-
- // Object type properties:
-
- final static int PROP_INPUT_BUFFER_LENGTH = 50;
- //final static int PROP_TEXT_BUFFER_LENGTH = 51;
- final static int PROP_MIN_TEXT_SEGMENT = 52;
- final static int PROP_CUSTOM_INTERNAL_ENTITIES = 53;
- final static int PROP_DTD_RESOLVER = 54;
- final static int PROP_ENTITY_RESOLVER = 55;
- final static int PROP_UNDECLARED_ENTITY_RESOLVER = 56;
- final static int PROP_BASE_URL = 57;
- final static int PROP_INPUT_PARSING_MODE = 58;
-
- /*
- ////////////////////////////////////////////////
- // Limits for numeric properties
- ////////////////////////////////////////////////
- */
-
- /**
- * Need to set a minimum size, since there are some limitations to
- * smallest consequtive block that can be used.
- */
- final static int MIN_INPUT_BUFFER_LENGTH = 8; // 16 bytes
-
- /**
- * Let's allow caching of just a dozen DTDs... shouldn't really
- * matter, how many DTDs does one really use?
- */
- final static int DTD_CACHE_SIZE_J2SE = 12;
-
- final static int DTD_CACHE_SIZE_J2ME = 5;
-
- /*
- ///////////////////////////////////////////////////////////////////////
- // Default values for custom properties:
- ///////////////////////////////////////////////////////////////////////
- */
-
- /**
- * By default, let's require minimum of 64 chars to be delivered
- * as shortest partial (piece of) text (CDATA, text) segment;
- * same for both J2ME subset and full readers. Prevents tiniest
- * runts from getting passed
- */
- final static int DEFAULT_SHORTEST_TEXT_SEGMENT = 64;
-
- /**
- * Default config flags are converted from individual settings,
- * to conform to StAX 1.0 specifications.
- */
- final static int DEFAULT_FLAGS_FULL =
- 0
- // First, default settings StAX specs dictate:
-
- | CFG_NAMESPACE_AWARE
- // Coalescing to be disabled
- //| CFG_COALESCE_TEXT
- | CFG_REPLACE_ENTITY_REFS
- | CFG_SUPPORT_EXTERNAL_ENTITIES
- | CFG_SUPPORT_DTD
-
- // and then custom setting defaults:
-
- // and namespace URI interning
- | CFG_INTERN_NAMES
- | CFG_INTERN_NS_URIS
-
- // we will also accurately report CDATA, by default
- | CFG_REPORT_CDATA
-
- /* 20-Jan-2006, TSa: As per discussions on stax-builders list
- * (and input from xml experts), 4.0 will revert to "do not
- * report SPACE events outside root element by default"
- * settings. Conceptually this is what xml specification
- * implies should be done: there is no content outside of
- * the element tree, including any ignorable content, just
- * processing instructions and comments.
- */
- //| CFG_REPORT_PROLOG_WS
-
- /* but enable DTD caching (if they are handled):
- * (... maybe J2ME subset shouldn't do it?)
- */
- | CFG_CACHE_DTDS
- /* 29-Mar-2006, TSa: But note, no caching by public-id, due
- * to problems with cases where public-id/system-id were
- * inconsistently used, leading to problems.
- */
-
- /* by default, let's also allow lazy parsing, since it tends
- * to improve performance
- */
- | CFG_LAZY_PARSING
-
- /* and also make Event objects preserve location info...
- * can be turned off for maximum performance
- */
- | CFG_PRESERVE_LOCATION
-
- // As per Stax 1.0 specs, we can not enable this by default:
- //| CFG_AUTO_CLOSE_INPUT);
-
- /* Also, let's enable dtd++ support (shouldn't hurt with non-dtd++
- * dtds)
- */
-
- | CFG_SUPPORT_DTDPP
-
- /*
- * Set this as a default, as this is required in xml;
- */
- | CFG_NORMALIZE_LFS
-
- /* Regarding Xml:id, let's enabled typing by default, but not
- * uniqueness validity checks: latter will be taken care of
- * by DTD validation if enabled, otherwise needs to be explicitly
- * enabled
- */
- | CFG_XMLID_TYPING
- // | CFG_XMLID_UNIQ_CHECKS
- ;
-
- /**
- * For now defaults for J2ME flags can be identical to 'full' set;
- * differences are in buffer sizes.
- */
- final static int DEFAULT_FLAGS_J2ME = DEFAULT_FLAGS_FULL;
-
- // // //
-
- /**
- * Map to use for converting from String property ids to ints
- * described above; useful to allow use of switch later on.
- */
- final static HashMap sProperties = new HashMap(64); // we have about 40 entries
- static {
- // Standard ones; support for features
- sProperties.put(XMLInputFactory.IS_COALESCING,
- DataUtil.Integer(PROP_COALESCE_TEXT));
- sProperties.put(XMLInputFactory.IS_NAMESPACE_AWARE,
- DataUtil.Integer(PROP_NAMESPACE_AWARE));
- sProperties.put(XMLInputFactory.IS_REPLACING_ENTITY_REFERENCES,
- DataUtil.Integer(PROP_REPLACE_ENTITY_REFS));
- sProperties.put(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES,
- DataUtil.Integer(PROP_SUPPORT_EXTERNAL_ENTITIES));
- sProperties.put(XMLInputFactory.IS_VALIDATING,
- DataUtil.Integer(PROP_VALIDATE_AGAINST_DTD));
- sProperties.put(XMLInputFactory.SUPPORT_DTD,
- DataUtil.Integer(PROP_SUPPORT_DTD));
-
- // Standard ones; pluggable components
- sProperties.put(XMLInputFactory.ALLOCATOR,
- DataUtil.Integer(PROP_EVENT_ALLOCATOR));
- sProperties.put(XMLInputFactory.REPORTER,
- DataUtil.Integer(PROP_WARNING_REPORTER));
- sProperties.put(XMLInputFactory.RESOLVER,
- DataUtil.Integer(PROP_XML_RESOLVER));
-
- // StAX2-introduced flags:
- sProperties.put(XMLInputFactory2.P_INTERN_NAMES,
- DataUtil.Integer(PROP_INTERN_NAMES));
- sProperties.put(XMLInputFactory2.P_INTERN_NS_URIS,
- DataUtil.Integer(PROP_INTERN_NS_URIS));
- sProperties.put(XMLInputFactory2.P_REPORT_CDATA,
- DataUtil.Integer(PROP_REPORT_CDATA));
- sProperties.put(XMLInputFactory2.P_REPORT_PROLOG_WHITESPACE,
- DataUtil.Integer(PROP_REPORT_PROLOG_WS));
- sProperties.put(XMLInputFactory2.P_PRESERVE_LOCATION,
- DataUtil.Integer(PROP_PRESERVE_LOCATION));
- sProperties.put(XMLInputFactory2.P_AUTO_CLOSE_INPUT,
- DataUtil.Integer(PROP_AUTO_CLOSE_INPUT));
- sProperties.put(XMLInputFactory2.XSP_SUPPORT_XMLID,
- DataUtil.Integer(PROP_SUPPORT_XMLID));
- sProperties.put(XMLInputFactory2.P_DTD_OVERRIDE,
- DataUtil.Integer(PROP_DTD_OVERRIDE));
-
- // Non-standard ones, flags:
-
- sProperties.put(WstxInputProperties.P_CACHE_DTDS,
- DataUtil.Integer(PROP_CACHE_DTDS));
- sProperties.put(WstxInputProperties.P_CACHE_DTDS_BY_PUBLIC_ID,
- DataUtil.Integer(PROP_CACHE_DTDS_BY_PUBLIC_ID));
- sProperties.put(XMLInputFactory2.P_LAZY_PARSING,
- DataUtil.Integer(PROP_LAZY_PARSING));
- sProperties.put(WstxInputProperties.P_SUPPORT_DTDPP,
- DataUtil.Integer(PROP_SUPPORT_DTDPP));
- sProperties.put(WstxInputProperties.P_TREAT_CHAR_REFS_AS_ENTS,
- DataUtil.Integer(PROP_TREAT_CHAR_REFS_AS_ENTS));
- sProperties.put(WstxInputProperties.P_NORMALIZE_LFS,
- DataUtil.Integer(PROP_NORMALIZE_LFS));
-
-
- // Non-standard ones, non-flags:
-
- sProperties.put(WstxInputProperties.P_INPUT_BUFFER_LENGTH,
- DataUtil.Integer(PROP_INPUT_BUFFER_LENGTH));
- sProperties.put(WstxInputProperties.P_MIN_TEXT_SEGMENT,
- DataUtil.Integer(PROP_MIN_TEXT_SEGMENT));
- sProperties.put(WstxInputProperties.P_CUSTOM_INTERNAL_ENTITIES,
- DataUtil.Integer(PROP_CUSTOM_INTERNAL_ENTITIES));
- sProperties.put(WstxInputProperties.P_DTD_RESOLVER,
- DataUtil.Integer(PROP_DTD_RESOLVER));
- sProperties.put(WstxInputProperties.P_ENTITY_RESOLVER,
- DataUtil.Integer(PROP_ENTITY_RESOLVER));
- sProperties.put(WstxInputProperties.P_UNDECLARED_ENTITY_RESOLVER,
- DataUtil.Integer(PROP_UNDECLARED_ENTITY_RESOLVER));
- sProperties.put(WstxInputProperties.P_BASE_URL,
- DataUtil.Integer(PROP_BASE_URL));
- sProperties.put(WstxInputProperties.P_INPUT_PARSING_MODE,
- DataUtil.Integer(PROP_INPUT_PARSING_MODE));
- }
-
- /*
- ///////////////////////////////////////////////////////////////////////
- // Current config state:
- ///////////////////////////////////////////////////////////////////////
- */
-
- final boolean mIsJ2MESubset;
-
- final SymbolTable mSymbols;
-
- /**
- * Bitset that contains state of on/off properties; initialized
- * to defaults, but can be set/cleared.
- */
- int mConfigFlags;
-
- /**
- * Bitset that indicates explicit changes to {@link #mConfigFlags}
- * through calls; empty bit means that the corresponding property
- * has its default value, set bit that an explicit call has been
- * made.
- */
- int mConfigFlagMods;
-
- /**
- * 13-Nov-2008, tatus: Need to be able to keep track of whether
- * name-interning has been explicitly enabled/disable or not
- * (not if it's whatever defaults we have)
- */
- final static int PROP_INTERN_NAMES_EXPLICIT = 26;
- final static int PROP_INTERN_NS_URIS_EXPLICIT = 27;
-
-
- int mInputBufferLen;
- int mMinTextSegmentLen;
-
- /**
- * Base URL to use as the resolution context for relative entity
- * references
- */
- URL mBaseURL = null;
-
- /**
- * Parsing mode can be changed from the default xml compliant
- * behavior to one of alternate modes (fragment processing,
- * multiple document processing).
- */
- WstxInputProperties.ParsingMode mParsingMode =
- WstxInputProperties.PARSING_MODE_DOCUMENT;
-
- /**
- * This boolean flag is set if the input document requires
- * xml 1.1 (or above) compliant processing: default is xml 1.0
- * compliant. Note that unlike most other properties, this
- * does not come from configuration settings, but from processed
- * document itself.
- */
- boolean mXml11 = false;
-
- /*
- ///////////////////////////////////////////////////////////////////////
- // Common configuration objects
- ///////////////////////////////////////////////////////////////////////
- */
-
- XMLReporter mReporter;
-
- XMLResolver mDtdResolver = null;
- XMLResolver mEntityResolver = null;
-
- /*
- ///////////////////////////////////////////////////////////////////////
- // More special(ized) configuration objects
- ///////////////////////////////////////////////////////////////////////
- */
-
- //Map mCustomEntities;
- //XMLResolver mUndeclaredEntityResolver;
- //DTDEventListener mDTDEventListener;
-
- Object[] mSpecialProperties = null;
-
- private final static int SPEC_PROC_COUNT = 4;
-
- private final static int SP_IX_CUSTOM_ENTITIES = 0;
- private final static int SP_IX_UNDECL_ENT_RESOLVER = 1;
- private final static int SP_IX_DTD_EVENT_LISTENER = 2;
- private final static int SP_IX_DTD_OVERRIDE = 3;
-
- /*
- ///////////////////////////////////////////////////////////////////////
- // Buffer recycling:
- ///////////////////////////////////////////////////////////////////////
- */
-
- /**
- * This ThreadLocal
contains a {@link SoftRerefence}
- * to a {@link BufferRecycler} used to provide a low-cost
- * buffer recycling between Reader instances.
- */
- final static ThreadLocal mRecyclerRef = new ThreadLocal();
-
- /**
- * This is the actually container of the recyclable buffers. It
- * is obtained via ThreadLocal/SoftReference combination, if one
- * exists, when Config instance is created. If one does not
- * exist, it will created first time a buffer is returned.
- */
- BufferRecycler mCurrRecycler = null;
-
- /*
- ///////////////////////////////////////////////////////////////////////
- // Life-cycle
- ///////////////////////////////////////////////////////////////////////
- */
-
- private ReaderConfig(boolean j2meSubset, SymbolTable symbols,
- int configFlags, int configFlagMods,
- int inputBufLen,
- int minTextSegmentLen)
- {
- mIsJ2MESubset = j2meSubset;
- mSymbols = symbols;
-
- mConfigFlags = configFlags;
- mConfigFlagMods = configFlagMods;
-
- mInputBufferLen = inputBufLen;
- mMinTextSegmentLen = minTextSegmentLen;
-
- /* Ok, let's then see if we can find a buffer recycler. Since they
- * are lazily constructed, and since GC may just flush them out
- * on its whims, it's possible we might not find one. That's ok;
- * we can reconstruct one if and when we are to return one or more
- * buffers.
- */
- SoftReference ref = (SoftReference) mRecyclerRef.get();
- if (ref != null) {
- mCurrRecycler = (BufferRecycler) ref.get();
- }
- }
-
- public static ReaderConfig createJ2MEDefaults()
- {
- /* For J2ME we'll use slightly smaller buffer sizes by
- * default, on assumption lower memory usage is desireable:
- */
- ReaderConfig rc = new ReaderConfig
- (true, null, DEFAULT_FLAGS_J2ME, 0,
- // 4k input buffer (2000 chars):
- 2000,
- DEFAULT_SHORTEST_TEXT_SEGMENT);
- return rc;
- }
-
- public static ReaderConfig createFullDefaults()
- {
- /* For full version, can use bit larger buffers to achieve better
- * overall performance.
- */
- ReaderConfig rc = new ReaderConfig
- (false, null, DEFAULT_FLAGS_FULL, 0,
- // 8k input buffer (4000 chars):
- 4000,
- DEFAULT_SHORTEST_TEXT_SEGMENT);
- return rc;
- }
-
- public ReaderConfig createNonShared(SymbolTable sym)
- {
- // should we throw an exception?
- //if (sym == null) { }
- ReaderConfig rc = new ReaderConfig(mIsJ2MESubset, sym,
- mConfigFlags, mConfigFlagMods,
- mInputBufferLen,
- mMinTextSegmentLen);
- rc.mReporter = mReporter;
- rc.mDtdResolver = mDtdResolver;
- rc.mEntityResolver = mEntityResolver;
- rc.mBaseURL = mBaseURL;
- rc.mParsingMode = mParsingMode;
- if (mSpecialProperties != null) {
- int len = mSpecialProperties.length;
- Object[] specProps = new Object[len];
- System.arraycopy(mSpecialProperties, 0, specProps, 0, len);
- rc.mSpecialProperties = specProps;
- }
-
- return rc;
- }
-
- /**
- * Unlike name suggests there is also some limited state information
- * associated with the config object. If these objects are reused,
- * that state needs to be reset between reuses, to avoid carrying
- * over incorrect state.
- */
- public void resetState()
- {
- // Current, only xml 1.0 vs 1.1 state is stored here:
- mXml11 = false;
- }
-
- /*
- ///////////////////////////////////////////////////////////////////////
- // Implementation of abstract methods
- ///////////////////////////////////////////////////////////////////////
- */
-
- protected int findPropertyId(String propName)
- {
- Integer I = (Integer) sProperties.get(propName);
- return (I == null) ? -1 : I.intValue();
- }
-
- /*
- ///////////////////////////////////////////////////////////////////////
- // Public API, accessors
- ///////////////////////////////////////////////////////////////////////
- */
-
- // // // Accessors for immutable configuration:
-
- public SymbolTable getSymbols() { return mSymbols; }
-
- /**
- * In future this property could/should be made configurable?
- */
-
- public int getDtdCacheSize() {
- return mIsJ2MESubset ? DTD_CACHE_SIZE_J2ME : DTD_CACHE_SIZE_J2SE;
- }
-
- // // // "Raw" accessors for on/off properties:
-
- public int getConfigFlags() { return mConfigFlags; }
-
- // // // Standard StAX on/off property accessors
-
- public boolean willCoalesceText() {
- return _hasConfigFlag(CFG_COALESCE_TEXT);
- }
-
- public boolean willSupportNamespaces() {
- return _hasConfigFlag(CFG_NAMESPACE_AWARE);
- }
-
- public boolean willReplaceEntityRefs() {
- return _hasConfigFlag(CFG_REPLACE_ENTITY_REFS);
- }
-
- public boolean willSupportExternalEntities() {
- return _hasConfigFlag(CFG_SUPPORT_EXTERNAL_ENTITIES);
- }
-
- public boolean willSupportDTDs() {
- return _hasConfigFlag(CFG_SUPPORT_DTD);
- }
-
- public boolean willValidateWithDTD() {
- return _hasConfigFlag(CFG_VALIDATE_AGAINST_DTD);
- }
-
- // // // Stax2 on/off property accessors
-
- public boolean willReportCData() {
- return _hasConfigFlag(CFG_REPORT_CDATA);
- }
-
- public boolean willParseLazily() {
- return _hasConfigFlag(CFG_LAZY_PARSING);
- }
-
- public boolean willInternNames() {
- return _hasConfigFlag(CFG_INTERN_NAMES);
- }
-
- public boolean willInternNsURIs() {
- return _hasConfigFlag(CFG_INTERN_NS_URIS);
- }
-
- public boolean willPreserveLocation() {
- return _hasConfigFlag(CFG_PRESERVE_LOCATION);
- }
-
- public boolean willAutoCloseInput() {
- return _hasConfigFlag(CFG_AUTO_CLOSE_INPUT);
- }
-
- // // // Woodstox on/off property accessors
-
- public boolean willReportPrologWhitespace() {
- return _hasConfigFlag(CFG_REPORT_PROLOG_WS);
- }
-
- public boolean willCacheDTDs() {
- return _hasConfigFlag(CFG_CACHE_DTDS);
- }
-
- public boolean willCacheDTDsByPublicId() {
- return _hasConfigFlag(CFG_CACHE_DTDS_BY_PUBLIC_ID);
- }
-
- public boolean willDoXmlIdTyping() {
- return _hasConfigFlag(CFG_XMLID_TYPING);
- }
-
- public boolean willDoXmlIdUniqChecks() {
- return _hasConfigFlag(CFG_XMLID_UNIQ_CHECKS);
- }
-
- public boolean willSupportDTDPP() {
- return _hasConfigFlag(CFG_SUPPORT_DTDPP);
- }
-
- public boolean willNormalizeLFs() {
- return _hasConfigFlag(CFG_NORMALIZE_LFS);
- }
-
- public boolean willTreatCharRefsAsEnts() {
- return _hasConfigFlag(CFG_TREAT_CHAR_REFS_AS_ENTS);
- }
-
- public int getInputBufferLength() { return mInputBufferLen; }
-
- public int getShortestReportedTextSegment() { return mMinTextSegmentLen; }
-
- public Map getCustomInternalEntities()
- {
- Map custEnt = (Map) _getSpecialProperty(SP_IX_CUSTOM_ENTITIES);
- if (custEnt == null) {
- return Collections.EMPTY_MAP;
- }
- // Better be defensive and just return a copy...
- int len = custEnt.size();
- HashMap m = new HashMap(len + (len >> 2), 0.81f);
- Iterator it = custEnt.entrySet().iterator();
- while (it.hasNext()) {
- Map.Entry me = (Map.Entry) it.next();
- /* Cast is there just as a safe-guard (assertion), and to
- * document the type...
- */
- m.put(me.getKey(), (EntityDecl) me.getValue());
- }
- return m;
- }
-
- public EntityDecl findCustomInternalEntity(String id)
- {
- Map custEnt = (Map) _getSpecialProperty(SP_IX_CUSTOM_ENTITIES);
- if (custEnt == null) {
- return null;
- }
- return (EntityDecl) custEnt.get(id);
- }
-
- public XMLReporter getXMLReporter() { return mReporter; }
-
- public XMLResolver getXMLResolver() { return mEntityResolver; }
-
- public XMLResolver getDtdResolver() { return mDtdResolver; }
- public XMLResolver getEntityResolver() { return mEntityResolver; }
- public XMLResolver getUndeclaredEntityResolver() {
- return (XMLResolver) _getSpecialProperty(SP_IX_UNDECL_ENT_RESOLVER);
- }
-
- public URL getBaseURL() { return mBaseURL; }
-
- public WstxInputProperties.ParsingMode getInputParsingMode() {
- return mParsingMode;
- }
-
- public boolean inputParsingModeDocuments() {
- return mParsingMode == WstxInputProperties.PARSING_MODE_DOCUMENTS;
- }
-
- public boolean inputParsingModeFragment() {
- return mParsingMode == WstxInputProperties.PARSING_MODE_FRAGMENT;
- }
-
- /**
- * @return True if the input well-formedness and validation checks
- * should be done according to xml 1.1 specification; false if
- * xml 1.0 specification.
- */
- public boolean isXml11() {
- return mXml11;
- }
-
- public DTDEventListener getDTDEventListener() {
- return (DTDEventListener) _getSpecialProperty(SP_IX_DTD_EVENT_LISTENER);
- }
-
- public DTDValidationSchema getDTDOverride() {
- return (DTDValidationSchema) _getSpecialProperty(SP_IX_DTD_OVERRIDE);
- }
-
- /**
- * Special accessor to use to verify whether name interning has
- * explicitly been enabled; true if call was been made to set
- * it to true; false otherwise (default, or set to false)
- */
- public boolean hasInternNamesBeenEnabled() {
- return _hasExplicitConfigFlag(CFG_INTERN_NAMES);
- }
-
- public boolean hasInternNsURIsBeenEnabled() {
- return _hasExplicitConfigFlag(CFG_INTERN_NS_URIS);
- }
-
- /*
- ///////////////////////////////////////////////////////////////////////
- // Simple mutators
- ///////////////////////////////////////////////////////////////////////
- */
-
- public void setConfigFlag(int flag) {
- mConfigFlags |= flag;
- mConfigFlagMods |= flag;
- }
-
- public void clearConfigFlag(int flag) {
- mConfigFlags &= ~flag;
- mConfigFlagMods |= flag;
- }
-
- // // // Mutators for standard StAX properties
-
- public void doCoalesceText(boolean state) {
- setConfigFlag(CFG_COALESCE_TEXT, state);
- }
-
- public void doSupportNamespaces(boolean state) {
- setConfigFlag(CFG_NAMESPACE_AWARE, state);
- }
-
- public void doReplaceEntityRefs(boolean state) {
- setConfigFlag(CFG_REPLACE_ENTITY_REFS, state);
- }
-
- public void doSupportExternalEntities(boolean state) {
- setConfigFlag(CFG_SUPPORT_EXTERNAL_ENTITIES, state);
- }
-
- public void doSupportDTDs(boolean state) {
- setConfigFlag(CFG_SUPPORT_DTD, state);
- }
-
- public void doValidateWithDTD(boolean state) {
- setConfigFlag(CFG_VALIDATE_AGAINST_DTD, state);
- }
-
- // // // Mutators for Woodstox-specific properties
-
- public void doInternNames(boolean state) {
- setConfigFlag(CFG_INTERN_NAMES, state);
- }
-
- public void doInternNsURIs(boolean state) {
- setConfigFlag(CFG_INTERN_NS_URIS, state);
- }
-
- public void doReportPrologWhitespace(boolean state) {
- setConfigFlag(CFG_REPORT_PROLOG_WS, state);
- }
-
- public void doReportCData(boolean state) {
- setConfigFlag(CFG_REPORT_CDATA, state);
- }
-
- public void doCacheDTDs(boolean state) {
- setConfigFlag(CFG_CACHE_DTDS, state);
- }
-
- public void doCacheDTDsByPublicId(boolean state) {
- setConfigFlag(CFG_CACHE_DTDS_BY_PUBLIC_ID, state);
- }
-
- public void doParseLazily(boolean state) {
- setConfigFlag(CFG_LAZY_PARSING, state);
- }
-
- public void doXmlIdTyping(boolean state) {
- setConfigFlag(CFG_XMLID_TYPING, state);
- }
-
- public void doXmlIdUniqChecks(boolean state) {
- setConfigFlag(CFG_XMLID_UNIQ_CHECKS, state);
- }
-
- public void doPreserveLocation(boolean state) {
- setConfigFlag(CFG_PRESERVE_LOCATION, state);
- }
-
- public void doAutoCloseInput(boolean state) {
- setConfigFlag(CFG_AUTO_CLOSE_INPUT, state);
- }
-
- public void doSupportDTDPP(boolean state) {
- setConfigFlag(CFG_SUPPORT_DTDPP, state);
- }
-
- public void doTreatCharRefsAsEnts(final boolean state) {
- setConfigFlag(CFG_TREAT_CHAR_REFS_AS_ENTS, state);
- }
-
- public void doNormalizeLFs(final boolean state) {
- setConfigFlag(CFG_NORMALIZE_LFS, state);
- }
-
- public void setInputBufferLength(int value)
- {
- /* Let's enforce minimum here; necessary to allow longest
- * consequtive text span to be available (xml decl, etc)
- */
- if (value < MIN_INPUT_BUFFER_LENGTH) {
- value = MIN_INPUT_BUFFER_LENGTH;
- }
- mInputBufferLen = value;
- }
-
- public void setShortestReportedTextSegment(int value) {
- mMinTextSegmentLen = value;
- }
-
- public void setCustomInternalEntities(Map m)
- {
- Map entMap;
- if (m == null || m.size() < 1) {
- entMap = Collections.EMPTY_MAP;
- } else {
- int len = m.size();
- entMap = new HashMap(len + (len >> 1), 0.75f);
- Iterator it = m.entrySet().iterator();
- while (it.hasNext()) {
- Map.Entry me = (Map.Entry) it.next();
- Object val = me.getValue();
- char[] ch;
- if (val == null) {
- ch = DataUtil.getEmptyCharArray();
- } else if (val instanceof char[]) {
- ch = (char[]) val;
- } else {
- // Probably String, but let's just ensure that
- String str = val.toString();
- ch = str.toCharArray();
- }
- String name = (String) me.getKey();
- entMap.put(name, IntEntity.create(name, ch));
- }
- }
- _setSpecialProperty(SP_IX_CUSTOM_ENTITIES, entMap);
- }
-
- public void setXMLReporter(XMLReporter r) {
- mReporter = r;
- }
-
- /**
- * Note: for better granularity, you should call {@link #setEntityResolver}
- * and {@link #setDtdResolver} instead.
- */
- public void setXMLResolver(XMLResolver r) {
- mEntityResolver = r;
- mDtdResolver = r;
- }
-
- public void setDtdResolver(XMLResolver r) {
- mDtdResolver = r;
- }
-
- public void setEntityResolver(XMLResolver r) {
- mEntityResolver = r;
- }
-
- public void setUndeclaredEntityResolver(XMLResolver r) {
- _setSpecialProperty(SP_IX_UNDECL_ENT_RESOLVER, r);
- }
-
- public void setBaseURL(URL baseURL) { mBaseURL = baseURL; }
-
- public void setInputParsingMode(WstxInputProperties.ParsingMode mode) {
- mParsingMode = mode;
- }
-
- /**
- * Method called to enable or disable 1.1 compliant processing; if
- * disabled, defaults to xml 1.0 compliant processing.
- */
- public void enableXml11(boolean state) {
- mXml11 = state;
- }
-
- public void setDTDEventListener(DTDEventListener l) {
- _setSpecialProperty(SP_IX_DTD_EVENT_LISTENER, l);
- }
-
- public void setDTDOverride(DTDValidationSchema schema) {
- _setSpecialProperty(SP_IX_DTD_OVERRIDE, schema);
- }
-
- /*
- ///////////////////////////////////////////////////////////////////////
- // Profile mutators:
- ///////////////////////////////////////////////////////////////////////
- */
-
- /**
- * Method to call to make Reader created conform as closely to XML
- * standard as possible, doing all checks and transformations mandated
- * (linefeed conversions, attr value normalizations).
- * See {@link XMLInputFactory2#configureForXmlConformance} for
- * required settings for standard StAX/StAX properties.
- *
- * In addition to the standard settings, following Woodstox-specific
- * settings are also done:
- *
- *
- * Notes: Does NOT change 'performance' settings (buffer sizes,
- * DTD caching, coalescing, interning, accurate location info).
- */
- public void configureForXmlConformance()
- {
- // // StAX 1.0 settings
- doSupportNamespaces(true);
- doSupportDTDs(true);
- doSupportExternalEntities(true);
- doReplaceEntityRefs(true);
-
- // // Stax2 additional settings
-
- // Better enable full xml:id checks:
- doXmlIdTyping(true);
- doXmlIdUniqChecks(true);
-
- // Woodstox-specific ones:
- }
-
- /**
- * 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.
- * See {@link XMLInputFactory2#configureForConvenience} for
- * required settings for standard StAX/StAX properties.
- *
- * In addition to the standard settings, following Woodstox-specific
- * settings are also done:
- *
- * - Disable
XMLStreamFactory2.P_LAZY_PARSING
(to allow for synchronous
- * error notification by forcing full XML events to be completely
- * parsed when reader's next() is called)
- *
- *
- */
- public void configureForConvenience()
- {
- // StAX (1.0) settings:
- doCoalesceText(true);
- doReplaceEntityRefs(true);
-
- // StAX2:
- doReportCData(false);
- doReportPrologWhitespace(false);
- /* Also, knowing exact locations is nice esp. for error
- * reporting purposes
- */
- doPreserveLocation(true);
-
- // Woodstox-specific:
-
- /* Also, we can force errors to be reported in timely manner:
- * (once again, at potential expense of performance)
- */
- doParseLazily(false);
- }
-
- /**
- * 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.
- *
- * See {@link XMLInputFactory2#configureForSpeed} for
- * required settings for standard StAX/StAX properties.
- *
- * In addition to the standard settings, following Woodstox-specific
- * settings are also done:
- *
- * - Enable
P_CACHE_DTDS
.
- *
- * - Enable
XMLStremaFactory2.P_LAZY_PARSING
(can improve performance
- * especially when skipping text segments)
- *
- * - Disable Xml:id uniqueness checks (and leave typing as is)
- *
- * - Set lowish value for
P_MIN_TEXT_SEGMENT
, to allow
- * reader to optimize segment length it uses (and possibly avoids
- * one copy operation in the process)
- *
- * - Increase
P_INPUT_BUFFER_LENGTH
a bit from default,
- * to allow for longer consequtive read operations; also reduces cases
- * where partial text segments are on input buffer boundaries.
- *
- *
- */
- public void configureForSpeed()
- {
- // StAX (1.0):
- doCoalesceText(false);
-
- // StAX2:
- doPreserveLocation(false);
- doReportPrologWhitespace(false);
- //doInternNames(true); // this is a NOP
- doInternNsURIs(true);
- doXmlIdUniqChecks(false);
-
- // Woodstox-specific:
- doCacheDTDs(true);
- doParseLazily(true);
-
- /* If we let Reader decide sizes of text segments, it should be
- * able to optimize it better, thus low min value. This value
- * is only used in cases where text is at buffer boundary, or
- * where entity prevents using consequtive chars from input buffer:
- */
- setShortestReportedTextSegment(16);
- setInputBufferLength(8000); // 16k input buffer
- }
-
- /**
- * 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.
- *
- * See {@link XMLInputFactory2#configureForLowMemUsage} for
- * required settings for standard StAX/StAX properties.
- *
- * In addition to the standard settings, following Woodstox-specific
- * settings are also done:
- *
- * - Disable
P_CACHE_DTDS
- *
- * - Enable
P_PARSE_LAZILY
- *
- * - Resets
P_MIN_TEXT_SEGMENT
to the (somewhat low)
- * default value.
- * -
- *
- Reduces
P_INPUT_BUFFER_LENGTH
a bit from the default
- * -
- *
- */
- public void configureForLowMemUsage()
- {
- // StAX (1.0)
- doCoalesceText(false);
-
- // StAX2:
-
- doPreserveLocation(false); // can reduce temporary mem usage
-
- // Woodstox-specific:
- doCacheDTDs(false);
- doParseLazily(true); // can reduce temporary mem usage
- doXmlIdUniqChecks(false); // enabling would increase mem usage
- setShortestReportedTextSegment(ReaderConfig.DEFAULT_SHORTEST_TEXT_SEGMENT);
- setInputBufferLength(512); // 1k input buffer
- // Text buffer need not be huge, as we do not coalesce
- }
-
- /**
- * 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.
- *
- * See {@link XMLInputFactory2#configureForLowMemUsage} for
- * required settings for standard StAX/StAX properties.
- *
- * In addition to the standard settings, following Woodstox-specific
- * settings are also done:
- *
- * - Increases
P_MIN_TEXT_SEGMENT
to the maximum value so
- * that all original text segment chunks are reported without
- * segmentation (but without coalescing with adjacent CDATA segments)
- * -
- *
- Sets
P_TREAT_CHAR_REFS_AS_ENTS
to true, so the all the
- * original character references are reported with their position,
- * original text, and the replacement text.
- *
- *
- */
- public void configureForRoundTripping()
- {
- // StAX (1.0)
- doCoalesceText(false);
- doReplaceEntityRefs(false);
-
- // StAX2:
- doReportCData(true);
- doReportPrologWhitespace(true);
-
- // Woodstox specific settings
- doTreatCharRefsAsEnts(true);
- doNormalizeLFs(false);
-
- // effectively prevents from reporting partial segments:
- setShortestReportedTextSegment(Integer.MAX_VALUE);
- }
-
- /*
- ///////////////////////////////////////////////////////////////////////
- // Buffer recycling:
- ///////////////////////////////////////////////////////////////////////
- */
-
- public char[] allocSmallCBuffer(int minSize)
- {
-//System.err.println("DEBUG: cfg, allocCSmall: "+mCurrRecycler);
- if (mCurrRecycler != null) {
- char[] result = mCurrRecycler.getSmallCBuffer(minSize);
- if (result != null) {
- return result;
- }
- }
- // Nope; no recycler, or it has no suitable buffers, let's create:
- return new char[minSize];
- }
-
- public void freeSmallCBuffer(char[] buffer)
- {
-//System.err.println("DEBUG: cfg, freeCSmall: "+buffer);
- // Need to create (and assign) the buffer?
- if (mCurrRecycler == null) {
- mCurrRecycler = createRecycler();
- }
- mCurrRecycler.returnSmallCBuffer(buffer);
- }
-
- public char[] allocMediumCBuffer(int minSize)
- {
-//System.err.println("DEBUG: cfg, allocCMed: "+mCurrRecycler);
- if (mCurrRecycler != null) {
- char[] result = mCurrRecycler.getMediumCBuffer(minSize);
- if (result != null) {
- return result;
- }
- }
- return new char[minSize];
- }
-
- public void freeMediumCBuffer(char[] buffer)
- {
-//System.err.println("DEBUG: cfg, freeCMed: "+buffer);
- if (mCurrRecycler == null) {
- mCurrRecycler = createRecycler();
- }
- mCurrRecycler.returnMediumCBuffer(buffer);
- }
-
- public char[] allocFullCBuffer(int minSize)
- {
-//System.err.println("DEBUG: cfg, allocCFull: "+mCurrRecycler);
- if (mCurrRecycler != null) {
- char[] result = mCurrRecycler.getFullCBuffer(minSize);
- if (result != null) {
- return result;
- }
- }
- return new char[minSize];
- }
-
- public void freeFullCBuffer(char[] buffer)
- {
-//System.err.println("DEBUG: cfg, freeCFull: "+buffer);
- // Need to create (and assign) the buffer?
- if (mCurrRecycler == null) {
- mCurrRecycler = createRecycler();
- }
- mCurrRecycler.returnFullCBuffer(buffer);
- }
-
- public byte[] allocFullBBuffer(int minSize)
- {
-//System.err.println("DEBUG: cfg, allocBFull: "+mCurrRecycler);
- if (mCurrRecycler != null) {
- byte[] result = mCurrRecycler.getFullBBuffer(minSize);
- if (result != null) {
- return result;
- }
- }
- return new byte[minSize];
- }
-
- public void freeFullBBuffer(byte[] buffer)
- {
-//System.err.println("DEBUG: cfg, freeBFull: "+buffer);
- // Need to create (and assign) the buffer?
- if (mCurrRecycler == null) {
- mCurrRecycler = createRecycler();
- }
- mCurrRecycler.returnFullBBuffer(buffer);
- }
-
- static int Counter = 0;
-
- private BufferRecycler createRecycler()
- {
- BufferRecycler recycler = new BufferRecycler();
- // No way to reuse/reset SoftReference, have to create new always:
-//System.err.println("DEBUG: RefCount: "+(++Counter));
- mRecyclerRef.set(new SoftReference(recycler));
- return recycler;
- }
-
- /*
- ///////////////////////////////////////////////////////////////////////
- // Internal methods:
- ///////////////////////////////////////////////////////////////////////
- */
-
- private void setConfigFlag(int flag, boolean state)
- {
- if (state) {
- mConfigFlags |= flag;
- } else {
- mConfigFlags &= ~flag;
- }
- mConfigFlagMods |= flag;
- }
-
- public Object getProperty(int id)
- {
- switch (id) {
- // First, standard Stax 1.0 properties:
-
- case PROP_COALESCE_TEXT:
- return willCoalesceText() ? Boolean.TRUE : Boolean.FALSE;
- case PROP_NAMESPACE_AWARE:
- return willSupportNamespaces() ? Boolean.TRUE : Boolean.FALSE;
- case PROP_REPLACE_ENTITY_REFS:
- return willReplaceEntityRefs() ? Boolean.TRUE : Boolean.FALSE;
- case PROP_SUPPORT_EXTERNAL_ENTITIES:
- return willSupportExternalEntities() ? Boolean.TRUE : Boolean.FALSE;
-
- case PROP_VALIDATE_AGAINST_DTD:
- return willValidateWithDTD() ? Boolean.TRUE : Boolean.FALSE;
- case PROP_SUPPORT_DTD:
- return willSupportDTDs() ? Boolean.TRUE : Boolean.FALSE;
- case PROP_WARNING_REPORTER:
- return getXMLReporter();
- case PROP_XML_RESOLVER:
- return getXMLResolver();
- case PROP_EVENT_ALLOCATOR:
- /* 25-Mar-2006, TSa: Not really supported here, so let's
- * return null
- */
- return null;
-
- // Then Stax2 properties:
-
- case PROP_REPORT_PROLOG_WS:
- return willReportPrologWhitespace() ? Boolean.TRUE : Boolean.FALSE;
- case PROP_REPORT_CDATA:
- return willReportCData() ? Boolean.TRUE : Boolean.FALSE;
-
- case PROP_INTERN_NAMES:
- return willInternNames() ? Boolean.TRUE : Boolean.FALSE;
- case PROP_INTERN_NS_URIS:
- return willInternNsURIs() ? Boolean.TRUE : Boolean.FALSE;
-
- case PROP_PRESERVE_LOCATION:
- return willPreserveLocation() ? Boolean.TRUE : Boolean.FALSE;
- case PROP_AUTO_CLOSE_INPUT:
- return willAutoCloseInput() ? Boolean.TRUE : Boolean.FALSE;
-
- case PROP_DTD_OVERRIDE:
- return getDTDOverride();
-
- // // // Then Woodstox custom properties:
-
- // first, flags:
- case PROP_CACHE_DTDS:
- return willCacheDTDs() ? Boolean.TRUE : Boolean.FALSE;
- case PROP_CACHE_DTDS_BY_PUBLIC_ID:
- return willCacheDTDsByPublicId() ? Boolean.TRUE : Boolean.FALSE;
- case PROP_LAZY_PARSING:
- return willParseLazily() ? Boolean.TRUE : Boolean.FALSE;
- case PROP_SUPPORT_XMLID:
- {
- if (!_hasConfigFlag(CFG_XMLID_TYPING)) {
- return XMLStreamProperties.XSP_V_XMLID_NONE;
- }
- return _hasConfigFlag(CFG_XMLID_UNIQ_CHECKS) ?
- XMLStreamProperties.XSP_V_XMLID_FULL :
- XMLStreamProperties.XSP_V_XMLID_TYPING;
- }
-
- case PROP_TREAT_CHAR_REFS_AS_ENTS:
- return willTreatCharRefsAsEnts() ? Boolean.TRUE : Boolean.FALSE;
-
- case PROP_NORMALIZE_LFS:
- return willNormalizeLFs() ? Boolean.TRUE : Boolean.FALSE;
-
- // then object values:
- case PROP_INPUT_BUFFER_LENGTH:
- return DataUtil.Integer(getInputBufferLength());
- case PROP_MIN_TEXT_SEGMENT:
- return DataUtil.Integer(getShortestReportedTextSegment());
- case PROP_CUSTOM_INTERNAL_ENTITIES:
- return getCustomInternalEntities();
- case PROP_DTD_RESOLVER:
- return getDtdResolver();
- case PROP_ENTITY_RESOLVER:
- return getEntityResolver();
- case PROP_UNDECLARED_ENTITY_RESOLVER:
- return getUndeclaredEntityResolver();
- case PROP_BASE_URL:
- return getBaseURL();
- case PROP_INPUT_PARSING_MODE:
- return getInputParsingMode();
-
- default: // sanity check, should never happen
- throw new IllegalStateException("Internal error: no handler for property with internal id "+id+".");
- }
- }
-
- public boolean setProperty(String propName, int id, Object value)
- {
- switch (id) {
- // First, standard (Stax 1.0) properties:
-
- case PROP_COALESCE_TEXT:
- doCoalesceText(ArgUtil.convertToBoolean(propName, value));
- break;
-
- case PROP_NAMESPACE_AWARE:
- doSupportNamespaces(ArgUtil.convertToBoolean(propName, value));
- break;
-
- case PROP_REPLACE_ENTITY_REFS:
- doReplaceEntityRefs(ArgUtil.convertToBoolean(propName, value));
- break;
-
- case PROP_SUPPORT_EXTERNAL_ENTITIES:
- doSupportExternalEntities(ArgUtil.convertToBoolean(propName, value));
- break;
-
- case PROP_SUPPORT_DTD:
- doSupportDTDs(ArgUtil.convertToBoolean(propName, value));
- break;
-
- // // // Then ones that can be dispatched:
-
- case PROP_VALIDATE_AGAINST_DTD:
- doValidateWithDTD(ArgUtil.convertToBoolean(propName, value));
- break;
-
- case PROP_WARNING_REPORTER:
- setXMLReporter((XMLReporter) value);
- break;
-
- case PROP_XML_RESOLVER:
- setXMLResolver((XMLResolver) value);
- break;
-
- case PROP_EVENT_ALLOCATOR:
- /* 25-Mar-2006, TSa: Not really supported here, so let's
- * return false to let caller deal with it
- */
- return false;
-
- // // // Then Stax2 properties, flags:
-
- case PROP_INTERN_NS_URIS:
- doInternNsURIs(ArgUtil.convertToBoolean(propName, value));
- break;
-
- case PROP_INTERN_NAMES:
- doInternNames(ArgUtil.convertToBoolean(propName, value));
- break;
-
- case PROP_REPORT_CDATA:
- doReportCData(ArgUtil.convertToBoolean(propName, value));
- break;
-
- case PROP_REPORT_PROLOG_WS:
- doReportPrologWhitespace(ArgUtil.convertToBoolean(propName, value));
- break;
-
- case PROP_PRESERVE_LOCATION:
- doPreserveLocation(ArgUtil.convertToBoolean(propName, value));
- break;
-
- case PROP_AUTO_CLOSE_INPUT:
- doAutoCloseInput(ArgUtil.convertToBoolean(propName, value));
- break;
-
- // // // Then Stax2 properties, enum/object types:
-
- case PROP_SUPPORT_XMLID:
- {
- boolean typing, uniq;
-
- if (XMLStreamProperties.XSP_V_XMLID_NONE.equals(value)) {
- typing = uniq = false;
- } else if (XMLStreamProperties.XSP_V_XMLID_TYPING.equals(value)) {
- typing = true;
- uniq = false;
- } else if (XMLStreamProperties.XSP_V_XMLID_FULL.equals(value)) {
- typing = uniq = true;
- } else {
- throw new IllegalArgumentException
- ("Illegal argument ('"+value+"') to set property "
-+XMLStreamProperties.XSP_SUPPORT_XMLID+" to: has to be one of '"
-+XMLStreamProperties.XSP_V_XMLID_NONE+"', '"+XMLStreamProperties.XSP_V_XMLID_TYPING+"' or '"+XMLStreamProperties.XSP_V_XMLID_FULL+"'"
- );
- }
- setConfigFlag(CFG_XMLID_TYPING, typing);
- setConfigFlag(CFG_XMLID_UNIQ_CHECKS, uniq);
- }
- break;
-
- case PROP_DTD_OVERRIDE:
- setDTDOverride((DTDValidationSchema) value);
- break;
-
- // // // And then Woodstox specific, flags
-
- case PROP_CACHE_DTDS:
- doCacheDTDs(ArgUtil.convertToBoolean(propName, value));
- break;
-
- case PROP_CACHE_DTDS_BY_PUBLIC_ID:
- doCacheDTDsByPublicId(ArgUtil.convertToBoolean(propName, value));
- break;
-
- case PROP_LAZY_PARSING:
- doParseLazily(ArgUtil.convertToBoolean(propName, value));
- break;
-
- case PROP_TREAT_CHAR_REFS_AS_ENTS:
- doTreatCharRefsAsEnts(ArgUtil.convertToBoolean(propName, value));
- break;
-
- case PROP_NORMALIZE_LFS:
- doNormalizeLFs(ArgUtil.convertToBoolean(propName, value));
- break;
-
- // // // And then Woodstox specific, enum/object:
-
- case PROP_INPUT_BUFFER_LENGTH:
- setInputBufferLength(ArgUtil.convertToInt(propName, value, 1));
- break;
-
- case PROP_MIN_TEXT_SEGMENT:
- setShortestReportedTextSegment(ArgUtil.convertToInt(propName, value, 1));
- break;
-
- case PROP_CUSTOM_INTERNAL_ENTITIES:
- setCustomInternalEntities((Map) value);
- break;
-
- case PROP_DTD_RESOLVER:
- setDtdResolver((XMLResolver) value);
- break;
-
- case PROP_ENTITY_RESOLVER:
- setEntityResolver((XMLResolver) value);
- break;
-
- case PROP_UNDECLARED_ENTITY_RESOLVER:
- setUndeclaredEntityResolver((XMLResolver) value);
- break;
-
- case PROP_BASE_URL:
- /* 17-Nov-2008, TSa: Let's make it bit more versatile; if it's not
- * a URL per se, let's assume it is something that we can convert
- * to URL
- */
- {
- URL u;
- if (value == null) {
- u = null;
- } else if (value instanceof URL) {
- u = (URL) value;
- } else {
- try {
- u = new URL(value.toString());
- } catch (Exception ioe) { // MalformedURLException actually...
- throw new IllegalArgumentException(ioe.getMessage(), ioe);
- }
- }
- setBaseURL(u);
- }
- break;
-
- case PROP_INPUT_PARSING_MODE:
- setInputParsingMode((WstxInputProperties.ParsingMode) value);
- break;
-
- default: // sanity check, should never happen
- throw new IllegalStateException("Internal error: no handler for property with internal id "+id+".");
- }
-
- return true;
- }
-
- protected boolean _hasConfigFlag(int flag) {
- return (mConfigFlags & flag) != 0;
- }
-
- /**
- * Method similar to {@link #_hasConfigFlag}, but that will only
- * return true if in addition to being set, flag has been explicitly
- * modified (i.e. setProperty has been called to modify it)
- */
- protected boolean _hasExplicitConfigFlag(int flag) {
- return _hasConfigFlag(flag) && (mConfigFlagMods & flag) != 0;
- }
-
- private final Object _getSpecialProperty(int ix)
- {
- if (mSpecialProperties == null) {
- return null;
- }
- return mSpecialProperties[ix];
- }
-
- private final void _setSpecialProperty(int ix, Object value)
- {
- if (mSpecialProperties == null) {
- mSpecialProperties = new Object[SPEC_PROC_COUNT];
- }
- mSpecialProperties[ix] = value;
- }
-}
diff -Nru libwoodstox-java-4.1.3/src/java/com/ctc/wstx/api/ValidatorConfig.java libwoodstox-java-5.1.0/src/java/com/ctc/wstx/api/ValidatorConfig.java
--- libwoodstox-java-4.1.3/src/java/com/ctc/wstx/api/ValidatorConfig.java 2012-04-24 04:38:20.000000000 +0000
+++ libwoodstox-java-5.1.0/src/java/com/ctc/wstx/api/ValidatorConfig.java 1970-01-01 00:00:00.000000000 +0000
@@ -1,39 +0,0 @@
-package com.ctc.wstx.api;
-
-public final class ValidatorConfig
- extends CommonConfig
-{
- /**
- * For now, since there are no mutable properties, we can share
- * a singleton instance.
- */
- final static ValidatorConfig sInstance = new ValidatorConfig();
-
- private ValidatorConfig()
- {
- }
-
- public static ValidatorConfig createDefaults()
- {
- /* For now, since there are no mutable properties, we can share
- * a singleton instance.
- */
- return sInstance;
- }
-
- protected int findPropertyId(String propName) {
- // Nothing above and beyond default settings...
- return -1;
- }
-
- protected Object getProperty(int id) {
- // nothing to get:
- return null;
- }
-
- protected boolean setProperty(String propName, int id, Object value) {
- // nothing to set:
- return false;
- }
-}
-
diff -Nru libwoodstox-java-4.1.3/src/java/com/ctc/wstx/api/WriterConfig.java libwoodstox-java-5.1.0/src/java/com/ctc/wstx/api/WriterConfig.java
--- libwoodstox-java-4.1.3/src/java/com/ctc/wstx/api/WriterConfig.java 2012-04-24 04:38:20.000000000 +0000
+++ libwoodstox-java-5.1.0/src/java/com/ctc/wstx/api/WriterConfig.java 1970-01-01 00:00:00.000000000 +0000
@@ -1,869 +0,0 @@
-package com.ctc.wstx.api;
-
-import java.lang.ref.SoftReference;
-import java.util.HashMap;
-
-import javax.xml.stream.*;
-
-import org.codehaus.stax2.XMLOutputFactory2; // for property consts
-import org.codehaus.stax2.XMLStreamProperties;
-import org.codehaus.stax2.io.EscapingWriterFactory;
-
-import com.ctc.wstx.api.WstxOutputProperties;
-import com.ctc.wstx.cfg.OutputConfigFlags;
-import com.ctc.wstx.io.BufferRecycler;
-import com.ctc.wstx.util.ArgUtil;
-import com.ctc.wstx.util.DataUtil;
-
-/**
- * Simple configuration container class; passed by reader factory to reader
- * instance created.
- */
-public final class WriterConfig
- extends CommonConfig
- implements OutputConfigFlags
-{
- // // // Constants for standard Stax properties:
-
- protected final static String DEFAULT_AUTOMATIC_NS_PREFIX = "wstxns";
-
- // // // First, standard Stax writer properties
-
- final static int PROP_AUTOMATIC_NS = 1; // standard property ("repairing")
-
- // // // And then additional Stax2 properties:
-
- // General output settings
- final static int PROP_AUTOMATIC_EMPTY_ELEMENTS = 2;
- final static int PROP_AUTO_CLOSE_OUTPUT = 3;
- // Namespace settings:
- final static int PROP_ENABLE_NS = 4;
- final static int PROP_AUTOMATIC_NS_PREFIX = 5;
- // Escaping text content/attr values:
- final static int PROP_TEXT_ESCAPER = 6;
- final static int PROP_ATTR_VALUE_ESCAPER = 7;
- // Problem checking/reporting options
- final static int PROP_PROBLEM_REPORTER = 8;
-
- // // // And then custom Wstx properties:
-
- // Output settings:
- final static int PROP_OUTPUT_CDATA_AS_TEXT = 11;
-
- final static int PROP_COPY_DEFAULT_ATTRS = 12;
-
- final static int PROP_ESCAPE_CR = 13;
-
- final static int PROP_ADD_SPACE_AFTER_EMPTY_ELEM = 14;
-
- final static int PROP_AUTOMATIC_END_ELEMENTS = 15;
-
- // Validation flags:
-
- final static int PROP_VALIDATE_STRUCTURE = 16;
- final static int PROP_VALIDATE_CONTENT = 17;
- final static int PROP_VALIDATE_ATTR = 18;
- final static int PROP_VALIDATE_NAMES = 19;
- final static int PROP_FIX_CONTENT = 20;
-
- // Other:
-
- final static int PROP_OUTPUT_INVALID_CHAR_HANDLER = 21;
- final static int PROP_OUTPUT_EMPTY_ELEMENT_HANDLER = 22;
-
- // Per-writer instance information
-
- final static int PROP_UNDERLYING_STREAM = 30;
- final static int PROP_UNDERLYING_WRITER = 31;
-
- // // // Default settings for additional properties:
-
- final static boolean DEFAULT_OUTPUT_CDATA_AS_TEXT = false;
- final static boolean DEFAULT_COPY_DEFAULT_ATTRS = false;
-
- /* 26-Dec-2006, TSa: Since CRs have been auto-escaped so far, let's
- * retain the defaults when adding new properties/features.
- */
- final static boolean DEFAULT_ESCAPE_CR = true;
-
- /**
- * 09-Aug-2007, TSa: Space has always been added after empty
- * element (before closing "/>"), but now it is configurable.
- * 31-Dec-2009, TSa: Intention was to leave it enabled for backwards
- * compatibility: but due to a bug this was NOT the case... ugh.
- */
- final static boolean DEFAULT_ADD_SPACE_AFTER_EMPTY_ELEM = false;
-
- /* How about validation? Let's turn them mostly off by default, since
- * there are some performance hits when enabling them.
- */
-
- // Structural checks are easy, cheap and useful...
- final static boolean DEFAULT_VALIDATE_STRUCTURE = true;
-
- /* 17-May-2006, TSa: Since content validation is now much cheaper
- * (due to integrated transcoders) than it used to be, let's
- * just enable content validation too.
- */
- final static boolean DEFAULT_VALIDATE_CONTENT = true;
- final static boolean DEFAULT_VALIDATE_ATTR = false;
- final static boolean DEFAULT_VALIDATE_NAMES = false;
-
- // This only matters if content validation is enabled...
- /**
- * As per [WSTX-120], default was changed to false,
- * from true (default prior to wstx 4.0)
- */
- //final static boolean DEFAULT_FIX_CONTENT = true;
- final static boolean DEFAULT_FIX_CONTENT = false;
-
- /**
- * Default config flags are converted from individual settings,
- * to conform to Stax 1.0 specifications.
- */
- final static int DEFAULT_FLAGS_J2ME =
- 0
-
- // Stax 1.0 mandated:
-
- // namespace-awareness assumed; repairing disabled by default:
- // | CFG_AUTOMATIC_NS
- | CFG_ENABLE_NS
-
- // Usually it's good to allow writer to produce empty elems
- // (note: default for woodstox 1.x was false)
- | CFG_AUTOMATIC_EMPTY_ELEMENTS
-
- | (DEFAULT_OUTPUT_CDATA_AS_TEXT ? CFG_OUTPUT_CDATA_AS_TEXT : 0)
- | (DEFAULT_COPY_DEFAULT_ATTRS ? CFG_COPY_DEFAULT_ATTRS : 0)
- | (DEFAULT_ESCAPE_CR ? CFG_ESCAPE_CR : 0)
- | (DEFAULT_ADD_SPACE_AFTER_EMPTY_ELEM ? CFG_ADD_SPACE_AFTER_EMPTY_ELEM : 0)
- | CFG_AUTOMATIC_END_ELEMENTS
-
- | (DEFAULT_VALIDATE_STRUCTURE ? CFG_VALIDATE_STRUCTURE : 0)
- | (DEFAULT_VALIDATE_CONTENT ? CFG_VALIDATE_CONTENT : 0)
- | (DEFAULT_VALIDATE_ATTR ? CFG_VALIDATE_ATTR : 0)
- | (DEFAULT_VALIDATE_NAMES ? CFG_VALIDATE_NAMES : 0)
- | (DEFAULT_FIX_CONTENT ? CFG_FIX_CONTENT : 0)
-
- // As per Stax 1.0 specs, we can not enable this by default:
- //| CFG_AUTO_CLOSE_INPUT);
- ;
-
- /**
- * For now, full instances start with same settings as J2ME subset
- */
- final static int DEFAULT_FLAGS_FULL = DEFAULT_FLAGS_J2ME;
-
- // // //
-
- /**
- * Map to use for converting from String property ids to ints
- * described above; useful to allow use of switch later on.
- */
- final static HashMap sProperties = new HashMap(8);
- static {
- // // Stax (1.0) standard ones:
- sProperties.put(XMLOutputFactory.IS_REPAIRING_NAMESPACES,
- DataUtil.Integer(PROP_AUTOMATIC_NS));
-
- // // Stax2 standard ones:
-
- // Namespace support
- sProperties.put(XMLStreamProperties.XSP_NAMESPACE_AWARE,
- DataUtil.Integer(PROP_ENABLE_NS));
-
- // Generic output
- sProperties.put(XMLOutputFactory2.P_AUTOMATIC_EMPTY_ELEMENTS,
- DataUtil.Integer(PROP_AUTOMATIC_EMPTY_ELEMENTS));
- sProperties.put(XMLOutputFactory2.P_AUTO_CLOSE_OUTPUT,
- DataUtil.Integer(PROP_AUTO_CLOSE_OUTPUT));
- // Namespace support
- sProperties.put(XMLOutputFactory2.P_AUTOMATIC_NS_PREFIX,
- DataUtil.Integer(PROP_AUTOMATIC_NS_PREFIX));
- // Text/attr value escaping (customized escapers)
- sProperties.put(XMLOutputFactory2.P_TEXT_ESCAPER,
- DataUtil.Integer(PROP_TEXT_ESCAPER));
- sProperties.put(XMLOutputFactory2.P_ATTR_VALUE_ESCAPER,
- DataUtil.Integer(PROP_ATTR_VALUE_ESCAPER));
- // Problem checking/reporting options
- sProperties.put(XMLStreamProperties.XSP_PROBLEM_REPORTER,
- DataUtil.Integer(PROP_PROBLEM_REPORTER));
-
- // // Woodstox-specifics:
-
- // Output conversions
- sProperties.put(WstxOutputProperties.P_OUTPUT_CDATA_AS_TEXT,
- DataUtil.Integer(PROP_OUTPUT_CDATA_AS_TEXT));
- sProperties.put(WstxOutputProperties.P_COPY_DEFAULT_ATTRS,
- DataUtil.Integer(PROP_COPY_DEFAULT_ATTRS));
- sProperties.put(WstxOutputProperties.P_OUTPUT_ESCAPE_CR,
- DataUtil.Integer(PROP_ESCAPE_CR));
- sProperties.put(WstxOutputProperties.P_ADD_SPACE_AFTER_EMPTY_ELEM
-,
- DataUtil.Integer(PROP_ADD_SPACE_AFTER_EMPTY_ELEM));
- sProperties.put(WstxOutputProperties.P_AUTOMATIC_END_ELEMENTS,
- DataUtil.Integer(PROP_AUTOMATIC_END_ELEMENTS));
- sProperties.put(WstxOutputProperties.P_OUTPUT_INVALID_CHAR_HANDLER,
- DataUtil.Integer(PROP_OUTPUT_INVALID_CHAR_HANDLER));
- sProperties.put(WstxOutputProperties.P_OUTPUT_EMPTY_ELEMENT_HANDLER,
- DataUtil.Integer(PROP_OUTPUT_EMPTY_ELEMENT_HANDLER));
-
- // Validation settings:
- sProperties.put(WstxOutputProperties.P_OUTPUT_VALIDATE_STRUCTURE,
- DataUtil.Integer(PROP_VALIDATE_STRUCTURE));
- sProperties.put(WstxOutputProperties.P_OUTPUT_VALIDATE_CONTENT,
- DataUtil.Integer(PROP_VALIDATE_CONTENT));
- sProperties.put(WstxOutputProperties.P_OUTPUT_VALIDATE_ATTR,
- DataUtil.Integer(PROP_VALIDATE_ATTR));
- sProperties.put(WstxOutputProperties.P_OUTPUT_VALIDATE_NAMES,
- DataUtil.Integer(PROP_VALIDATE_NAMES));
- sProperties.put(WstxOutputProperties.P_OUTPUT_FIX_CONTENT,
- DataUtil.Integer(PROP_FIX_CONTENT));
-
- // Underlying stream/writer access
- sProperties.put(WstxOutputProperties.P_OUTPUT_UNDERLYING_STREAM,
- DataUtil.Integer(PROP_UNDERLYING_STREAM));
- sProperties.put(WstxOutputProperties.P_OUTPUT_UNDERLYING_STREAM,
- DataUtil.Integer(PROP_UNDERLYING_STREAM));
- }
-
- /*
- //////////////////////////////////////////////////////////
- // Current config state:
- //////////////////////////////////////////////////////////
- */
-
- final boolean mIsJ2MESubset;
-
- protected int mConfigFlags;
-
- /*
- //////////////////////////////////////////////////////////
- // More special(ized) configuration objects
- //////////////////////////////////////////////////////////
- */
-
- //protected String mAutoNsPrefix;
- //protected EscapingWriterFactory mTextEscaperFactory = null;
- //protected EscapingWriterFactory mAttrValueEscaperFactory = null;
- //protected XMLReporter mProblemReporter = null;
- //protected InvalidCharHandler mInvalidCharHandler = null;
-
- Object[] mSpecialProperties = null;
-
- private final static int SPEC_PROC_COUNT = 6;
-
- private final static int SP_IX_AUTO_NS_PREFIX = 0;
- private final static int SP_IX_TEXT_ESCAPER_FACTORY = 1;
- private final static int SP_IX_ATTR_VALUE_ESCAPER_FACTORY = 2;
- private final static int SP_IX_PROBLEM_REPORTER = 3;
- private final static int SP_IX_INVALID_CHAR_HANDLER = 4;
- private final static int SP_IX_EMPTY_ELEMENT_HANDLER = 5;
-
- /*
- //////////////////////////////////////////////////////////
- // Buffer recycling:
- //////////////////////////////////////////////////////////
- */
-
- /**
- * This ThreadLocal
contains a {@link SoftRerefence}
- * to a {@link BufferRecycler} used to provide a low-cost
- * buffer recycling between Reader instances.
- */
- final static ThreadLocal mRecyclerRef = new ThreadLocal();
-
- /**
- * This is the actually container of the recyclable buffers. It
- * is obtained via ThreadLocal/SoftReference combination, if one
- * exists, when Config instance is created. If one does not
- * exists, it will created first time a buffer is returned.
- */
- BufferRecycler mCurrRecycler = null;
-
- /*
- //////////////////////////////////////////////////////////
- // Life-cycle:
- //////////////////////////////////////////////////////////
- */
-
- private WriterConfig(boolean j2meSubset, int flags, Object[] specProps)
- {
- mIsJ2MESubset = j2meSubset;
- mConfigFlags = flags;
- mSpecialProperties = specProps;
-
- /* Ok, let's then see if we can find a buffer recycler. Since they
- * are lazily constructed, and since GC may just flush them out
- * on its whims, it's possible we might not find one. That's ok;
- * we can reconstruct one if and when we are to return one or more
- * buffers.
- */
- SoftReference ref = (SoftReference) mRecyclerRef.get();
- if (ref != null) {
- mCurrRecycler = (BufferRecycler) ref.get();
- }
- }
-
- public static WriterConfig createJ2MEDefaults()
- {
- return new WriterConfig(true, DEFAULT_FLAGS_J2ME, null);
- }
-
- public static WriterConfig createFullDefaults()
- {
- return new WriterConfig(true, DEFAULT_FLAGS_FULL, null);
- }
-
- public WriterConfig createNonShared()
- {
- Object[] specProps;
-
- if (mSpecialProperties != null) {
- int len = mSpecialProperties.length;
- specProps = new Object[len];
- System.arraycopy(mSpecialProperties, 0, specProps, 0, len);
- } else {
- specProps = null;
- }
- return new WriterConfig(mIsJ2MESubset, mConfigFlags, specProps);
- }
-
- /*
- //////////////////////////////////////////////////////////
- // Implementation of abstract methods
- //////////////////////////////////////////////////////////
- */
-
- protected int findPropertyId(String propName)
- {
- Integer I = (Integer) sProperties.get(propName);
- return (I == null) ? -1 : I.intValue();
- }
-
- /*
- //////////////////////////////////////////////////////////
- // Public API
- //////////////////////////////////////////////////////////
- */
-
- public Object getProperty(int id)
- {
- switch (id) {
-
- // First, Stax 1.0 properties:
-
- case PROP_AUTOMATIC_NS:
- return automaticNamespacesEnabled() ? Boolean.TRUE : Boolean.FALSE;
-
- // Then Stax2 properties:
-
- // First, properties common to input/output factories:
-
- case PROP_ENABLE_NS:
- return willSupportNamespaces() ? Boolean.TRUE : Boolean.FALSE;
- case PROP_PROBLEM_REPORTER:
- return getProblemReporter();
-
- // Then output-specific properties:
- case PROP_AUTOMATIC_EMPTY_ELEMENTS:
- return automaticEmptyElementsEnabled() ? Boolean.TRUE : Boolean.FALSE;
- case PROP_AUTO_CLOSE_OUTPUT:
- return willAutoCloseOutput() ? Boolean.TRUE : Boolean.FALSE;
- case PROP_AUTOMATIC_NS_PREFIX:
- return getAutomaticNsPrefix();
- case PROP_TEXT_ESCAPER:
- return getTextEscaperFactory();
- case PROP_ATTR_VALUE_ESCAPER:
- return getAttrValueEscaperFactory();
-
- // // // Then Woodstox-specific properties:
-
- case PROP_OUTPUT_CDATA_AS_TEXT:
- return willOutputCDataAsText() ? Boolean.TRUE : Boolean.FALSE;
- case PROP_COPY_DEFAULT_ATTRS:
- return willCopyDefaultAttrs() ? Boolean.TRUE : Boolean.FALSE;
- case PROP_ESCAPE_CR:
- return willEscapeCr() ? Boolean.TRUE : Boolean.FALSE;
- case PROP_ADD_SPACE_AFTER_EMPTY_ELEM:
- return willAddSpaceAfterEmptyElem() ? Boolean.TRUE : Boolean.FALSE;
- case PROP_AUTOMATIC_END_ELEMENTS:
- return automaticEndElementsEnabled() ? Boolean.TRUE : Boolean.FALSE;
-
- case PROP_VALIDATE_STRUCTURE:
- return willValidateStructure() ? Boolean.TRUE : Boolean.FALSE;
- case PROP_VALIDATE_CONTENT:
- return willValidateContent() ? Boolean.TRUE : Boolean.FALSE;
- case PROP_VALIDATE_ATTR:
- return willValidateAttributes() ? Boolean.TRUE : Boolean.FALSE;
- case PROP_VALIDATE_NAMES:
- return willValidateNames() ? Boolean.TRUE : Boolean.FALSE;
- case PROP_FIX_CONTENT:
- return willFixContent() ? Boolean.TRUE : Boolean.FALSE;
- case PROP_OUTPUT_INVALID_CHAR_HANDLER:
- return getInvalidCharHandler();
- case PROP_OUTPUT_EMPTY_ELEMENT_HANDLER:
- return getEmptyElementHandler();
-
- // And then per-instance properties: not valid via config object
- case PROP_UNDERLYING_STREAM:
- case PROP_UNDERLYING_WRITER:
- throw new IllegalStateException("Can not access per-stream-writer properties via factory");
- }
-
- throw new IllegalStateException("Internal error: no handler for property with internal id "+id+".");
- }
-
- /**
- * @return True, if the specified property was succesfully
- * set to specified value; false if its value was not changed
- */
- public boolean setProperty(String name, int id, Object value)
- {
- switch (id) {
- // First, Stax 1.0 properties:
-
- case PROP_AUTOMATIC_NS:
- enableAutomaticNamespaces(ArgUtil.convertToBoolean(name, value));
- break;
-
- // // // Then Stax2 ones:
-
- case PROP_ENABLE_NS:
- doSupportNamespaces(ArgUtil.convertToBoolean(name, value));
- break;
- case PROP_PROBLEM_REPORTER:
- setProblemReporter((XMLReporter) value);
- break;
-
- case PROP_AUTOMATIC_EMPTY_ELEMENTS:
- enableAutomaticEmptyElements(ArgUtil.convertToBoolean(name, value));
- break;
-
- case PROP_AUTO_CLOSE_OUTPUT:
- doAutoCloseOutput(ArgUtil.convertToBoolean(name, value));
- break;
-
- case PROP_AUTOMATIC_NS_PREFIX:
- // value should be a String, but let's verify that:
- setAutomaticNsPrefix(value.toString());
- break;
-
- case PROP_TEXT_ESCAPER:
- setTextEscaperFactory((EscapingWriterFactory) value);
- break;
-
- case PROP_ATTR_VALUE_ESCAPER:
- setAttrValueEscaperFactory((EscapingWriterFactory) value);
- break;
-
- // // // Then Woodstox-specific ones:
-
- case PROP_OUTPUT_CDATA_AS_TEXT:
- doOutputCDataAsText(ArgUtil.convertToBoolean(name, value));
- break;
- case PROP_COPY_DEFAULT_ATTRS:
- doCopyDefaultAttrs(ArgUtil.convertToBoolean(name, value));
- break;
- case PROP_ESCAPE_CR:
- doEscapeCr(ArgUtil.convertToBoolean(name, value));
- break;
- case PROP_ADD_SPACE_AFTER_EMPTY_ELEM:
- doAddSpaceAfterEmptyElem(ArgUtil.convertToBoolean(name, value));
- break;
- case PROP_AUTOMATIC_END_ELEMENTS:
- enableAutomaticEndElements(ArgUtil.convertToBoolean(name, value));
- break;
- case PROP_VALIDATE_STRUCTURE:
- doValidateStructure(ArgUtil.convertToBoolean(name, value));
- break;
- case PROP_VALIDATE_CONTENT:
- doValidateContent(ArgUtil.convertToBoolean(name, value));
- break;
- case PROP_VALIDATE_ATTR:
- doValidateAttributes(ArgUtil.convertToBoolean(name, value));
- break;
- case PROP_VALIDATE_NAMES:
- doValidateNames(ArgUtil.convertToBoolean(name, value));
- break;
- case PROP_FIX_CONTENT:
- doFixContent(ArgUtil.convertToBoolean(name, value));
- break;
- case PROP_OUTPUT_INVALID_CHAR_HANDLER:
- setInvalidCharHandler((InvalidCharHandler) value);
- break;
- case PROP_OUTPUT_EMPTY_ELEMENT_HANDLER:
- setEmptyElementHandler((EmptyElementHandler) value);
- break;
-
- case PROP_UNDERLYING_STREAM:
- case PROP_UNDERLYING_WRITER:
- throw new IllegalStateException("Can not modify per-stream-writer properties via factory");
-
- default:
- throw new IllegalStateException("Internal error: no handler for property with internal id "+id+".");
- }
-
- return true;
- }
-
- /*
- //////////////////////////////////////////////////////////
- // Extended Woodstox API, accessors/modifiers
- //////////////////////////////////////////////////////////
- */
-
- // // // "Raw" accessors for on/off properties:
-
- public int getConfigFlags() { return mConfigFlags; }
-
-
- // // // Accessors, standard properties:
-
- public boolean automaticNamespacesEnabled() {
- return hasConfigFlag(CFG_AUTOMATIC_NS);
- }
-
- // // // Accessors, Woodstox properties:
-
- public boolean automaticEmptyElementsEnabled() {
- return hasConfigFlag(CFG_AUTOMATIC_EMPTY_ELEMENTS);
- }
-
-public boolean willAutoCloseOutput() {
- return hasConfigFlag(CFG_AUTO_CLOSE_OUTPUT);
- }
-
- public boolean willSupportNamespaces() {
- return hasConfigFlag(CFG_ENABLE_NS);
- }
-
- public boolean willOutputCDataAsText() {
- return hasConfigFlag(CFG_OUTPUT_CDATA_AS_TEXT);
- }
-
- public boolean willCopyDefaultAttrs() {
- return hasConfigFlag(CFG_COPY_DEFAULT_ATTRS);
- }
-
- public boolean willEscapeCr() {
- return hasConfigFlag(CFG_ESCAPE_CR);
- }
-
- public boolean willAddSpaceAfterEmptyElem() {
- return hasConfigFlag(CFG_ADD_SPACE_AFTER_EMPTY_ELEM);
- }
-
- public boolean automaticEndElementsEnabled() {
- return hasConfigFlag(CFG_AUTOMATIC_END_ELEMENTS);
- }
-
- public boolean willValidateStructure() {
- return hasConfigFlag(CFG_VALIDATE_STRUCTURE);
- }
-
- public boolean willValidateContent() {
- return hasConfigFlag(CFG_VALIDATE_CONTENT);
- }
-
- public boolean willValidateAttributes() {
- return hasConfigFlag(CFG_VALIDATE_ATTR);
- }
-
- public boolean willValidateNames() {
- return hasConfigFlag(CFG_VALIDATE_NAMES);
- }
-
- public boolean willFixContent() {
- return hasConfigFlag(CFG_FIX_CONTENT);
- }
-
- /**
- * @return Prefix to use as the base for automatically generated
- * namespace prefixes ("namespace prefix prefix", so to speak).
- * Defaults to "wstxns".
- */
- public String getAutomaticNsPrefix() {
- String prefix = (String) getSpecialProperty(SP_IX_AUTO_NS_PREFIX);
- if (prefix == null) {
- prefix = DEFAULT_AUTOMATIC_NS_PREFIX;
- }
- return prefix;
- }
-
- public EscapingWriterFactory getTextEscaperFactory() {
- return (EscapingWriterFactory) getSpecialProperty(SP_IX_TEXT_ESCAPER_FACTORY);
- }
-
- public EscapingWriterFactory getAttrValueEscaperFactory() {
- return (EscapingWriterFactory) getSpecialProperty(SP_IX_ATTR_VALUE_ESCAPER_FACTORY);
- }
-
- public XMLReporter getProblemReporter() {
- return (XMLReporter) getSpecialProperty(SP_IX_PROBLEM_REPORTER);
- }
-
- public InvalidCharHandler getInvalidCharHandler() {
- return (InvalidCharHandler) getSpecialProperty(SP_IX_INVALID_CHAR_HANDLER);
- }
-
- public EmptyElementHandler getEmptyElementHandler() {
- return (EmptyElementHandler) getSpecialProperty(SP_IX_EMPTY_ELEMENT_HANDLER);
- }
-
- // // // Mutators:
-
- // Standard properies:
-
- public void enableAutomaticNamespaces(boolean state) {
- setConfigFlag(CFG_AUTOMATIC_NS, state);
- }
-
- // Wstx properies:
-
- public void enableAutomaticEmptyElements(boolean state) {
- setConfigFlag(CFG_AUTOMATIC_EMPTY_ELEMENTS, state);
- }
-
- public void doAutoCloseOutput(boolean state) {
- setConfigFlag(CFG_AUTO_CLOSE_OUTPUT, state);
- }
-
- public void doSupportNamespaces(boolean state) {
- setConfigFlag(CFG_ENABLE_NS, state);
- }
-
- public void doOutputCDataAsText(boolean state) {
- setConfigFlag(CFG_OUTPUT_CDATA_AS_TEXT, state);
- }
-
- public void doCopyDefaultAttrs(boolean state) {
- setConfigFlag(CFG_COPY_DEFAULT_ATTRS, state);
- }
-
- public void doEscapeCr(boolean state) {
- setConfigFlag(CFG_ESCAPE_CR, state);
- }
-
- public void doAddSpaceAfterEmptyElem(boolean state) {
- setConfigFlag(CFG_ADD_SPACE_AFTER_EMPTY_ELEM, state);
- }
-
- public void enableAutomaticEndElements(boolean state) {
- setConfigFlag(CFG_AUTOMATIC_END_ELEMENTS, state);
- }
-
- public void doValidateStructure(boolean state) {
- setConfigFlag(CFG_VALIDATE_STRUCTURE, state);
- }
-
- public void doValidateContent(boolean state) {
- setConfigFlag(CFG_VALIDATE_CONTENT, state);
- }
-
- public void doValidateAttributes(boolean state) {
- setConfigFlag(CFG_VALIDATE_ATTR, state);
- }
-
- public void doValidateNames(boolean state) {
- setConfigFlag(CFG_VALIDATE_NAMES, state);
- }
-
- public void doFixContent(boolean state) {
- setConfigFlag(CFG_FIX_CONTENT, state);
- }
-
- /**
- * @param prefix Prefix to use as the base for automatically generated
- * namespace prefixes ("namespace prefix prefix", so to speak).
- */
- public void setAutomaticNsPrefix(String prefix) {
- setSpecialProperty(SP_IX_AUTO_NS_PREFIX, prefix);
- }
-
- public void setTextEscaperFactory(EscapingWriterFactory f) {
- setSpecialProperty(SP_IX_TEXT_ESCAPER_FACTORY, f);
- }
-
- public void setAttrValueEscaperFactory(EscapingWriterFactory f) {
- setSpecialProperty(SP_IX_ATTR_VALUE_ESCAPER_FACTORY, f);
- }
-
- public void setProblemReporter(XMLReporter rep) {
- setSpecialProperty(SP_IX_PROBLEM_REPORTER, rep);
- }
-
- public void setInvalidCharHandler(InvalidCharHandler h) {
- setSpecialProperty(SP_IX_INVALID_CHAR_HANDLER, h);
- }
-
- public void setEmptyElementHandler(EmptyElementHandler h) {
- setSpecialProperty(SP_IX_EMPTY_ELEMENT_HANDLER, h);
- }
-
- /*
- //////////////////////////////////////////////////////////
- // Extended Woodstox API, profiles
- //////////////////////////////////////////////////////////
- */
-
- /**
- * For Woodstox, this profile enables all basic well-formedness checks,
- * including checking for name validity.
- */
- public void configureForXmlConformance()
- {
- doValidateAttributes(true);
- doValidateContent(true);
- doValidateStructure(true);
- doValidateNames(true);
- }
-
- /**
- * For Woodstox, this profile enables all basic well-formedness checks,
- * including checking for name validity, and also enables all matching
- * "fix-me" properties (currently only content-fixing property exists).
- */
- public void configureForRobustness()
- {
- doValidateAttributes(true);
- doValidateStructure(true);
- doValidateNames(true);
-
- /* This the actual "meat": we do want to not only check if the
- * content is ok, but also "fix" it if not, and if there's a way
- * to fix it:
- */
- doValidateContent(true);
- doFixContent(true);
- }
-
- /**
- * For Woodstox, setting this profile disables most checks for validity;
- * specifically anything that can have measurable performance impact.
- *
- */
- public void configureForSpeed()
- {
- doValidateAttributes(false);
- doValidateContent(false);
- doValidateNames(false);
-
- // Structural validation is cheap: can be left enabled (if already so)
- //doValidateStructure(false);
- }
-
- /*
- /////////////////////////////////////////////////////
- // Buffer recycling:
- /////////////////////////////////////////////////////
- */
-
- /**
- * Method called to allocate intermediate recyclable copy buffers
- */
- public char[] allocMediumCBuffer(int minSize)
- {
- if (mCurrRecycler != null) {
- char[] result = mCurrRecycler.getMediumCBuffer(minSize);
- if (result != null) {
- return result;
- }
- }
- return new char[minSize];
- }
-
- public void freeMediumCBuffer(char[] buffer)
- {
- // Need to create (and assign) the buffer?
- if (mCurrRecycler == null) {
- mCurrRecycler = createRecycler();
- }
- mCurrRecycler.returnMediumCBuffer(buffer);
- }
-
- public char[] allocFullCBuffer(int minSize)
- {
- if (mCurrRecycler != null) {
- char[] result = mCurrRecycler.getFullCBuffer(minSize);
- if (result != null) {
- return result;
- }
- }
- return new char[minSize];
- }
-
- public void freeFullCBuffer(char[] buffer)
- {
- // Need to create (and assign) the buffer?
- if (mCurrRecycler == null) {
- mCurrRecycler = createRecycler();
- }
- mCurrRecycler.returnFullCBuffer(buffer);
- }
-
- public byte[] allocFullBBuffer(int minSize)
- {
- if (mCurrRecycler != null) {
- byte[] result = mCurrRecycler.getFullBBuffer(minSize);
- if (result != null) {
- return result;
- }
- }
- return new byte[minSize];
- }
-
- public void freeFullBBuffer(byte[] buffer)
- {
- // Need to create (and assign) the buffer?
- if (mCurrRecycler == null) {
- mCurrRecycler = createRecycler();
- }
- mCurrRecycler.returnFullBBuffer(buffer);
- }
-
- static int Counter = 0;
-
- private BufferRecycler createRecycler()
- {
- BufferRecycler recycler = new BufferRecycler();
- // No way to reuse/reset SoftReference, have to create new always:
- mRecyclerRef.set(new SoftReference(recycler));
- return recycler;
- }
-
- /*
- //////////////////////////////////////////////////////////
- // Internal methods
- //////////////////////////////////////////////////////////
- */
-
- private void setConfigFlag(int flag, boolean state) {
- if (state) {
- mConfigFlags |= flag;
- } else {
- mConfigFlags &= ~flag;
- }
- }
-
- private final boolean hasConfigFlag(int flag) {
- return ((mConfigFlags & flag) == flag);
- }
-
- private final Object getSpecialProperty(int ix)
- {
- if (mSpecialProperties == null) {
- return null;
- }
- return mSpecialProperties[ix];
- }
-
- private final void setSpecialProperty(int ix, Object value)
- {
- if (mSpecialProperties == null) {
- mSpecialProperties = new Object[SPEC_PROC_COUNT];
- }
- mSpecialProperties[ix] = value;
- }
-}
diff -Nru libwoodstox-java-4.1.3/src/java/com/ctc/wstx/api/WstxInputProperties.java libwoodstox-java-5.1.0/src/java/com/ctc/wstx/api/WstxInputProperties.java
--- libwoodstox-java-4.1.3/src/java/com/ctc/wstx/api/WstxInputProperties.java 2012-04-24 04:38:20.000000000 +0000
+++ libwoodstox-java-5.1.0/src/java/com/ctc/wstx/api/WstxInputProperties.java 1970-01-01 00:00:00.000000000 +0000
@@ -1,263 +0,0 @@
-package com.ctc.wstx.api;
-
-import javax.xml.stream.XMLResolver;
-
-import org.codehaus.stax2.XMLInputFactory2;
-
-/**
- * Class that contains constant for property names used to configure
- * cursor and event readers produced by Wstx implementation of
- * {@link javax.xml.stream.XMLInputFactory}.
- *
- * TODO:
- *
- * - CHECK_CHAR_VALIDITY (separate for white spaces?)
- * - CATALOG_RESOLVER? (or at least, ENABLE_CATALOGS)
- */
-public final class WstxInputProperties
-{
- /**
- * Constants used when no DTD handling is done, and we do not know the
- * 'real' type of an attribute. Seems like CDATA is the safe choice.
- */
- public final static String UNKNOWN_ATTR_TYPE = "CDATA";
-
- /*
- ///////////////////////////////////////////////////////
- // Simple on/off settings:
- ///////////////////////////////////////////////////////
- */
-
- // // // Normalization:
-
- /**
- * Feature that controls whether linefeeds are normalized into
- * canonical linefeed as mandated by xml specification.
- *
- * Note that disabling this property (from its default enabled
- * state) will result in non-conforming XML processing. It may
- * be useful for use cases where changes to input content should
- * be minimized.
- *
- * Note: this property was initially removed from Woodstox 4.0,
- * but was reintroduced in 4.0.8 due to user request.
- */
- public final static String P_NORMALIZE_LFS = "com.ctc.wstx.normalizeLFs";
-
- //public final static String P_NORMALIZE_ATTR_VALUES = "com.ctc.wstx.normalizeAttrValues";
-
- // // // XML character validation:
-
- /**
- * Whether readers will verify that characters in text content are fully
- * valid XML characters (not just Unicode). If true, will check
- * that they are valid (including white space); if false, will not
- * check.
- *
- * Turning this option off may improve parsing performance; leaving
- * it on guarantees compatibility with XML 1.0 specs regarding character
- * validity rules.
- */
- public final static String P_VALIDATE_TEXT_CHARS = "com.ctc.wstx.validateTextChars";
-
-
- // // // Caching:
-
- /**
- * Whether readers will try to cache parsed external DTD subsets or not.
- */
-
- public final static String P_CACHE_DTDS = "com.ctc.wstx.cacheDTDs";
-
- /**
- * Whether reader is to cache DTDs (when caching enabled) based on public id
- * or not: if not, system id will be primarily used. Although theoretically
- * public IDs should be unique, and should be good caching keys, sometimes
- * broken documents use 'wrong' public IDs, and such by default caching keys
- * are based on system id only.
- */
- public final static String P_CACHE_DTDS_BY_PUBLIC_ID = "com.ctc.wstx.cacheDTDsByPublicId";
-
-
- // // // Enabling/disabling lazy/incomplete parsing
-
- /**
- * Whether stream readers are allowed to do lazy parsing, meaning
- * to parse minimal part of the event when
- * {@link javax.xml.stream.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 javax.xml.stream.XMLStreamReader#next} is called, but only when the
- * rest of event are read or skipped.
- *
- * Default value for Woodstox is such that lazy parsing is
- * enabled.
- *
- * @deprecated As of Woodstox 4.0 use
- * {@link XMLInputFactory2#P_LAZY_PARSING} instead (from
- * Stax2 extension API, v3.0)
- */
- public final static String P_LAZY_PARSING = XMLInputFactory2.P_LAZY_PARSING;
-
- // // // API behavior (for backwards compatibility)
-
- /**
- * This read-only property indicates whether null is returned for default name space prefix;
- * Boolean.TRUE indicates it does, Boolean.FALSE that it does not.
- *
- * Default value for 4.1 is 'false'; this will most likely change for 5.0 since
- * Stax API actually specifies null to be used.
- *
- * @since 4.1.2
- */
- public final static String P_RETURN_NULL_FOR_DEFAULT_NAMESPACE = "com.ctc.wstx.returnNullForDefaultNamespace";
-
- // // // Enabling/disabling support for dtd++
-
- /**
- * Whether the Reader will recognized DTD++ extensions when parsing
- * DTD subsets.
- *
- * Note: not implemented as of 2.0.x
- */
- public final static String P_SUPPORT_DTDPP = "com.ctc.wstx.supportDTDPP";
-
-
- /**
- * Whether the Reader will treat character references as entities while parsing
- * XML documents.
- */
- public static final String P_TREAT_CHAR_REFS_AS_ENTS = "com.ctc.wstx.treatCharRefsAsEnts";
-
- // // // Enabling alternate mode for parsing XML fragments instead
- // // // of full documents
-
- // Automatic W3C Schema support?
- /*
- * Whether W3C Schema hint attributes are recognized within document,
- * and used to locate Schema to use for validation.
- */
- //public final static String P_AUTOMATIC_W3C_SCHEMA = 0x00100000;
-
- /*
- ///////////////////////////////////////////////////////
- // More complex settings:
- ///////////////////////////////////////////////////////
- */
-
- // // // Buffer sizes;
-
- /**
- * Size of input buffer (in chars), to use for reading XML content
- * from input stream/reader.
- */
- public final static String P_INPUT_BUFFER_LENGTH = "com.ctc.wstx.inputBufferLength";
-
- // // // Constraints on sizes of text segments parsed:
-
-
- /**
- * Property to specify shortest non-complete text segment (part of
- * CDATA section or text content) that parser is allowed to return,
- * if not required to coalesce text.
- */
- public final static String P_MIN_TEXT_SEGMENT = "com.ctc.wstx.minTextSegment";
-
- // // // Entity handling
-
- /**
- * Property of type {@link java.util.Map}, that defines explicit set of
- * internal (generic) entities that will define of override any entities
- * defined in internal or external subsets; except for the 5 pre-defined
- * entities (lt, gt, amp, apos, quot). Can be used to explicitly define
- * entites that would normally come from a DTD.
- *
- * @deprecated This feature may be removed from future versions of
- * Woodstox, since the same functionality can be achieved by using
- * custom entity resolvers.
- */
- public final static String P_CUSTOM_INTERNAL_ENTITIES = "com.ctc.wstx.customInternalEntities";
-
- /**
- * Property of type {@link XMLResolver}, that
- * will allow overriding of default DTD and external parameter entity
- * resolution.
- */
- public final static String P_DTD_RESOLVER = "com.ctc.wstx.dtdResolver";
-
- /**
- * Property of type {@link XMLResolver}, that
- * will allow overriding of default external general entity
- * resolution. Note that using this property overrides settings done
- * using {@link javax.xml.stream.XMLInputFactory#RESOLVER} (and vice versa).
- */
- public final static String P_ENTITY_RESOLVER = "com.ctc.wstx.entityResolver";
-
- /**
- * Property of type {@link XMLResolver}, that
- * will allow graceful handling of references to undeclared (general)
- * entities.
- */
- public final static String P_UNDECLARED_ENTITY_RESOLVER = "com.ctc.wstx.undeclaredEntityResolver";
-
- /**
- * Property of type {@link java.net.URL}, that will allow specifying
- * context URL to use when resolving relative references, for the
- * main-level entities (external DTD subset, references from the internal
- * DTD subset).
- */
- public final static String P_BASE_URL = "com.ctc.wstx.baseURL";
-
- // // // Alternate parsing modes
-
- /**
- * Three-valued property (one of
- * {@link #PARSING_MODE_DOCUMENT},
- * {@link #PARSING_MODE_FRAGMENT} or
- * {@link #PARSING_MODE_DOCUMENTS}; default being the document mode)
- * that can be used to handle "non-standard" XML content. The default
- * mode (PARSING_MODE_DOCUMENT
) allows parsing of only
- * well-formed XML documents, but the other two modes allow more lenient
- * parsing. Fragment mode allows parsing of XML content that does not
- * have a single root element (can have zero or more), nor can have
- * XML or DOCTYPE declarations: this may be useful if parsing a subset
- * of a full XML document. Multi-document
- * (PARSING_MODE_DOCUMENTS
) mode on the other hand allows
- * parsing of a stream that contains multiple consequtive well-formed
- * documents, with possibly multiple XML and DOCTYPE declarations.
- *
- * The main difference from the API perspective is that in first two
- * modes, START_DOCUMENT and END_DOCUMENT are used as usual (as the first
- * and last events returned), whereas the multi-document mode can return
- * multiple pairs of these events: although it is still true that the
- * first event (one cursor points to when reader is instantiated or
- * returned by the event reader), there may be intervening pairs that
- * signal boundary between two adjacent enclosed documents.
- */
- public final static String P_INPUT_PARSING_MODE = "com.ctc.wstx.fragmentMode";
-
- // // // DTD defaulting, overriding
-
- /*
- ////////////////////////////////////////////////////////////////////
- // Helper classes, values enumerations
- ////////////////////////////////////////////////////////////////////
- */
-
- public final static ParsingMode PARSING_MODE_DOCUMENT = new ParsingMode();
- public final static ParsingMode PARSING_MODE_FRAGMENT = new ParsingMode();
- public final static ParsingMode PARSING_MODE_DOCUMENTS = new ParsingMode();
-
- /**
- * Inner class used for creating type-safe enumerations (prior to JDK 1.5).
- */
- public final static class ParsingMode
- {
- ParsingMode() { }
- }
-}
diff -Nru libwoodstox-java-4.1.3/src/java/com/ctc/wstx/api/WstxOutputProperties.java libwoodstox-java-5.1.0/src/java/com/ctc/wstx/api/WstxOutputProperties.java
--- libwoodstox-java-4.1.3/src/java/com/ctc/wstx/api/WstxOutputProperties.java 2012-04-24 04:38:20.000000000 +0000
+++ libwoodstox-java-5.1.0/src/java/com/ctc/wstx/api/WstxOutputProperties.java 1970-01-01 00:00:00.000000000 +0000
@@ -1,178 +0,0 @@
-package com.ctc.wstx.api;
-
-/**
- * Class that contains constant for property names used to configure
- * cursor and event writers produced by Wstx implementation of
- * {@link javax.xml.stream.XMLOutputFactory}.
- *
- */
-public final class WstxOutputProperties
-{
- /**
- * Default xml version number output, if none was specified by
- * application. Version 1.0 is used
- * to try to maximize compatibility (some older parsers
- * may barf on 1.1 and later...)
- */
- public final static String DEFAULT_XML_VERSION = "1.0";
-
- /**
- * If no encoding is passed, we should just default to what xml
- * in general expects (and can determine), UTF-8.
- *
- * Note: you can check out bug entry [WSTX-18] for more details
- */
- public final static String DEFAULT_OUTPUT_ENCODING = "UTF-8";
-
- // // // Output options, simple on/off settings:
-
- /**
- * Whether writer should just automatically convert all calls that
- * would normally produce CDATA to produce (quoted) text.
- */
- public final static String P_OUTPUT_CDATA_AS_TEXT = "com.ctc.wstx.outputCDataAsText";
-
- /**
- * Whether writer should copy attributes that were initially expanded
- * using default settings ("implicit" attributes) or not.
- */
- public final static String P_COPY_DEFAULT_ATTRS = "com.ctc.wstx.copyDefaultAttrs";
-
- /**
- * Whether writer is to add a single white space before closing "/>"
- * of the empty element or not. It is sometimes useful to add to
- * increase compatibility with HTML browsers, or to increase
- * readability.
- *
- * The default value is 'false', up to Woodstox 4.x.
- *
- * NOTE: JavaDocs for versions 4.0.0 - 4.0.7 incorrectly state that
- * default is 'true': this is NOT the case.
- *
- * Note: added to resolve Jira entry
- * WSTX-125.
- */
- public final static String P_ADD_SPACE_AFTER_EMPTY_ELEM = "com.ctc.wstx.addSpaceAfterEmptyElem";
-
- /**
- * Whether stream writer is to automatically add end elements that are
- * needed to properly close the output tree, when the stream is closed
- * (either explicitly by a call to close
or
- * closeCompletely
, or implicitly by a call
- * to writeEndDocument
.
- *
- * The default value is 'true' as of Woodstox 4.x.
- * Prior to 4.0, this feature was always enabled and there was no
- * way to disable it)
- *
- * @since 3.2.8
- */
- public final static String P_AUTOMATIC_END_ELEMENTS = "com.ctc.wstx.automaticEndElements";
-
- // // // Validation options:
-
- /**
- * Whether output classes should do basic verification that the output
- * structure is well-formed (start and end elements match); that
- * there is one and only one root, and that there is no textual content
- * in prolog/epilog. If false, won't do any checking regarding structure.
- */
- public final static String P_OUTPUT_VALIDATE_STRUCTURE = "com.ctc.wstx.outputValidateStructure";
-
- /**
- * Whether output classes should do basic verification that the textual
- * content output as part of nodes should be checked for validity,
- * if there's a possibility of invalid content. Nodes that include
- * such constraints are: comment/'--', cdata/']]>',
- * proc. instr/'?>'.
- */
- public final static String P_OUTPUT_VALIDATE_CONTENT = "com.ctc.wstx.outputValidateContent";
-
- /**
- * Whether output classes should check uniqueness of attribute names,
- * to prevent accidental output of duplicate attributes.
- */
- public final static String P_OUTPUT_VALIDATE_ATTR = "com.ctc.wstx.outputValidateAttr";
-
- /**
- * Whether output classes should check validity of names, ie that they
- * only contain legal XML identifier characters.
- */
- public final static String P_OUTPUT_VALIDATE_NAMES = "com.ctc.wstx.outputValidateNames";
-
- /**
- * Property that further modifies handling of invalid content so
- * that if {@link #P_OUTPUT_VALIDATE_CONTENT} is enabled, instead of
- * reporting an error, writer will try to fix the problem.
- * Invalid content in this context refers to comment
- * content with "--", CDATA with "]]>" and proc. instr data with "?>".
- * This can
- * be done for some content (CDATA, possibly comment), by splitting
- * content into separate
- * segments; but not for others (proc. instr, since that might
- * change the semantics in unintended ways).
- */
- public final static String P_OUTPUT_FIX_CONTENT = "com.ctc.wstx.outputFixContent";
-
- /**
- * Property that determines whether Carriage Return (\r) characters are
- * to be escaped when output or not. If enabled, all instances of
- * of character \r are escaped using a character entity (where possible,
- * that is, within CHARACTERS events, and attribute values). Otherwise
- * they are output as is. The main reason to enable this property is
- * to ensure that carriage returns are preserved as is through parsing,
- * since otherwise they will be converted to canonical xml linefeeds
- * (\n), when occuring along or as part of \r\n pair.
- */
- public final static String P_OUTPUT_ESCAPE_CR = "com.ctc.wstx.outputEscapeCr";
-
- /**
- * Property that defines a {@link InvalidCharHandler} used to determine
- * what to do with a Java character that app tries to output but which
- * is not a valid xml character. Alternatives are converting it to
- * another character or throw an exception: default implementations
- * exist for both behaviors.
- */
- public final static String P_OUTPUT_INVALID_CHAR_HANDLER = "com.ctc.wstx.outputInvalidCharHandler";
-
- /**
- * Property that defines an {@link EmptyElementHandler} used to determine
- * if the end tag for an empty element should be written or not.
- *
- * If specified {@link org.codehaus.stax2.XMLOutputFactory2#P_AUTOMATIC_EMPTY_ELEMENTS} is ignored.
- */
- public final static String P_OUTPUT_EMPTY_ELEMENT_HANDLER = "com.ctc.wstx.outputEmptyElementHandler";
-
- // // // Per-instance access to underlying output objects
-
- /**
- * Property that can be used to find out the underlying
- * {@link java.io.OutputStream} that an
- * {@link javax.xml.stream.XMLStreamWriter} instance is using,
- * if known (not known if constructed with a {@link java.io.Writer},
- * or other non-stream destination). Null is returned, if not
- * known.
- *
- * Note: in general it is dangerous to operate on returned stream
- * (if any), due to buffering stream writer can do. As such, caller
- * has to take care to know what he is doing, including properly
- * flushing output.
- */
- public final static String P_OUTPUT_UNDERLYING_STREAM = "com.ctc.wstx.outputUnderlyingStream";
-
- /**
- * Property that can be used to find out the underlying
- * {@link java.io.Writer} that an
- * {@link javax.xml.stream.XMLStreamWriter} instance is using,
- * if known (may not be known if constructed with a {@link java.io.OutputStream},
- * or other non-Writer destination). Null is returned, if not
- * known. Note that the Writer may be an internal wrapper over
- * an output stream.
- *
- * Note: in general it is dangerous to operate on returned Writer
- * (if any), due to buffering stream writer can do. As such, caller
- * has to take care to know what he is doing, including properly
- * flushing output.
- */
- public final static String P_OUTPUT_UNDERLYING_WRITER = "com.ctc.wstx.outputUnderlyingWriter";
-}
diff -Nru libwoodstox-java-4.1.3/src/java/com/ctc/wstx/cfg/ErrorConsts.java libwoodstox-java-5.1.0/src/java/com/ctc/wstx/cfg/ErrorConsts.java
--- libwoodstox-java-4.1.3/src/java/com/ctc/wstx/cfg/ErrorConsts.java 2012-04-24 04:38:20.000000000 +0000
+++ libwoodstox-java-5.1.0/src/java/com/ctc/wstx/cfg/ErrorConsts.java 1970-01-01 00:00:00.000000000 +0000
@@ -1,193 +0,0 @@
-package com.ctc.wstx.cfg;
-
-import javax.xml.XMLConstants;
-import javax.xml.stream.XMLStreamConstants;
-
-/**
- * "Static" class that contains error message constants. Note that the
- * error message constants are NOT made final; reason is that doing so
- * would make compiler inline them in other classes. Doing so would increase
- * class size (although not mem usage -- Strings do get interned), with
- * minimal performance impact.
- */
-public class ErrorConsts
- implements XMLStreamConstants
-{
- // // // Types of warnings we issue via XMLReporter
-
- public static String WT_ENT_DECL = "entity declaration";
- public static String WT_ELEM_DECL = "element declaration";
- public static String WT_ATTR_DECL = "attribute declaration";
- public static String WT_XML_DECL = "xml declaration";
- public static String WT_DT_DECL = "doctype declaration";
- public static String WT_NS_DECL = "namespace declaration";
-
- /**
- * This is the generic type for warnings based on XMLValidationProblem
- * objects.
- */
- public static String WT_VALIDATION = "schema validation";
-
- // // And then warning strings
-
- public static String W_UNDEFINED_ELEM = "Undefined element \"{0}\"; referred to by attribute(s)";
- public static String W_MIXED_ENCODINGS = "Inconsistent text encoding; declared as \"{0}\" in xml declaration, application had passed \"{1}\"";
- public static String W_MISSING_DTD = "Missing DOCTYPE declaration in validating mode; can not validate elements or attributes";
- public static String W_DTD_DUP_ATTR = "Attribute \"{0}\" (for element <{1}>) declared multiple times";
- public static String W_DTD_ATTR_REDECL = "Attribute \"{0}\" already declared for element <{1}>; ignoring re-declaration";
-
- // // // Generic errors:
-
- public static String ERR_INTERNAL = "Internal error";
- public static String ERR_NULL_ARG = "Illegal to pass null as argument";
- public static String ERR_UNKNOWN_FEATURE = "Unrecognized feature \"{0}\"";
-
- // // // Wrong reader state:
-
- public static String ERR_STATE_NOT_STELEM = "Current event not START_ELEMENT";
- public static String ERR_STATE_NOT_ELEM = "Current event not START_ELEMENT or END_ELEMENT";
- public static String ERR_STATE_NOT_PI = "Current event not PROCESSING_INSTRUCTION";
- public static String ERR_STATE_NOT_ELEM_OR_TEXT = "Current event ({0}) not START_ELEMENT, END_ELEMENT, CHARACTERS or CDATA";
-
- // // // XML declaration related problems
-
- public static String ERR_XML_10_VS_11 = "XML 1.0 document can not refer to XML 1.1 parsed external entities";
-
- // // // Structural problems, prolog/epilog:
-
- public static String ERR_DTD_IN_EPILOG = "Can not have DOCTYPE declaration in epilog";
- public static String ERR_DTD_DUP = "Duplicate DOCTYPE declaration";
- public static String ERR_CDATA_IN_EPILOG = " (CDATA not allowed in prolog/epilog)";
-
- // // // Illegal input:
-
- public static String ERR_HYPHENS_IN_COMMENT = "String '--' not allowed in comment (missing '>'?)";
- public static String ERR_BRACKET_IN_TEXT = "String ']]>' not allowed in textual content, except as the end marker of CDATA section";
-
- // // // Generic parsing errors:
-
- public static String ERR_UNEXP_KEYWORD = "Unexpected keyword \"{0}\"; expected \"{1}\"";
-
- public static String ERR_WF_PI_MISSING_TARGET = "Missing processing instruction target";
- public static String ERR_WF_PI_XML_TARGET = "Illegal processing instruction target (\"{0}\"); 'xml' (case insensitive) is reserved by the specs.";
- public static String ERR_WF_PI_XML_MISSING_SPACE = "excepted either space or \"?>\" after PI target";
-
- // // // Entity problems:
-
- public static String ERR_WF_ENTITY_EXT_DECLARED = "Entity \"{0}\" declared externally, but referenced from a document declared 'standalone=\"yes\"'";
-
- public static String ERR_WF_GE_UNDECLARED = "Undeclared general entity \"{0}\"";
-
- public static String ERR_WF_GE_UNDECLARED_SA = "Undeclared general entity \"{0}\" (document in stand-alone mode; perhaps declared externally?)";
-
- // // // Namespace problems:
-
- public static String ERR_NS_UNDECLARED = "Undeclared namespace prefix \"{0}\"";
- public static String ERR_NS_UNDECLARED_FOR_ATTR = "Undeclared namespace prefix \"{0}\" (for attribute \"{1}\")";
-
- public static String ERR_NS_REDECL_XML = "Trying to redeclare prefix 'xml' from its default URI '"
- +XMLConstants.XML_NS_URI
- +"' to \"{0}\"";
-
- public static String ERR_NS_REDECL_XMLNS = "Trying to declare prefix 'xmlns' (illegal as per NS 1.1 #4)";
-
- public static String ERR_NS_REDECL_XML_URI = "Trying to bind URI '"
- +XMLConstants.XML_NS_URI+" to prefix \"{0}\" (can only bind to 'xml')";
-
- public static String ERR_NS_REDECL_XMLNS_URI = "Trying to bind URI '"
- +XMLConstants.XMLNS_ATTRIBUTE_NS_URI+" to prefix \"{0}\" (can not be explicitly bound)";
-
- public static String ERR_NS_EMPTY =
-"Non-default namespace can not map to empty URI (as per Namespace 1.0 # 2) in XML 1.0 documents";
-
-
- // // // DTD-specific:
-
- public static String ERR_DTD_MAINLEVEL_KEYWORD = "; expected a keyword (ATTLIST, ELEMENT, ENTITY, NOTATION), comment, or conditional section";
-
- public static String ERR_DTD_ATTR_TYPE = "; expected one of type (CDATA, ID, IDREF, IDREFS, ENTITY, ENTITIES NOTATION, NMTOKEN or NMTOKENS)";
-
- public static String ERR_DTD_DEFAULT_TYPE = "; expected #REQUIRED, #IMPLIED or #FIXED";
-
- public static String ERR_DTD_ELEM_REDEFD =
- "Trying to redefine element \"{0}\" (originally defined at {1})";
- public static String ERR_DTD_NOTATION_REDEFD =
- "Trying to redefine notation \"{0}\" (originally defined at {1})";
-
- public static String ERR_DTD_UNDECLARED_ENTITY =
- "Undeclared {0} entity \"{1}\"";
-
- public static String ERR_DTD_XML_SPACE = "Attribute xml:space has to be defined of type enumerated, and have 1 or 2 values, 'default' and/or 'preserve'";
-
- public static String ERR_DTD_XML_ID = "Attribute xml:id has to have attribute type of ID, as per Xml:id specification";
-
-
- // // // DTD-validation:
-
- public static String ERR_VLD_UNKNOWN_ELEM = "Undefined element <{0}> encountered";
-
- public static String ERR_VLD_EMPTY = "Element <{0}> has EMPTY content specification; can not contain {1}";
- public static String ERR_VLD_NON_MIXED = "Element <{0}> has non-mixed content specification; can not contain non-white space text, or any CDATA sections";
- public static String ERR_VLD_ANY = "Element <{0}> has ANY content specification; can not contain {1}";
- public static String ERR_VLD_UNKNOWN_ATTR = "Element <{0}> has no attribute \"{1}\"";
- public static String ERR_VLD_WRONG_ROOT = "Unexpected root element <{0}>; expected <{0}> as per DOCTYPE declaration";
-
- // // // Output problems:
-
- public static String WERR_PROLOG_CDATA =
- "Trying to output a CDATA block outside main element tree (in prolog or epilog)";
- public static String WERR_PROLOG_NONWS_TEXT =
- "Trying to output non-whitespace characters outside main element tree (in prolog or epilog)";
- public static String WERR_PROLOG_SECOND_ROOT =
- "Trying to output second root, <{0}>";
-
- public static String WERR_CDATA_CONTENT =
- "Illegal input: CDATA block has embedded ']]>' in it (index {0})";
- public static String WERR_COMMENT_CONTENT =
- "Illegal input: comment content has embedded '--' in it (index {0})";
-
- public static String WERR_ATTR_NO_ELEM =
- "Trying to write an attribute when there is no open start element.";
-
- public static String WERR_NAME_EMPTY = "Illegal to pass empty name";
-
- public static String WERR_NAME_ILLEGAL_FIRST_CHAR = "Illegal first name character {0}";
- public static String WERR_NAME_ILLEGAL_CHAR = "Illegal name character {0}";
-
- /*
- ////////////////////////////////////////////////////
- // Utility methods
- ////////////////////////////////////////////////////
- */
-
- public static String tokenTypeDesc(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+"]";
- }
-}
diff -Nru libwoodstox-java-4.1.3/src/java/com/ctc/wstx/cfg/InputConfigFlags.java libwoodstox-java-5.1.0/src/java/com/ctc/wstx/cfg/InputConfigFlags.java
--- libwoodstox-java-4.1.3/src/java/com/ctc/wstx/cfg/InputConfigFlags.java 2012-04-24 04:38:20.000000000 +0000
+++ libwoodstox-java-5.1.0/src/java/com/ctc/wstx/cfg/InputConfigFlags.java 1970-01-01 00:00:00.000000000 +0000
@@ -1,204 +0,0 @@
-package com.ctc.wstx.cfg;
-
-/**
- * Constant interface that contains configuration flag used by parser
- * and parser factory, as well as some other input constants.
- */
-public interface InputConfigFlags
-{
- /*
- //////////////////////////////////////////////////////
- // Flags for standard StAX features:
- //////////////////////////////////////////////////////
- */
-
- // // // Namespace handling:
-
- /**
- * If true, parser will handle namespaces according to XML specs; if
- * false, will only pass them as part of element/attribute name value
- * information.
- */
- final static int CFG_NAMESPACE_AWARE = 0x0001;
-
-
- // // // Text normalization
-
-
- /// Flag that indicates iterator should coalesce all text segments.
- final static int CFG_COALESCE_TEXT = 0x0002;
-
-
- // // // Entity handling
-
- /**
- * Flag that enables automatic replacement of internal entities
- */
- final static int CFG_REPLACE_ENTITY_REFS = 0x0004;
-
- /**
- * Flag that enables support for expanding external entities. Woodstox
- * pretty much ignores the setting, since effectively it is irrelevant,
- * as {@link #CFG_REPLACE_ENTITY_REFS} and {@link #CFG_SUPPORT_DTD}
- * both need to be enabled for external entities to be supported.
- */
- final static int CFG_SUPPORT_EXTERNAL_ENTITIES = 0x0008;
-
- // // // DTD handling
-
- /**
- * Whether DTD handling is enabled or disabled; disabling means both
- * internal and external subsets will just be skipped unprocessed.
- */
- final static int CFG_SUPPORT_DTD = 0x0010;
-
- /**
- * Not yet (fully) supported; added as the placeholder
- */
- final static int CFG_VALIDATE_AGAINST_DTD = 0x0020;
-
- // // Note: can add 2 more 'standard' flags here...
-
- /*
- //////////////////////////////////////////////////////
- // Flags for StAX2 features
- //////////////////////////////////////////////////////
- */
-
- /**
- * If true, parser will report (ignorable) white space events in prolog
- * and epilog; if false, it will silently ignore them.
- */
- final static int CFG_REPORT_PROLOG_WS = 0x0100;
-
- // // // Type conversions:
-
-
- /**
- * If true, parser will accurately report CDATA event as such (unless
- * coalescing); otherwise will always report them as CHARACTERS
- * independent of coalescing settings.
- */
- final static int CFG_REPORT_CDATA = 0x0200;
-
- // // // String interning:
-
- /**
- * If true, will guarantee that all names (attribute/element local names
- * have been intern()ed. If false, this is not guaranteed although
- * implementation may still choose to do it.
- */
- final static int CFG_INTERN_NAMES = 0x0400;
-
- /**
- * It true, will call intern() on all namespace URIs parsed; otherwise
- * will just use 'regular' Strings created from parsed contents. Interning
- * makes namespace-based access faster, but has initial overhead of
- * intern() call.
- */
- final static int CFG_INTERN_NS_URIS = 0x0800;
-
- // // // Lazy/incomplete parsing
-
- /**
- * Property that determines whether Event objects created will
- * contain (accurate) {@link javax.xml.stream.Location} information or not. If not,
- * Location may be null or a fixed location (beginning of main
- * XML file).
- *
- * Note, however, that the underlying parser will still keep track
- * of location information for error reporting purposes; it's only
- * Event objects that are affected.
- */
- final static int CFG_PRESERVE_LOCATION = 0x1000;
-
- // // // Input source handling
-
- /**
- * Property that enables/disables stream reader to close the underlying
- * input source, either when it is asked to (.close() is called), or
- * when it doesn't need it any more (reaching EOF, hitting an
- * unrecoverable exception).
- * As per Stax 1.0 specification, automatic closing is NOT enabled by
- * default; except if the caller has no access to the target (i.e.
- * when factory created it)
- */
- final static int CFG_AUTO_CLOSE_INPUT = 0x2000;
-
- /*
- //////////////////////////////////////////////////////
- // Flags for Woodstox-specific features
- //////////////////////////////////////////////////////
- */
-
- // // // Content normalization
-
- // 20-Jan-2007, TSa: These properties removed from 4.0, deprecated:
- final static int CFG_NORMALIZE_LFS = 0x4000;
- //final static int CFG_NORMALIZE_ATTR_VALUES = 0x8000;
-
- // // // Caching
-
- /**
- * If true, input factory is allowed cache parsed external DTD subsets,
- * potentially speeding up things for which DTDs are needed for: entity
- * substitution, attribute defaulting, and of course DTD-based validation.
- */
- final static int CFG_CACHE_DTDS = 0x00010000;
-
- /**
- * If true, key used for matching DTD subsets can be the public id,
- * if false, only system id can be used.
- */
- final static int CFG_CACHE_DTDS_BY_PUBLIC_ID = 0x00020000;
-
- // // // Lazy/incomplete parsing
-
- /**
- * If true, input factory can defer parsing of nodes until data is
- * actually needed; if false, it has to read all the data in right
- * away when next type is requested. Setting it to true is good for
- * performance, in the cases where some of the nodes (like comments,
- * processing instructions, or whole subtrees) are ignored. Otherwise
- * setting will not make much of a difference. Downside is that error
- * reporting is also done 'lazily'; not right away when getting the next
- * even type but when either accessing data, or skipping it.
- */
- final static int CFG_LAZY_PARSING = 0x00040000;
-
- // // // Validation support
-
- // DTD++ support
-
- /**
- * If true, DTD-parser will recognize DTD++ features, and the validator
- * will also use any such information found from DTD when DTD validation
- * is enabled.
- */
- final static int CFG_SUPPORT_DTDPP = 0x00080000;
-
- // Automatic W3C Schema support?
- //final static int CFG_AUTOMATIC_W3C_SCHEMA = 0x00100000;
-
- // // // Xml:id support
-
- /**
- * If true, xml:id attribute type assignment and matching checks will
- * be done as per Xml:id specification. Needs to be enabled for xml:id
- * uniqueness checks to function properly
- */
- final static int CFG_XMLID_TYPING = 0x00200000;
-
- /**
- * If true, xml:id attribute uniqueness constraints are enforced, even
- * if not validating against DTD otherwise.
- */
- final static int CFG_XMLID_UNIQ_CHECKS = 0x00400000;
-
- /**
- * If true, the XML parser will treat character references as entities.
- *
- */
- final static int CFG_TREAT_CHAR_REFS_AS_ENTS = 0x00800000;
-}
-
diff -Nru libwoodstox-java-4.1.3/src/java/com/ctc/wstx/cfg/OutputConfigFlags.java libwoodstox-java-5.1.0/src/java/com/ctc/wstx/cfg/OutputConfigFlags.java
--- libwoodstox-java-4.1.3/src/java/com/ctc/wstx/cfg/OutputConfigFlags.java 2012-04-24 04:38:20.000000000 +0000
+++ libwoodstox-java-5.1.0/src/java/com/ctc/wstx/cfg/OutputConfigFlags.java 1970-01-01 00:00:00.000000000 +0000
@@ -1,105 +0,0 @@
-package com.ctc.wstx.cfg;
-
-/**
- * Constant interface that contains configuration flag used by output
- * classes internally, for presenting on/off configuration options.
- */
-public interface OutputConfigFlags
-{
- /**
- * Flag that indicates whether writer is namespace-aware or not; if not,
- * only local part is ever used.
- */
- final static int CFG_ENABLE_NS = 0x0001;
-
- /// Flag that indicates that output class should auto-generate namespace prefixes as necessary.
- final static int CFG_AUTOMATIC_NS = 0x0002;
-
- /// Flag that indicates we can output 'automatic' empty elements.
- final static int CFG_AUTOMATIC_EMPTY_ELEMENTS = 0x0004;
-
- /**
- * Whether writer should just automatically convert all calls that
- * would normally produce CDATA to produce (quoted) text.
- */
- final static int CFG_OUTPUT_CDATA_AS_TEXT = 0x0008;
-
- /**
- * Flag that indicates whether attributes expanded from default attribute
- * values should be copied to output, when using copy methods.
- */
- final static int CFG_COPY_DEFAULT_ATTRS = 0x0010;
-
- /**
- * Flag that indicates whether CR (\r, ascii 13) characters occuring
- * in text (CHARACTERS) and attribute values should be escaped using
- * character entities or not. Escaping is needed to enable seamless
- * round-tripping (preserving CR characters).
- */
- final static int CFG_ESCAPE_CR = 0x0020;
-
- /**
- * Flag that indicates
- * whether writer is to add a single white space before closing "/>"
- * of the empty element or not. It is sometimes useful to add to
- * increase compatibility with HTML browsers, or to increase
- * readability.
- */
- final static int CFG_ADD_SPACE_AFTER_EMPTY_ELEM = 0x0040;
-
- /**
- * Flag that indicates we can output 'automatic' empty elements;
- * end elements needed to close the logical output tree when
- * stream writer is closed (by closing it explicitly, or by writing
- * end-document event)
- *
- * @since 3.2.8
- */
- final static int CFG_AUTOMATIC_END_ELEMENTS = 0x0080;
-
- /// Flag that indicates we should check validity of output XML structure.
- final static int CFG_VALIDATE_STRUCTURE = 0x0100;
-
- /**
- * Flag that indicates we should check validity of textual content of
- * nodes that have constraints.
- *
- * Specifically: comments can not have '--', CDATA sections can not
- * have ']]>' and processing instruction can not have '?<' character
- * combinations in content passed in.
- */
- final static int CFG_VALIDATE_CONTENT = 0x0200;
-
- /**
- * Flag that indicates we should check validity of names (element and
- * attribute names and prefixes; processing instruction names), that they
- * contain only legal identifier characters.
- */
- final static int CFG_VALIDATE_NAMES = 0x0400;
-
- /**
- * Flag that indicates we should check uniqueness of attribute names,
- * to prevent accidental output of duplicate attributes.
- */
- final static int CFG_VALIDATE_ATTR = 0x0800;
-
- /**
- * Flag that will enable writer that checks for validity of content
- * to try to fix the problem, by splitting output segments as
- * necessary. If disabled, validation will throw an exception; and
- * without validation no problem is noticed by writer (but instead
- * invalid output is created).
- */
- final static int CFG_FIX_CONTENT = 0x1000;
-
- /**
- * Property that enables/disables stream write to close the underlying
- * output target, either when it is asked to (.close() is called), or
- * when it doesn't need it any more (reaching EOF, hitting an
- * unrecoverable exception).
- * As per Stax 1.0 specification, automatic closing is NOT enabled by
- * default; except if the caller has no access to the target (i.e.
- * when factory created it)
- */
- final static int CFG_AUTO_CLOSE_OUTPUT = 0x2000;
-}
diff -Nru libwoodstox-java-4.1.3/src/java/com/ctc/wstx/cfg/package.html libwoodstox-java-5.1.0/src/java/com/ctc/wstx/cfg/package.html
--- libwoodstox-java-4.1.3/src/java/com/ctc/wstx/cfg/package.html 2012-04-24 04:38:20.000000000 +0000
+++ libwoodstox-java-5.1.0/src/java/com/ctc/wstx/cfg/package.html 1970-01-01 00:00:00.000000000 +0000
@@ -1,3 +0,0 @@
-
-Package that contains internal configuration settings for Woodstox.
-
diff -Nru libwoodstox-java-4.1.3/src/java/com/ctc/wstx/cfg/ParsingErrorMsgs.java libwoodstox-java-5.1.0/src/java/com/ctc/wstx/cfg/ParsingErrorMsgs.java
--- libwoodstox-java-4.1.3/src/java/com/ctc/wstx/cfg/ParsingErrorMsgs.java 2012-04-24 04:38:20.000000000 +0000
+++ libwoodstox-java-5.1.0/src/java/com/ctc/wstx/cfg/ParsingErrorMsgs.java 1970-01-01 00:00:00.000000000 +0000
@@ -1,26 +0,0 @@
-package com.ctc.wstx.cfg;
-
-public interface ParsingErrorMsgs
-{
- // // // EOF problems:
-
- final static String SUFFIX_IN_ATTR_VALUE = " in attribute value";
- final static String SUFFIX_IN_DEF_ATTR_VALUE = " in attribute default value";
- final static String SUFFIX_IN_CDATA = " in CDATA section";
- final static String SUFFIX_IN_CLOSE_ELEMENT = " in end tag";
- final static String SUFFIX_IN_COMMENT = " in comment";
- final static String SUFFIX_IN_DTD = " in DOCTYPE declaration";
- final static String SUFFIX_IN_DTD_EXTERNAL = " in external DTD subset";
- final static String SUFFIX_IN_DTD_INTERNAL = " in internal DTD subset";
- final static String SUFFIX_IN_DOC = " in main document content";
- final static String SUFFIX_IN_ELEMENT = " in start tag";
- final static String SUFFIX_IN_ENTITY_REF = " in entity reference";
- final static String SUFFIX_IN_EPILOG = " in epilog";
- final static String SUFFIX_IN_NAME = " in name token";
- final static String SUFFIX_IN_PROC_INSTR = " in processing instruction";
- final static String SUFFIX_IN_PROLOG = " in prolog";
- final static String SUFFIX_IN_TEXT = " in document text content";
- final static String SUFFIX_IN_XML_DECL = " in xml declaration";
-
- final static String SUFFIX_EOF_EXP_NAME = "; expected an identifier";
-}
diff -Nru libwoodstox-java-4.1.3/src/java/com/ctc/wstx/cfg/XmlConsts.java libwoodstox-java-5.1.0/src/java/com/ctc/wstx/cfg/XmlConsts.java
--- libwoodstox-java-4.1.3/src/java/com/ctc/wstx/cfg/XmlConsts.java 2012-04-24 04:38:20.000000000 +0000
+++ libwoodstox-java-5.1.0/src/java/com/ctc/wstx/cfg/XmlConsts.java 1970-01-01 00:00:00.000000000 +0000
@@ -1,66 +0,0 @@
-package com.ctc.wstx.cfg;
-
-/**
- * Simple constant container interface, shared by input and output
- * sides.
- */
-public interface XmlConsts
-{
- // // // Constants for XML declaration
-
- public final static String XML_DECL_KW_ENCODING = "encoding";
- public final static String XML_DECL_KW_VERSION = "version";
- public final static String XML_DECL_KW_STANDALONE = "standalone";
-
- public final static String XML_V_10_STR = "1.0";
- public final static String XML_V_11_STR = "1.1";
-
- /**
- * This constants refers to cases where the version has not been
- * declared explicitly; and needs to be considered to be 1.0.
- */
- public final static int XML_V_UNKNOWN = 0x0000;
-
- public final static int XML_V_10 = 0x0100;
- public final static int XML_V_11 = 0x0110;
-
- public final static String XML_SA_YES = "yes";
- public final static String XML_SA_NO = "no";
-
- // // // Stax specs mandates some settings: but since exact
- // // // definitions have been re-interpreted a few times,
- // // // let's isolate them in a single place
-
- /* 13-Mar-2008, TSa: As per latest reading of Stax specs,
- * all of these are expected to be "", not null.
- */
-
- public final static String ELEM_NO_NS_URI = "";
-
- public final static String ATTR_NO_NS_URI = "";
-
- public final static String ELEM_NO_PREFIX = "";
-
- public final static String ATTR_NO_PREFIX = "";
-
- /**
- * Top-most namespace URI assigned for root element, if not specifically
- * defined (default namespace unbound).
- *
- * As per Stax specs, related clarifying discussion on
- * the mailing list, and especially JDK 1.6 definitions
- * in {@link javax.xml.XMLConstants} constants, empty String
- * should be used instead of null.
- */
- public final static String DEFAULT_NAMESPACE_URI = ELEM_NO_NS_URI;
-
- // // // Well, these are not strictly xml constants, but for
- // // // now can live here
-
- /**
- * This constant defines the highest Unicode character allowed
- * in XML content.
- */
- final static int MAX_UNICODE_CHAR = 0x10FFFF;
-
-}
diff -Nru libwoodstox-java-4.1.3/src/java/com/ctc/wstx/compat/package.html libwoodstox-java-5.1.0/src/java/com/ctc/wstx/compat/package.html
--- libwoodstox-java-4.1.3/src/java/com/ctc/wstx/compat/package.html 2012-04-24 04:38:20.000000000 +0000
+++ libwoodstox-java-5.1.0/src/java/com/ctc/wstx/compat/package.html 1970-01-01 00:00:00.000000000 +0000
@@ -1,7 +0,0 @@
-
-Package that contains classes that allow abstracting out the details of
-JDK platform version being used. Currently classes are used to implement
-"graceful degradation" of functionality, when certain JDK classes are only
-fully implemented as part of JDKs later than the minimum version
-Woodstox needs for running (for Woodstox versions up to 3.x it was JDK 1.2, for 4.x JDK 1.4).
-
diff -Nru libwoodstox-java-4.1.3/src/java/com/ctc/wstx/compat/QNameCreator.java libwoodstox-java-5.1.0/src/java/com/ctc/wstx/compat/QNameCreator.java
--- libwoodstox-java-4.1.3/src/java/com/ctc/wstx/compat/QNameCreator.java 2012-04-24 04:38:20.000000000 +0000
+++ libwoodstox-java-5.1.0/src/java/com/ctc/wstx/compat/QNameCreator.java 1970-01-01 00:00:00.000000000 +0000
@@ -1,70 +0,0 @@
-package com.ctc.wstx.compat;
-
-import java.util.logging.Logger;
-
-import javax.xml.namespace.QName;
-
-/**
- * Helper class used to solve [WSTX-174]: some older AppServers were
- * shipped with incompatible version of QName class, which is missing
- * the 3 argument constructor. To address this, we'll use bit of
- * ClassLoader hacker to gracefully (?) downgrade to using 2 arg
- * alternatives if necessary.
- *
- * Note: choice of java.util.logging logging is only based on the
- * fact that it is guaranteed to be present (we have JDK 1.4 baseline
- * requirement) so that we do not add external dependencies.
- * It is not a recommendation for using JUL per se; most users would
- * do well to just use slf4j or log4j directly instead.
- *
- * @author Tatu Saloranta
- *
- * @since 3.2.8
- */
-public final class QNameCreator
-{
- /**
- * Creator object that creates QNames using proper 3-arg constructor.
- * If dynamic class loading fails
- */
- private final static Helper _helper;
- static {
- Helper h = null;
- try {
- // Not sure where it'll fail, constructor or create...
- Helper h0 = new Helper();
- /*QName n =*/ h0.create("elem", "http://dummy", "ns");
- h = h0;
- } catch (Throwable t) {
- String msg = "Could not construct QNameCreator.Helper; assume 3-arg QName constructor not available and use 2-arg method instead. Problem: "+t.getMessage();
- try {
- Logger.getLogger("com.ctc.wstx.compat.QNameCreator").warning(msg);
- } catch (Throwable t2) { // just in case JUL craps out...
- System.err.println("ERROR: failed to log error using Logger (problem "+t.getMessage()+"), original problem: "+msg);
- }
- }
- _helper = h;
- }
-
- public static QName create(String uri, String localName, String prefix)
- {
- if (_helper == null) { // can't use 3-arg constructor; but 2-arg will be there
- return new QName(uri, localName);
- }
- return _helper.create(uri, localName, prefix);
- }
-
- /**
- * Helper class used to encapsulate calls to the missing method.
- */
- private final static class Helper
- {
- public Helper() { }
-
- public QName create(String localName, String nsURI, String prefix)
- {
- return new QName(localName, nsURI, prefix);
- }
- }
-}
-
diff -Nru libwoodstox-java-4.1.3/src/java/com/ctc/wstx/dom/DOMOutputElement.java libwoodstox-java-5.1.0/src/java/com/ctc/wstx/dom/DOMOutputElement.java
--- libwoodstox-java-4.1.3/src/java/com/ctc/wstx/dom/DOMOutputElement.java 2012-04-24 04:38:20.000000000 +0000
+++ libwoodstox-java-5.1.0/src/java/com/ctc/wstx/dom/DOMOutputElement.java 1970-01-01 00:00:00.000000000 +0000
@@ -1,212 +0,0 @@
-package com.ctc.wstx.dom;
-
-import javax.xml.namespace.NamespaceContext;
-
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-
-import com.ctc.wstx.sw.OutputElementBase;
-import com.ctc.wstx.util.BijectiveNsMap;
-
-/**
- * Context object that holds information about an open element
- * (one for which START_ELEMENT has been sent, but no END_ELEMENT)
- */
-public final class DOMOutputElement
- extends OutputElementBase
-{
- /**
- * Reference to the parent element, element enclosing this element.
- * Null for root element.
- * Non-final to allow temporary pooling
- * (on per-writer basis, to keep these short-lived).
- */
- private DOMOutputElement mParent;
-
- /**
- * DOM node that is the root under which content is written, in case
- * where there is no parent (mParent == null). If mParent is not null,
- * this will be null.
- * Value is of type
- * {@link Document}, {@link DocumentFragment} or {@link Element}
- */
- private final Node mRootNode;
-
- /**
- * Actual DOM element for which this element object acts as a proxy.
- */
- private Element mElement;
-
- private boolean mDefaultNsSet;
-
- /**
- * Constructor for the virtual root element
- */
- private DOMOutputElement(Node rootNode)
- {
- super();
- mRootNode = rootNode;
- mParent = null;
- mElement = null;
- mNsMapping = null;
- mNsMapShared = false;
- mDefaultNsURI = "";
- mRootNsContext = null;
- mDefaultNsSet = false;
- }
-
- private DOMOutputElement(DOMOutputElement parent, Element element, BijectiveNsMap ns)
- {
- super(parent, ns);
- mRootNode = null;
- mParent = parent;
- mElement = element;
- mNsMapping = ns;
- mNsMapShared = (ns != null);
- mDefaultNsURI = parent.mDefaultNsURI;
- mRootNsContext = parent.mRootNsContext;
- mDefaultNsSet = false;
- }
-
- /**
- * Method called to reuse a pooled instance.
- *
- * @return Chained pooled instance that should now be head of the
- * reuse chain
- */
- private void relink(DOMOutputElement parent, Element element)
- {
- super.relink(parent);
- mParent = parent;
- mElement = element;
- parent.appendNode(element);
- mDefaultNsSet = false;
- }
-
- public static DOMOutputElement createRoot(Node rootNode)
- {
- return new DOMOutputElement(rootNode);
- }
-
- /**
- * Simplest factory method, which gets called when a 1-argument
- * element output method is called. It is, then, assumed to
- * use the default namespace.
- * Will both create the child element and attach it to parent element,
- * or lacking own owner document.
- */
- protected DOMOutputElement createAndAttachChild(Element element)
- {
- if (mRootNode != null) {
- mRootNode.appendChild(element);
- } else {
- mElement.appendChild(element);
- }
- return createChild(element);
- }
-
- protected DOMOutputElement createChild(Element element)
- {
- return new DOMOutputElement(this, element, mNsMapping);
- }
-
- /**
- * @return New head of the recycle pool
- */
- protected DOMOutputElement reuseAsChild(DOMOutputElement parent, Element element)
- {
- DOMOutputElement poolHead = mParent;
- relink(parent, element);
- return poolHead;
- }
-
- /**
- * Method called to temporarily link this instance to a pool, to
- * allow reusing of instances with the same reader.
- */
- protected void addToPool(DOMOutputElement poolHead)
- {
- mParent = poolHead;
- }
-
- /*
- ///////////////////////////////////////////////////////////
- // Public API, accessors
- ///////////////////////////////////////////////////////////
- */
-
- public DOMOutputElement getParent() {
- return mParent;
- }
-
- public boolean isRoot() {
- // (Virtual) Root element has no parent...
- return (mParent == null);
- }
-
- /**
- * @return String presentation of the fully-qualified name, in
- * "prefix:localName" format (no URI). Useful for error and
- * debugging messages.
- */
- public String getNameDesc() {
- if(mElement != null) {
- return mElement.getLocalName();
- }
- return "#error"; // unexpected case
- }
-
- /*
- ///////////////////////////////////////////////////////////
- // Public API, mutators
- ///////////////////////////////////////////////////////////
- */
-
- public void setDefaultNsUri(String uri) {
- mDefaultNsURI = uri;
- mDefaultNsSet = true;
- }
-
- protected void setRootNsContext(NamespaceContext ctxt)
- {
- mRootNsContext = ctxt;
- /* Let's also see if we have an active default ns mapping:
- * (provided it hasn't yet explicitly been set for this element)
- */
- if (!mDefaultNsSet) {
- String defURI = ctxt.getNamespaceURI("");
- if (defURI != null && defURI.length() > 0) {
- mDefaultNsURI = defURI;
- }
- }
- }
-
- /*
- ///////////////////////////////////////////////////////////
- // Public API, DOM manipulation
- ///////////////////////////////////////////////////////////
- */
-
- protected void appendNode(Node n)
- {
- if (mRootNode != null) {
- mRootNode.appendChild(n);
- } else {
- mElement.appendChild(n);
- }
- }
-
- protected void addAttribute(String pname, String value)
- {
- mElement.setAttribute(pname, value);
- }
-
- protected void addAttribute(String uri, String qname, String value)
- {
- mElement.setAttributeNS(uri, qname, value);
- }
-
- public void appendChild(Node n) {
- mElement.appendChild(n);
- }
-}
diff -Nru libwoodstox-java-4.1.3/src/java/com/ctc/wstx/dom/WstxDOMWrappingReader.java libwoodstox-java-5.1.0/src/java/com/ctc/wstx/dom/WstxDOMWrappingReader.java
--- libwoodstox-java-4.1.3/src/java/com/ctc/wstx/dom/WstxDOMWrappingReader.java 2012-04-24 04:38:20.000000000 +0000
+++ libwoodstox-java-5.1.0/src/java/com/ctc/wstx/dom/WstxDOMWrappingReader.java 1970-01-01 00:00:00.000000000 +0000
@@ -1,91 +0,0 @@
-package com.ctc.wstx.dom;
-
-import java.util.Collections;
-
-import javax.xml.stream.*;
-import javax.xml.transform.dom.DOMSource;
-
-//import org.codehaus.stax2.XMLInputFactory2;
-import org.codehaus.stax2.ri.dom.DOMWrappingReader;
-
-import com.ctc.wstx.api.ReaderConfig;
-import com.ctc.wstx.exc.WstxParsingException;
-
-public class WstxDOMWrappingReader
- extends DOMWrappingReader
-{
- protected final ReaderConfig mConfig;
-
- /*
- ///////////////////////////////////////////////////
- // Life-cycle
- ///////////////////////////////////////////////////
- */
-
- protected WstxDOMWrappingReader(DOMSource src, ReaderConfig cfg)
- throws XMLStreamException
- {
- super(src, cfg.willSupportNamespaces(), cfg.willCoalesceText());
- mConfig = cfg;
- // [WSTX-162]: allow enabling/disabling name/ns intern()ing
- if (cfg.hasInternNamesBeenEnabled()) {
- setInternNames(true);
- }
- if (cfg.hasInternNsURIsBeenEnabled()) {
- setInternNsURIs(true);
- }
- }
-
- public static WstxDOMWrappingReader createFrom(DOMSource src, ReaderConfig cfg)
- throws XMLStreamException
- {
- return new WstxDOMWrappingReader(src, cfg);
- }
-
- /*
- ///////////////////////////////////////////////////
- // Defined/Overridden config methods
- ///////////////////////////////////////////////////
- */
-
- public boolean isPropertySupported(String name)
- {
- // !!! TBI: not all these properties are really supported
- return mConfig.isPropertySupported(name);
- }
-
- public Object getProperty(String name)
- {
- if (name.equals("javax.xml.stream.entities")) {
- // !!! TBI
- return Collections.EMPTY_LIST;
- }
- if (name.equals("javax.xml.stream.notations")) {
- // !!! TBI
- return Collections.EMPTY_LIST;
- }
- return mConfig.getProperty(name);
- }
-
- public boolean setProperty(String name, Object value)
- {
- // Basic config accessor works just fine...
- return mConfig.setProperty(name, value);
- }
-
- /*
- ///////////////////////////////////////////////////
- // Defined/Overridden error reporting
- ///////////////////////////////////////////////////
- */
-
- // @Override
- protected void throwStreamException(String msg, Location loc)
- throws XMLStreamException
- {
- if (loc == null) {
- throw new WstxParsingException(msg);
- }
- throw new WstxParsingException(msg, loc);
- }
-}
diff -Nru libwoodstox-java-4.1.3/src/java/com/ctc/wstx/dom/WstxDOMWrappingWriter.java libwoodstox-java-5.1.0/src/java/com/ctc/wstx/dom/WstxDOMWrappingWriter.java
--- libwoodstox-java-4.1.3/src/java/com/ctc/wstx/dom/WstxDOMWrappingWriter.java 2012-04-24 04:38:20.000000000 +0000
+++ libwoodstox-java-5.1.0/src/java/com/ctc/wstx/dom/WstxDOMWrappingWriter.java 1970-01-01 00:00:00.000000000 +0000
@@ -1,744 +0,0 @@
-package com.ctc.wstx.dom;
-
-import java.util.*;
-
-import javax.xml.XMLConstants;
-import javax.xml.namespace.*;
-import javax.xml.stream.*;
-import javax.xml.transform.dom.DOMResult;
-
-import org.w3c.dom.*;
-
-import org.codehaus.stax2.ri.EmptyNamespaceContext;
-import org.codehaus.stax2.ri.dom.DOMWrappingWriter;
-
-import com.ctc.wstx.api.WriterConfig;
-import com.ctc.wstx.cfg.ErrorConsts;
-import com.ctc.wstx.sw.OutputElementBase;
-
-/* TODO:
- *
- * - validator interface implementation
- */
-
-/**
- * This is an adapter class that allows building a DOM tree using
- * {@link XMLStreamWriter} interface.
- *
- * Note that the implementation is only to be used for use with
- * javax.xml.transform.dom.DOMResult
.
- *
- * Some notes regarding missing/incomplete functionality:
- *
- * - Validation functionality not implemented
- *
- *
- *
- * @author Tatu Saloranta
- * @author Dan Diephouse
- */
-public class WstxDOMWrappingWriter
- extends DOMWrappingWriter
-{
- /*
- ///////////////////////////////////////////////////////////
- // Constants
- ///////////////////////////////////////////////////////////
- */
-
- final protected static String ERR_NSDECL_WRONG_STATE =
- "Trying to write a namespace declaration when there is no open start element.";
-
- /*
- ///////////////////////////////////////////////////////////
- // Configuration
- ///////////////////////////////////////////////////////////
- */
-
- protected final WriterConfig mConfig;
-
- /*
- ///////////////////////////////////////////////////////////
- // State
- ///////////////////////////////////////////////////////////
- */
-
- /**
- * This element is the current context element, under which
- * all other nodes are added, until matching end element
- * is output. Null outside of the main element tree.
- *
- * Note: explicit empty element (written using
- * writeEmptyElement
) will never become
- * current element.
- */
- protected DOMOutputElement mCurrElem;
-
- /**
- * This element is non-null right after a call to
- * either writeStartElement
and
- * writeEmptyElement
, and can be used to
- * add attributes and namespace declarations.
- *
- * Note: while this is often the same as {@link #mCurrElem},
- * it's not always. Specifically, an empty element (written
- * explicitly using writeEmptyElement
) will
- * become open element but NOT current element. Conversely,
- * regular elements will remain current element when
- * non elements are written (text, comments, PI), but
- * not the open element.
- */
- protected DOMOutputElement mOpenElement;
-
- /**
- * for NsRepairing mode
- */
- protected int[] mAutoNsSeq;
- protected String mSuggestedDefNs = null;
- protected String mAutomaticNsPrefix;
-
- /**
- * Map that contains URI-to-prefix entries that point out suggested
- * prefixes for URIs. These are populated by calls to
- * {@link #setPrefix}, and they are only used as hints for binding;
- * if there are conflicts, repairing writer can just use some other
- * prefix.
- */
- HashMap mSuggestedPrefixes = null;
-
- /*
- ///////////////////////////////////////////////////////////
- // Life-cycle
- ///////////////////////////////////////////////////////////
- */
-
- private WstxDOMWrappingWriter(WriterConfig cfg, Node treeRoot)
- throws XMLStreamException
- {
- super(treeRoot, cfg.willSupportNamespaces(), cfg.automaticNamespacesEnabled());
- mConfig = cfg;
- mAutoNsSeq = null;
- mAutomaticNsPrefix = mNsRepairing ? mConfig.getAutomaticNsPrefix() : null;
-
- /* Ok; we need a document node; or an element node; or a document
- * fragment node.
- */
- switch (treeRoot.getNodeType()) {
- case Node.DOCUMENT_NODE:
- case Node.DOCUMENT_FRAGMENT_NODE:
- // both are ok, but no current element
- mCurrElem = DOMOutputElement.createRoot(treeRoot);
- mOpenElement = null;
- break;
-
- case Node.ELEMENT_NODE: // can make sub-tree... ok
- {
- // still need a virtual root node as parent
- DOMOutputElement root = DOMOutputElement.createRoot(treeRoot);
- Element elem = (Element) treeRoot;
- mOpenElement = mCurrElem = root.createChild(elem);
- }
- break;
-
- default: // other Nodes not usable
- throw new XMLStreamException("Can not create an XMLStreamWriter for a DOM node of type "+treeRoot.getClass());
- }
- }
-
- public static WstxDOMWrappingWriter createFrom(WriterConfig cfg, DOMResult dst)
- throws XMLStreamException
- {
- Node rootNode = dst.getNode();
- return new WstxDOMWrappingWriter(cfg, rootNode);
- }
-
- /*
- ///////////////////////////////////////////////////////////
- // XMLStreamWriter API (Stax 1.0)
- ///////////////////////////////////////////////////////////
- */
-
- //public void close() { }
- //public void flush() { }
-
-
- public NamespaceContext getNamespaceContext()
- {
- if (!mNsAware) {
- return EmptyNamespaceContext.getInstance();
- }
- return mCurrElem;
- }
-
- public String getPrefix(String uri)
- {
- if (!mNsAware) {
- return null;
- }
- if (mNsContext != null) {
- String prefix = mNsContext.getPrefix(uri);
- if (prefix != null) {
- return prefix;
- }
- }
- return mCurrElem.getPrefix(uri);
- }
-
- public Object getProperty(String name) {
- return mConfig.getProperty(name);
- }
-
- public void setDefaultNamespace(String uri) {
- mSuggestedDefNs = (uri == null || uri.length() == 0) ? null : uri;
- }
-
- //public void setNamespaceContext(NamespaceContext context)
-
- public void setPrefix(String prefix, String uri)
- throws XMLStreamException
- {
- if (prefix == null) {
- throw new NullPointerException("Can not pass null 'prefix' value");
- }
- // Are we actually trying to set the default namespace?
- if (prefix.length() == 0) {
- setDefaultNamespace(uri);
- return;
- }
- if (uri == null) {
- throw new NullPointerException("Can not pass null 'uri' value");
- }
-
- /* Let's verify that xml/xmlns are never (mis)declared; as
- * mandated by XML NS specification
- */
- {
- if (prefix.equals("xml")) {
- if (!uri.equals(XMLConstants.XML_NS_URI)) {
- throwOutputError(ErrorConsts.ERR_NS_REDECL_XML, uri);
- }
- } else if (prefix.equals("xmlns")) { // prefix "xmlns"
- if (!uri.equals(XMLConstants.XMLNS_ATTRIBUTE_NS_URI)) {
- throwOutputError(ErrorConsts.ERR_NS_REDECL_XMLNS, uri);
- }
- // At any rate; we are NOT to output it
- return;
- } else {
- // Neither of prefixes.. but how about URIs?
- if (uri.equals(XMLConstants.XML_NS_URI)) {
- throwOutputError(ErrorConsts.ERR_NS_REDECL_XML_URI, prefix);
- } else if (uri.equals(XMLConstants.XMLNS_ATTRIBUTE_NS_URI)) {
- throwOutputError(ErrorConsts.ERR_NS_REDECL_XMLNS_URI, prefix);
- }
- }
- }
-
- if (mSuggestedPrefixes == null) {
- mSuggestedPrefixes = new HashMap(16);
- }
- mSuggestedPrefixes.put(uri, prefix);
-
- }
-
- public void writeAttribute(String localName, String value)
- throws XMLStreamException
- {
- outputAttribute(null, null, localName, value);
- }
-
- public void writeAttribute(String nsURI, String localName, String value)
- throws XMLStreamException
- {
- outputAttribute(nsURI, null, localName, value);
- }
-
- public void writeAttribute(String prefix, String nsURI, String localName, String value)
- throws XMLStreamException
- {
- outputAttribute(nsURI, prefix, localName, value);
- }
-
- //public void writeCData(String data)
- //public void writeCharacters(char[] text, int start, int len)
- //public void writeCharacters(String text)
- //public void writeComment(String data)
-
- public void writeDefaultNamespace(String nsURI)
- {
- if (mOpenElement == null) {
- throw new IllegalStateException("No currently open START_ELEMENT, cannot write attribute");
- }
- setDefaultNamespace(nsURI);
- mOpenElement.addAttribute(XMLConstants.XMLNS_ATTRIBUTE_NS_URI, "xmlns", nsURI);
- }
-
- //public void writeDTD(String dtd)
-
- public void writeEmptyElement(String localName)
- throws XMLStreamException
- {
- writeEmptyElement(null, localName);
- }
-
- public void writeEmptyElement(String nsURI, String localName)
- throws XMLStreamException
- {
- // First things first: must
-
- /* Note: can not just call writeStartElement(), since this
- * element will only become the open elem, but not a parent elem
- */
- createStartElem(nsURI, null, localName, true);
- }
-
- public void writeEmptyElement(String prefix, String localName, String nsURI)
- throws XMLStreamException
- {
- if (prefix == null) { // passing null would mean "dont care", if repairing
- prefix = "";
- }
- createStartElem(nsURI, prefix, localName, true);
- }
-
- public void writeEndDocument()
- {
- mCurrElem = mOpenElement = null;
- }
-
- public void writeEndElement()
- {
- // Simple, just need to traverse up... if we can
- if (mCurrElem == null || mCurrElem.isRoot()) {
- throw new IllegalStateException("No open start element to close");
- }
- mOpenElement = null; // just in case it was open
- mCurrElem = mCurrElem.getParent();
- }
-
- //public void writeEntityRef(String name)
-
- public void writeNamespace(String prefix, String nsURI) throws XMLStreamException
- {
- if (prefix == null || prefix.length() == 0) {
- writeDefaultNamespace(nsURI);
- return;
- }
- if (!mNsAware) {
- throwOutputError("Can not write namespaces with non-namespace writer.");
- }
- outputAttribute(XMLConstants.XMLNS_ATTRIBUTE_NS_URI, "xmlns", prefix, nsURI);
- mCurrElem.addPrefix(prefix, nsURI);
- }
-
- //public void writeProcessingInstruction(String target)
- //public void writeProcessingInstruction(String target, String data)
-
- //public void writeStartDocument()
- //public void writeStartDocument(String version)
- //public void writeStartDocument(String encoding, String version)
-
- public void writeStartElement(String localName)
- throws XMLStreamException
- {
- writeStartElement(null, localName);
- }
-
- public void writeStartElement(String nsURI, String localName)
- throws XMLStreamException
- {
- createStartElem(nsURI, null, localName, false);
- }
-
- public void writeStartElement(String prefix, String localName, String nsURI)
- throws XMLStreamException
- {
- createStartElem(nsURI, prefix, localName, false);
- }
-
- /*
- ///////////////////////////////////////////////////////////
- // XMLStreamWriter2 API (Stax2 v3.0):
- // additional accessors
- ///////////////////////////////////////////////////////////
- */
-
- //public XMLStreamLocation2 getLocation()
- //public String getEncoding()
-
- public boolean isPropertySupported(String name)
- {
- // !!! TBI: not all these properties are really supported
- return mConfig.isPropertySupported(name);
- }
-
- public boolean setProperty(String name, Object value)
- {
- /* Note: can not call local method, since it'll return false for
- * recognized but non-mutable properties
- */
- return mConfig.setProperty(name, value);
- }
-
- /*
- ///////////////////////////////////////////////////////////
- // XMLStreamWriter2 API (Stax2 v2.0):
- // extended write methods
- ///////////////////////////////////////////////////////////
- */
-
- //public void writeCData(char[] text, int start, int len)
-
- public void writeDTD(String rootName, String systemId, String publicId,
- String internalSubset)
- throws XMLStreamException
- {
- /* Alas: although we can create a DocumentType object, there
- * doesn't seem to be a way to attach it in DOM-2!
- */
- if (mCurrElem != null) {
- throw new IllegalStateException("Operation only allowed to the document before adding root element");
- }
- reportUnsupported("writeDTD()");
- }
-
- //public void writeFullEndElement() throws XMLStreamException
-
- //public void writeSpace(char[] text, int start, int len)
- //public void writeSpace(String text)
-
-
- //public void writeStartDocument(String version, String encoding, boolean standAlone)
-
- /*
- ///////////////////////////////////////////////////////////
- // XMLStreamWriter2 API (Stax2 v2.0): validation
- ///////////////////////////////////////////////////////////
- */
-
- //public XMLValidator validateAgainst(XMLValidationSchema schema)
- //public XMLValidator stopValidatingAgainst(XMLValidationSchema schema)
- //public XMLValidator stopValidatingAgainst(XMLValidator validator)
- //public ValidationProblemHandler setValidationProblemHandler(ValidationProblemHandler h)
-
- /*
- ///////////////////////////////////////////////////////////
- // Impls of abstract methods from base class
- ///////////////////////////////////////////////////////////
- */
-
- protected void appendLeaf(Node n)
- throws IllegalStateException
- {
- mCurrElem.appendNode(n);
- mOpenElement = null;
- }
-
- /*
- ///////////////////////////////////////////////////////////
- // Internal methods
- ///////////////////////////////////////////////////////////
- */
-
- /* Note: copied from regular RepairingNsStreamWriter#writeStartOrEmpty
- * (and its non-repairing counterpart).
- */
-
- /**
- * Method called by all start element write methods.
- *
- * @param nsURI Namespace URI to use: null and empty String denote 'no namespace'
- */
- protected void createStartElem(String nsURI, String prefix, String localName, boolean isEmpty)
- throws XMLStreamException
- {
- DOMOutputElement elem;
-
- if (!mNsAware) {
- if(nsURI != null && nsURI.length() > 0) {
- throwOutputError("Can not specify non-empty uri/prefix in non-namespace mode");
- }
- elem = mCurrElem.createAndAttachChild(mDocument.createElement(localName));
- } else {
- if (mNsRepairing) {
- String actPrefix = validateElemPrefix(prefix, nsURI, mCurrElem);
- if (actPrefix != null) { // fine, an existing binding we can use:
- if (actPrefix.length() != 0) {
- elem = mCurrElem.createAndAttachChild(mDocument.createElementNS(nsURI, actPrefix+":"+localName));
- } else {
- elem = mCurrElem.createAndAttachChild(mDocument.createElementNS(nsURI, localName));
- }
- } else { // nah, need to create a new binding...
- /* Need to ensure that we'll pass "" as prefix, not null,
- * so it is understood as "I want to use the default NS",
- * not as "whatever prefix, I don't care"
- */
- if (prefix == null) {
- prefix = "";
- }
- actPrefix = generateElemPrefix(prefix, nsURI, mCurrElem);
- boolean hasPrefix = (actPrefix.length() != 0);
- if (hasPrefix) {
- localName = actPrefix + ":" + localName;
- }
- elem = mCurrElem.createAndAttachChild(mDocument.createElementNS(nsURI, localName));
- /* Hmmh. writeNamespace method requires open element
- * to be defined. So we'll need to set it first
- * (will be set again at a later point -- would be
- * good to refactor this method into separate
- * sub-classes or so)
- */
- mOpenElement = elem;
- // Need to add new ns declaration as well
- if (hasPrefix) {
- writeNamespace(actPrefix, nsURI);
- elem.addPrefix(actPrefix, nsURI);
- } else {
- writeDefaultNamespace(nsURI);
- elem.setDefaultNsUri(nsURI);
- }
- }
- } else {
- /* Non-repairing; if non-null prefix (including "" to
- * indicate "no prefix") passed, use as is, otherwise
- * try to locate the prefix if got namespace.
- */
- if (prefix == null && nsURI != null && nsURI.length() > 0) {
- if (nsURI == null) {
- nsURI = "";
- }
- prefix = (mSuggestedPrefixes == null) ? null : (String) mSuggestedPrefixes.get(nsURI);
- if (prefix == null) {
- throwOutputError("Can not find prefix for namespace \""+nsURI+"\"");
- }
- }
- if (prefix != null && prefix.length() != 0) {
- localName = prefix + ":" +localName;
- }
- elem = mCurrElem.createAndAttachChild(mDocument.createElementNS(nsURI, localName));
- }
- }
- /* Got the element; need to make it the open element, and
- * if it's not an (explicit) empty element, current element as well
- */
- mOpenElement = elem;
- if (!isEmpty) {
- mCurrElem = elem;
- }
- }
-
- protected void outputAttribute(String nsURI, String prefix, String localName, String value)
- throws XMLStreamException
- {
- if (mOpenElement == null) {
- throw new IllegalStateException("No currently open START_ELEMENT, cannot write attribute");
- }
-
- if (mNsAware) {
- if (mNsRepairing) {
- prefix = findOrCreateAttrPrefix(prefix, nsURI, mOpenElement);
- }
- if (prefix != null && prefix.length() > 0) {
- localName = prefix + ":" + localName;
- }
- mOpenElement.addAttribute(nsURI, localName, value);
- } else { // non-ns, simple
- if (prefix != null && prefix.length() > 0) {
- localName = prefix + ":" + localName;
- }
- mOpenElement.addAttribute(localName, value);
- }
- }
-
- private final String validateElemPrefix(String prefix, String nsURI,
- DOMOutputElement elem)
- throws XMLStreamException
- {
- /* 06-Feb-2005, TSa: Special care needs to be taken for the
- * "empty" (or missing) namespace:
- * (see comments from findOrCreatePrefix())
- */
- if (nsURI == null || nsURI.length() == 0) {
- String currURL = elem.getDefaultNsUri();
- if (currURL == null || currURL.length() == 0) {
- // Ok, good:
- return "";
- }
- // Nope, needs to be re-bound:
- return null;
- }
-
- int status = elem.isPrefixValid(prefix, nsURI, true);
- if (status == DOMOutputElement.PREFIX_OK) {
- return prefix;
- }
- return null;
- }
-
- /*
- ///////////////////////////////////////////////////////////
- // Internal methods
- ///////////////////////////////////////////////////////////
- */
-
- /**
- * Method called to find an existing prefix for the given namespace,
- * if any exists in the scope. If one is found, it's returned (including
- * "" for the current default namespace); if not, null is returned.
- *
- * @param nsURI URI of namespace for which we need a prefix
- */
- protected final String findElemPrefix(String nsURI, DOMOutputElement elem)
- throws XMLStreamException
- {
- /* Special case: empty NS URI can only be bound to the empty
- * prefix...
- */
- if (nsURI == null || nsURI.length() == 0) {
- String currDefNsURI = elem.getDefaultNsUri();
- if (currDefNsURI != null && currDefNsURI.length() > 0) {
- // Nope; won't do... has to be re-bound, but not here:
- return null;
- }
- return "";
- }
- return mCurrElem.getPrefix(nsURI);
- }
-
-
- /**
- * Method called after {@link #findElemPrefix} has returned null,
- * to create and bind a namespace mapping for specified namespace.
- */
- protected final String generateElemPrefix(String suggPrefix, String nsURI,
- DOMOutputElement elem)
- throws XMLStreamException
- {
- /* Ok... now, since we do not have an existing mapping, let's
- * see if we have a preferred prefix to use.
- */
- /* Except if we need the empty namespace... that can only be
- * bound to the empty prefix:
- */
- if (nsURI == null || nsURI.length() == 0) {
- return "";
- }
-
- /* Ok; with elements this is easy: the preferred prefix can
- * ALWAYS be used, since it can mask preceding bindings:
- */
- if (suggPrefix == null) {
- // caller wants this URI to map as the default namespace?
- if (mSuggestedDefNs != null && mSuggestedDefNs.equals(nsURI)) {
- suggPrefix = "";
- } else {
- suggPrefix = (mSuggestedPrefixes == null) ? null:
- (String) mSuggestedPrefixes.get(nsURI);
- if (suggPrefix == null) {
- /* 16-Oct-2005, TSa: We have 2 choices here, essentially;
- * could make elements always try to override the def
- * ns... or can just generate new one. Let's do latter
- * for now.
- */
- if (mAutoNsSeq == null) {
- mAutoNsSeq = new int[1];
- mAutoNsSeq[0] = 1;
- }
- suggPrefix = elem.generateMapping(mAutomaticNsPrefix, nsURI,
- mAutoNsSeq);
- }
- }
- }
-
- // Ok; let's let the caller deal with bindings
- return suggPrefix;
- }
-
-
- /**
- * Method called to somehow find a prefix for given namespace, to be
- * used for a new start element; either use an existing one, or
- * generate a new one. If a new mapping needs to be generated,
- * it will also be automatically bound, and necessary namespace
- * declaration output.
- *
- * @param suggPrefix Suggested prefix to bind, if any; may be null
- * to indicate "no preference"
- * @param nsURI URI of namespace for which we need a prefix
- * @param elem Currently open start element, on which the attribute
- * will be added.
- */
- protected final String findOrCreateAttrPrefix(String suggPrefix, String nsURI,
- DOMOutputElement elem)
- throws XMLStreamException
- {
- if (nsURI == null || nsURI.length() == 0) {
- /* Attributes never use the default namespace; missing
- * prefix always leads to the empty ns... so nothing
- * special is needed here.
- */
- return null;
- }
- // Maybe the suggested prefix is properly bound?
- if (suggPrefix != null) {
- int status = elem.isPrefixValid(suggPrefix, nsURI, false);
- if (status == OutputElementBase.PREFIX_OK) {
- return suggPrefix;
- }
- /* Otherwise, if the prefix is unbound, let's just bind
- * it -- if caller specified a prefix, it probably prefers
- * binding that prefix even if another prefix already existed?
- * The remaining case (already bound to another URI) we don't
- * want to touch, at least not yet: it may or not be safe
- * to change binding, so let's just not try it.
- */
- if (status == OutputElementBase.PREFIX_UNBOUND) {
- elem.addPrefix(suggPrefix, nsURI);
- writeNamespace(suggPrefix, nsURI);
- return suggPrefix;
- }
- }
-
- // If not, perhaps there's another existing binding available?
- String prefix = elem.getExplicitPrefix(nsURI);
- if (prefix != null) { // already had a mapping for the URI... cool.
- return prefix;
- }
-
- /* Nope, need to create one. First, let's see if there's a
- * preference...
- */
- if (suggPrefix != null) {
- prefix = suggPrefix;
- } else if (mSuggestedPrefixes != null) {
- prefix = (String) mSuggestedPrefixes.get(nsURI);
- // note: def ns is never added to suggested prefix map
- }
-
- if (prefix != null) {
- /* Can not use default namespace for attributes.
- * Also, re-binding is tricky for attributes; can't
- * re-bind anything that's bound on this scope... or
- * used in this scope. So, to simplify life, let's not
- * re-bind anything for attributes.
- */
- if (prefix.length() == 0
- || (elem.getNamespaceURI(prefix) != null)) {
- prefix = null;
- }
- }
-
- if (prefix == null) {
- if (mAutoNsSeq == null) {
- mAutoNsSeq = new int[1];
- mAutoNsSeq[0] = 1;
- }
- prefix = mCurrElem.generateMapping(mAutomaticNsPrefix, nsURI,
- mAutoNsSeq);
- }
-
- // Ok; so far so good: let's now bind and output the namespace:
- elem.addPrefix(prefix, nsURI);
- writeNamespace(prefix, nsURI);
- return prefix;
- }
-}
diff -Nru libwoodstox-java-4.1.3/src/java/com/ctc/wstx/dtd/ChoiceContentSpec.java libwoodstox-java-5.1.0/src/java/com/ctc/wstx/dtd/ChoiceContentSpec.java
--- libwoodstox-java-4.1.3/src/java/com/ctc/wstx/dtd/ChoiceContentSpec.java 2012-04-24 04:38:20.000000000 +0000
+++ libwoodstox-java-5.1.0/src/java/com/ctc/wstx/dtd/ChoiceContentSpec.java 1970-01-01 00:00:00.000000000 +0000
@@ -1,240 +0,0 @@
-package com.ctc.wstx.dtd;
-
-import java.util.*;
-
-import com.ctc.wstx.util.ExceptionUtil;
-import com.ctc.wstx.util.PrefixedName;
-
-/**
- * Content specification that defines content model that has
- * multiple alternative elements; including mixed content model.
- */
-public class ChoiceContentSpec
- extends ContentSpec
-{
- final boolean mNsAware;
-
- /**
- * Whether this is a mixed content model; mostly affects String
- * representation
- */
- final boolean mHasMixed;
-
- final ContentSpec[] mContentSpecs;
-
- /*
- ///////////////////////////////////////////////////
- // Life-cycle
- ///////////////////////////////////////////////////
- */
-
- private ChoiceContentSpec(boolean nsAware, char arity, boolean mixed,
- ContentSpec[] specs)
- {
- super(arity);
- mNsAware = nsAware;
- mHasMixed = mixed;
- mContentSpecs = specs;
- }
-
- private ChoiceContentSpec(boolean nsAware, char arity, boolean mixed, Collection specs)
- {
- super(arity);
- mNsAware = nsAware;
- mHasMixed = mixed;
- mContentSpecs = new ContentSpec[specs.size()];
- specs.toArray(mContentSpecs);
- }
-
- public static ChoiceContentSpec constructChoice(boolean nsAware, char arity,
- Collection specs)
- {
- return new ChoiceContentSpec(nsAware, arity, false, specs);
- }
-
- public static ChoiceContentSpec constructMixed(boolean nsAware, Collection specs)
- {
- return new ChoiceContentSpec(nsAware, '*', true, specs);
- }
-
- /*
- ///////////////////////////////////////////////////
- // Public API
- ///////////////////////////////////////////////////
- */
-
- public StructValidator getSimpleValidator()
- {
- /* Can we create a simple validator? Yes, if the sub-specs are
- * all simple (leaves == element tokens with no arity modifier);
- * this is always true for mixed.
- */
- ContentSpec[] specs = mContentSpecs;
- int len = specs.length;
- int i;
-
- if (mHasMixed) {
- i = len;
- } else {
- i = 0;
- for (; i < len; ++i) {
- if (!specs[i].isLeaf()) {
- break;
- }
- }
- }
-
- if (i == len) { // all leaves, kewl
- PrefixedNameSet keyset = namesetFromSpecs(mNsAware, specs);
- return new Validator(mArity, keyset);
- }
-
- // Nah, need a DFA...
- return null;
- }
-
- public ModelNode rewrite()
- {
- // First, need to convert sub-specs:
- ContentSpec[] specs = mContentSpecs;
- int len = specs.length;
- ModelNode[] models = new ModelNode[len];
- for (int i = 0; i < len; ++i) {
- models[i] = specs[i].rewrite();
- }
- ChoiceModel model = new ChoiceModel(models);
-
- // and then resolve arity modifiers, if necessary:
- if (mArity == '*') {
- return new StarModel(model);
- }
- if (mArity == '?') {
- return new OptionalModel(model);
- }
- if (mArity == '+') {
- return new ConcatModel(model,
- new StarModel(model.cloneModel()));
- }
- return model;
- }
-
- public String toString()
- {
- StringBuffer sb = new StringBuffer();
-
- if (mHasMixed) {
- sb.append("(#PCDATA | ");
- } else {
- sb.append('(');
- }
- for (int i = 0; i < mContentSpecs.length; ++i) {
- if (i > 0) {
- sb.append(" | ");
- }
- sb.append(mContentSpecs[i].toString());
- }
- sb.append(')');
-
- if (mArity != ' ') {
- sb.append(mArity);
- }
- return sb.toString();
- }
-
- /*
- ///////////////////////////////////////////////////
- // Internal methods
- ///////////////////////////////////////////////////
- */
-
- /*
- ///////////////////////////////////////////////////
- // Package methods
- ///////////////////////////////////////////////////
- */
-
- protected static PrefixedNameSet namesetFromSpecs(boolean nsAware, ContentSpec[] specs)
- {
- int len = specs.length;
- PrefixedName[] nameArray = new PrefixedName[len];
- for (int i = 0; i < len; ++i) {
- nameArray[i] = ((TokenContentSpec)specs[i]).getName();
- }
-
- if (len < 5) { // 4 or fewer elements -> small
- return new SmallPrefixedNameSet(nsAware, nameArray);
- }
- return new LargePrefixedNameSet(nsAware, nameArray);
- }
-
- /*
- ///////////////////////////////////////////////////
- // Validator class that can be used for simple
- // choices (including mixed content)
- ///////////////////////////////////////////////////
- */
-
- final static class Validator
- extends StructValidator
- {
- final char mArity;
- final PrefixedNameSet mNames;
-
- int mCount = 0;
-
- public Validator(char arity, PrefixedNameSet names)
- {
- mArity = arity;
- mNames = names;
- }
-
- /**
- * Rules for reuse are simple: if we can have any number of
- * repetitions, we can just use a shared root instance. Although
- * its count variable will get updated this doesn't really
- * matter as it won't be used. Otherwise a new instance has to
- * be created always, to keep track of instance counts.
- */
- public StructValidator newInstance() {
- return (mArity == '*') ? this : new Validator(mArity, mNames);
- }
-
- public String tryToValidate(PrefixedName elemName)
- {
- if (!mNames.contains(elemName)) {
- if (mNames.hasMultiple()) {
- return "Expected one of ("+mNames.toString(" | ")+")";
- }
- return "Expected <"+mNames.toString("")+">";
- }
- if (++mCount > 1 && (mArity == '?' || mArity == ' ')) {
- if (mNames.hasMultiple()) {
- return "Expected $END (already had one of ["
- +mNames.toString(" | ")+"]";
- }
- return "Expected $END (already had one <"
- +mNames.toString("")+">]";
- }
- return null;
- }
-
- public String fullyValid()
- {
- switch (mArity) {
- case '*':
- case '?':
- return null;
- case '+': // need at least one (and multiples checked earlier)
- case ' ':
- if (mCount > 0) {
- return null;
- }
- return "Expected "+(mArity == '+' ? "at least" : "")
- +" one of elements ("+mNames+")";
- }
- // should never happen:
- ExceptionUtil.throwGenericInternal();
- return null;
- }
- }
-}
diff -Nru libwoodstox-java-4.1.3/src/java/com/ctc/wstx/dtd/ChoiceModel.java libwoodstox-java-5.1.0/src/java/com/ctc/wstx/dtd/ChoiceModel.java
--- libwoodstox-java-4.1.3/src/java/com/ctc/wstx/dtd/ChoiceModel.java 2012-04-24 04:38:20.000000000 +0000
+++ libwoodstox-java-5.1.0/src/java/com/ctc/wstx/dtd/ChoiceModel.java 1970-01-01 00:00:00.000000000 +0000
@@ -1,110 +0,0 @@
-package com.ctc.wstx.dtd;
-
-import java.util.*;
-
-/**
- * Model class that encapsulates set of sub-models, of which one (and only
- * one) needs to be matched.
- */
-public class ChoiceModel
- extends ModelNode
-{
- final ModelNode[] mSubModels;
-
- boolean mNullable = false;
-
- BitSet mFirstPos, mLastPos;
-
- /*
- ///////////////////////////////////////////////////
- // Life-cycle
- ///////////////////////////////////////////////////
- */
-
- protected ChoiceModel(ModelNode[] subModels)
- {
- super();
- mSubModels = subModels;
- boolean nullable = false;
- for (int i = 0, len = subModels.length; i < len; ++i) {
- if (subModels[i].isNullable()) {
- nullable = true;
- break;
- }
- }
- mNullable = nullable;
- }
-
- /*
- ///////////////////////////////////////////////////
- // Public API
- ///////////////////////////////////////////////////
- */
-
- public String toString()
- {
- StringBuffer sb = new StringBuffer();
- for (int i = 0; i < mSubModels.length; ++i) {
- if (i > 0) {
- sb.append(" | ");
- }
- sb.append(mSubModels[i].toString());
- }
- sb.append(')');
- return sb.toString();
- }
-
- /**
- * Method that has to create a deep copy of the model, without
- * sharing any of existing Objects.
- */
- public ModelNode cloneModel()
- {
- int len = mSubModels.length;
- ModelNode[] newModels = new ModelNode[len];
- for (int i = 0; i < len; ++i) {
- newModels[i] = mSubModels[i].cloneModel();
- }
- return new ChoiceModel(newModels);
- }
-
- public boolean isNullable() {
- return mNullable;
- }
-
- public void indexTokens(List tokens)
- {
- // First, let's ask sub-models to calc their settings
- for (int i = 0, len = mSubModels.length; i < len; ++i) {
- mSubModels[i].indexTokens(tokens);
- }
- }
-
- public void addFirstPos(BitSet firstPos) {
- if (mFirstPos == null) {
- mFirstPos = new BitSet();
- for (int i = 0, len = mSubModels.length; i < len; ++i) {
- mSubModels[i].addFirstPos(mFirstPos);
- }
- }
- firstPos.or(mFirstPos);
- }
-
- public void addLastPos(BitSet lastPos) {
- if (mLastPos == null) {
- mLastPos = new BitSet();
- for (int i = 0, len = mSubModels.length; i < len; ++i) {
- mSubModels[i].addLastPos(mLastPos);
- }
- }
- lastPos.or(mLastPos);
- }
-
- public void calcFollowPos(BitSet[] followPosSets)
- {
- // need to let child models do their stuff:
- for (int i = 0, len = mSubModels.length; i < len; ++i) {
- mSubModels[i].calcFollowPos(followPosSets);
- }
- }
-}
diff -Nru libwoodstox-java-4.1.3/src/java/com/ctc/wstx/dtd/ConcatModel.java libwoodstox-java-5.1.0/src/java/com/ctc/wstx/dtd/ConcatModel.java
--- libwoodstox-java-4.1.3/src/java/com/ctc/wstx/dtd/ConcatModel.java 2012-04-24 04:38:20.000000000 +0000
+++ libwoodstox-java-5.1.0/src/java/com/ctc/wstx/dtd/ConcatModel.java 1970-01-01 00:00:00.000000000 +0000
@@ -1,114 +0,0 @@
-package com.ctc.wstx.dtd;
-
-import java.util.*;
-
-/**
- * Model class that represents sequence of 2 sub-models, needed to be
- * matched in the order.
- */
-public class ConcatModel
- extends ModelNode
-{
- ModelNode mLeftModel;
- ModelNode mRightModel;
-
- final boolean mNullable;
-
- BitSet mFirstPos, mLastPos;
-
- /*
- ///////////////////////////////////////////////////
- // Life-cycle
- ///////////////////////////////////////////////////
- */
-
- public ConcatModel(ModelNode left, ModelNode right)
- {
- super();
- mLeftModel = left;
- mRightModel = right;
- mNullable = mLeftModel.isNullable() && mRightModel.isNullable();
- }
-
- /*
- ///////////////////////////////////////////////////
- // Public API
- ///////////////////////////////////////////////////
- */
-
- /**
- * Method that has to create a deep copy of the model, without
- * sharing any of existing Objects.
- */
- public ModelNode cloneModel() {
- return new ConcatModel(mLeftModel.cloneModel(), mRightModel.cloneModel());
- }
-
- public boolean isNullable() {
- return mNullable;
- }
-
- public void indexTokens(List tokens)
- {
- mLeftModel.indexTokens(tokens);
- mRightModel.indexTokens(tokens);
- }
-
- public void addFirstPos(BitSet pos) {
- if (mFirstPos == null) {
- mFirstPos = new BitSet();
- mLeftModel.addFirstPos(mFirstPos);
- if (mLeftModel.isNullable()) {
- mRightModel.addFirstPos(mFirstPos);
- }
- }
- pos.or(mFirstPos);
- }
-
- public void addLastPos(BitSet pos) {
- if (mLastPos == null) {
- mLastPos = new BitSet();
- mRightModel.addLastPos(mLastPos);
- if (mRightModel.isNullable()) {
- mLeftModel.addLastPos(mLastPos);
- }
- }
- pos.or(mLastPos);
- }
-
- public void calcFollowPos(BitSet[] followPosSets)
- {
- // Let's let sub-models do what they need to do
- mLeftModel.calcFollowPos(followPosSets);
- mRightModel.calcFollowPos(followPosSets);
-
- /* And then we can calculate follower sets between left and
- * right sub models; so that left model's last position entries
- * have right model's first position entries included
- */
- BitSet foll = new BitSet();
- mRightModel.addFirstPos(foll);
-
- BitSet toAddTo = new BitSet();
- mLeftModel.addLastPos(toAddTo);
-
- int ix = 0; // need to/can skip the null entry (index 0)
- while ((ix = toAddTo.nextSetBit(ix+1)) >= 0) {
- /* Ok; so token at this index needs to have follow positions
- * added...
- */
- followPosSets[ix].or(foll);
- }
- }
-
- public String toString()
- {
- StringBuffer sb = new StringBuffer();
- sb.append('(');
- sb.append(mLeftModel.toString());
- sb.append(", ");
- sb.append(mRightModel.toString());
- sb.append(')');
- return sb.toString();
- }
-}
diff -Nru libwoodstox-java-4.1.3/src/java/com/ctc/wstx/dtd/ContentSpec.java libwoodstox-java-5.1.0/src/java/com/ctc/wstx/dtd/ContentSpec.java
--- libwoodstox-java-4.1.3/src/java/com/ctc/wstx/dtd/ContentSpec.java 2012-04-24 04:38:20.000000000 +0000
+++ libwoodstox-java-5.1.0/src/java/com/ctc/wstx/dtd/ContentSpec.java 1970-01-01 00:00:00.000000000 +0000
@@ -1,68 +0,0 @@
-/* Woodstox XML processor
- *
- * Copyright (c) 2004 Tatu Saloranta, tatu.saloranta@iki.fi
- *
- * Licensed under the License specified in the file LICENSE which is
- * included with the source code.
- * You may not use this file except in compliance with the License.
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.ctc.wstx.dtd;
-
-/**
- * Abstract base class for classes that contain parts of a content
- * specification of an element defined in DTD. They are created
- * by {@link FullDTDReader} when parsing an DTD subset, and they
- * will be used for constructing actual validators for the element
- * content.
- */
-public abstract class ContentSpec
-{
- protected char mArity;
-
- /*
- ///////////////////////////////////////////////////
- // Life-cycle
- ///////////////////////////////////////////////////
- */
-
- public ContentSpec(char arity) {
- mArity = arity;
- }
-
- /*
- ///////////////////////////////////////////////////
- // Public API
- ///////////////////////////////////////////////////
- */
-
- public final char getArity() { return mArity; }
-
- public final void setArity(char c) { mArity = c; }
-
- public boolean isLeaf() { return false; }
-
- /**
- * Method called by input element stack to get validator for
- * this content specification, if this specification is simple
- * enough not to need full DFA-based validator.
- *
- * @return Simple content model validator, if one can be directly
- * constructed, or null to indicate that a DFA needs to be
- * created.
- */
- public abstract StructValidator getSimpleValidator();
-
- /**
- * Method called as the first part of DFA construction, if necessary;
- * will usually create simpler {@link ModelNode} instances that will
- * match definition this instance contains.
- */
- public abstract ModelNode rewrite();
-}
diff -Nru libwoodstox-java-4.1.3/src/java/com/ctc/wstx/dtd/DefaultAttrValue.java libwoodstox-java-5.1.0/src/java/com/ctc/wstx/dtd/DefaultAttrValue.java
--- libwoodstox-java-4.1.3/src/java/com/ctc/wstx/dtd/DefaultAttrValue.java 2012-04-24 04:38:20.000000000 +0000
+++ libwoodstox-java-5.1.0/src/java/com/ctc/wstx/dtd/DefaultAttrValue.java 1970-01-01 00:00:00.000000000 +0000
@@ -1,218 +0,0 @@
-/* Woodstox XML processor
- *
- * Copyright (c) 2004- Tatu Saloranta, tatu.saloranta@iki.fi
- *
- * Licensed under the License specified in the file LICENSE which is
- * included with the source code.
- * You may not use this file except in compliance with the License.
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.ctc.wstx.dtd;
-
-import java.text.MessageFormat;
-
-import javax.xml.stream.Location;
-import javax.xml.stream.XMLStreamException;
-
-import org.codehaus.stax2.validation.ValidationContext;
-import org.codehaus.stax2.validation.XMLValidationProblem;
-import org.codehaus.stax2.validation.XMLValidator;
-
-import com.ctc.wstx.cfg.ErrorConsts;
-
-/**
- * Simple container class used to contain information about the default
- * value for an attribute. Although for most use cases a simple String
- * would suffice, there are cases where additional information is needed
- * (especially status of 'broken' default values, which only need to be
- * reported should the default value be needed).
- */
-public final class DefaultAttrValue
-{
- /*
- ////////////////////////////////////////////////////
- // Constants
- ////////////////////////////////////////////////////
- */
-
- // // // Default value types
-
- public final static int DEF_DEFAULT = 1;
- public final static int DEF_IMPLIED = 2;
- public final static int DEF_REQUIRED = 3;
- public final static int DEF_FIXED = 4;
-
- /*
- ////////////////////////////////////////////////////
- // Singleton instances
- ////////////////////////////////////////////////////
- */
-
- final static DefaultAttrValue sImplied = new DefaultAttrValue(DEF_IMPLIED);
-
- final static DefaultAttrValue sRequired = new DefaultAttrValue(DEF_REQUIRED);
-
- /*
- ////////////////////////////////////////////////////
- // State
- ////////////////////////////////////////////////////
- */
-
- final int mDefValueType;
-
- /**
- * Actual expanded textual content of the default attribute value;
- * normalized if appropriate in this mode.
- * Note that all entities have been expanded: if a GE/PE was undefined,
- * and no fatal errors were reported (non-validating mode), the
- * references were just silently removed, and matching entries added
- * to mUndeclaredEntity
- */
- private String mValue = null;
-
- /**
- * For now, let's only keep track of the first undeclared entity:
- * can be extended if necessary.
- */
- private UndeclaredEntity mUndeclaredEntity = null;
-
- /*
- ////////////////////////////////////////////////////
- // Life-cycle (creation, configuration)
- ////////////////////////////////////////////////////
- */
-
- private DefaultAttrValue(int defValueType)
- {
- mDefValueType = defValueType;
- }
-
- public static DefaultAttrValue constructImplied() { return sImplied; }
- public static DefaultAttrValue constructRequired() { return sRequired; }
-
- public static DefaultAttrValue constructFixed() {
- return new DefaultAttrValue(DEF_FIXED);
- }
-
- public static DefaultAttrValue constructOptional() {
- return new DefaultAttrValue(DEF_DEFAULT);
- }
-
- public void setValue(String v) {
- mValue = v;
- }
-
- public void addUndeclaredPE(String name, Location loc)
- {
- addUndeclaredEntity(name, loc, true);
- }
-
- public void addUndeclaredGE(String name, Location loc)
- {
- addUndeclaredEntity(name, loc, false);
- }
-
- public void reportUndeclared(ValidationContext ctxt, XMLValidator dtd)
- throws XMLStreamException
- {
- mUndeclaredEntity.reportUndeclared(ctxt, dtd);
- }
-
- /*
- ////////////////////////////////////////////////////
- // Accessors:
- ////////////////////////////////////////////////////
- */
-
- public boolean hasUndeclaredEntities() {
- return (mUndeclaredEntity != null);
- }
-
- public String getValue() {
- return mValue;
- }
-
- /**
- * @return Expanded default value String, if there were no problems
- * (no undeclared entities), or null to indicate there were problems.
- * In latter case, caller is to figure out exact type of the problem
- * and report this appropriately to the application.
- */
- public String getValueIfOk()
- {
- return (mUndeclaredEntity == null) ? mValue : null;
- }
-
- public boolean isRequired() {
- return (this == sRequired);
- }
-
- public boolean isFixed() {
- return (mDefValueType == DEF_FIXED);
- }
-
- public boolean hasDefaultValue() {
- return (mDefValueType == DEF_DEFAULT)
- || (mDefValueType == DEF_FIXED);
- }
-
- /**
- * Method used by the element to figure out if attribute needs "special"
- * checking; basically if it's required, and/or has a default value.
- * In both cases missing the attribute has specific consequences, either
- * exception or addition of a default value.
- */
- public boolean isSpecial() {
- // Only non-special if #IMPLIED
- return (this != sImplied);
- }
-
- /*
- ////////////////////////////////////////////////////
- // Internal methods
- ////////////////////////////////////////////////////
- */
-
- private void addUndeclaredEntity(String name, Location loc, boolean isPe)
- {
- if (mUndeclaredEntity == null) {
- mUndeclaredEntity = new UndeclaredEntity(name, loc, isPe);
- }
- }
-
- /*
- ////////////////////////////////////////////////////
- // Helper class(es):
- ////////////////////////////////////////////////////
- */
-
- final static class UndeclaredEntity
- {
- final String mName;
- final boolean mIsPe;
- final Location mLocation;
-
- UndeclaredEntity(String name, Location loc, boolean isPe)
- {
- mName = name;
- mIsPe = isPe;
- mLocation = loc;
- }
-
- public void reportUndeclared(ValidationContext ctxt, XMLValidator dtd)
- throws XMLStreamException
- {
- String msg = MessageFormat.format(ErrorConsts.ERR_DTD_UNDECLARED_ENTITY, new Object[] { (mIsPe ? "parsed" : "general"), mName });
- XMLValidationProblem prob = new XMLValidationProblem
- (mLocation, msg, XMLValidationProblem.SEVERITY_FATAL);
- prob.setReporter(dtd);
- ctxt.reportProblem(prob);
- }
- }
-}
diff -Nru libwoodstox-java-4.1.3/src/java/com/ctc/wstx/dtd/DFAState.java libwoodstox-java-5.1.0/src/java/com/ctc/wstx/dtd/DFAState.java
--- libwoodstox-java-4.1.3/src/java/com/ctc/wstx/dtd/DFAState.java 2012-04-24 04:38:20.000000000 +0000
+++ libwoodstox-java-5.1.0/src/java/com/ctc/wstx/dtd/DFAState.java 1970-01-01 00:00:00.000000000 +0000
@@ -1,207 +0,0 @@
-/* Woodstox XML processor
- *
- * Copyright (c) 2004 Tatu Saloranta, tatu.saloranta@iki.fi
- *
- * Licensed under the License specified in the file LICENSE which is
- * included with the source code.
- * You may not use this file except in compliance with the License.
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.ctc.wstx.dtd;
-
-import java.util.*;
-
-import com.ctc.wstx.util.PrefixedName;
-
-/**
- * Class that represents a state in DFA used for validating complex
- * DTD content models.
- */
-public final class DFAState
-{
- final int mIndex;
- final boolean mAccepting;
-
- BitSet mTokenSet;
-
- HashMap mNext = new HashMap();
-
- /*
- ///////////////////////////////////////////////
- // Life-cycle:
- ///////////////////////////////////////////////
- */
-
- public DFAState(int index, BitSet tokenSet)
- {
- mIndex = index;
- // If we have a transition to state 0, it is an accepting state...
- mAccepting = tokenSet.get(0);
- mTokenSet = tokenSet;
- }
-
- public static DFAState constructDFA(ContentSpec rootSpec)
- {
- // Let's first create the real model tree:
- ModelNode modelRoot = rootSpec.rewrite();
-
- /* Then we need to add the dummy end token, and concat node
- * to contain it:
- */
- TokenModel eofToken = TokenModel.getNullToken();
- ConcatModel dummyRoot = new ConcatModel(modelRoot, eofToken);
-
- /* then need to allocate index numbers for tokens
- * (which will also calculate nullability)
- */
- ArrayList tokens = new ArrayList();
- tokens.add(eofToken); // has to be added first, explicitly
- dummyRoot.indexTokens(tokens);
-
- /* And then we can request calculation of follow pos; this will
- * also recursively calculate first/last pos as needed:
- */
- int flen = tokens.size();
- BitSet[] followPos = new BitSet[flen];
- PrefixedName[] tokenNames = new PrefixedName[flen];
- for (int i = 0; i < flen; ++i) {
- followPos[i] = new BitSet(flen);
- tokenNames[i] = ((TokenModel) tokens.get(i)).getName();
- }
- dummyRoot.calcFollowPos(followPos);
-
- /* And then we can calculate DFA stuff. First step is to get
- * firstpos set for the root node, for creating the first
- * state:
- */
- BitSet initial = new BitSet(flen);
- dummyRoot.addFirstPos(initial);
- DFAState firstState = new DFAState(0, initial);
- ArrayList stateList = new ArrayList();
- stateList.add(firstState);
- HashMap stateMap = new HashMap();
- stateMap.put(initial, firstState);
-
- int i = 0;
- while (i < stateList.size()) {
- DFAState curr = (DFAState) stateList.get(i++);
- curr.calcNext(tokenNames, followPos, stateList, stateMap);
- }
-
- // DEBUG:
- /*
- for (i = 0; i < stateList.size(); ++i) {
- //System.out.println(stateList.get(i));
- }
- */
-
- // And there we have it!
- return firstState;
- }
-
- /*
- ///////////////////////////////////////////////
- // Public API, accessors:
- ///////////////////////////////////////////////
- */
-
- public boolean isAcceptingState() {
- return mAccepting;
- }
-
- public int getIndex() {
- return mIndex;
- }
-
- public DFAState findNext(PrefixedName elemName) {
- return (DFAState) mNext.get(elemName);
- }
-
- public TreeSet getNextNames() {
- // Let's order them alphabetically
- TreeSet names = new TreeSet();
- Iterator it = mNext.keySet().iterator();
- while (it.hasNext()) {
- Object o = it.next();
- names.add(o);
- }
- return names;
- }
-
- public void calcNext(PrefixedName[] tokenNames, BitSet[] tokenFPs,
- List stateList, Map stateMap)
- {
- /* Need to loop over all included tokens, and find groups
- * of said tokens
- */
- int first = -1;
-
- /* Need to clone; can not modify in place, since the BitSet
- * is also used as the key...
- */
- BitSet tokenSet = (BitSet) mTokenSet.clone();
- // No need to keep the reference to it, though:
- mTokenSet = null;
-
- while ((first = tokenSet.nextSetBit(first+1)) >= 0) {
- PrefixedName tokenName = tokenNames[first];
-
- /* Special case; the dummy end token has null as name;
- * we can skip that one:
- */
- if (tokenName == null) {
- continue;
- }
-
- BitSet nextGroup = (BitSet) tokenFPs[first].clone();
- int second = first;
-
- while ((second = tokenSet.nextSetBit(second+1)) > 0) {
- if (tokenNames[second] == tokenName) {
- // Let's clear it, too, so we won't match it again:
- tokenSet.clear(second);
- nextGroup.or(tokenFPs[second]);
- }
- }
-
- // Ok; is it a new group?
- DFAState next = (DFAState) stateMap.get(nextGroup);
- if (next == null) { // yup!
- next = new DFAState(stateList.size(), nextGroup);
- stateList.add(next);
- stateMap.put(nextGroup, next);
- }
- mNext.put(tokenName, next);
- }
- }
-
- /*
- ///////////////////////////////////////////////
- // Other methods
- ///////////////////////////////////////////////
- */
-
- public String toString()
- {
- StringBuffer sb = new StringBuffer();
- sb.append("State #"+mIndex+":\n");
- sb.append(" Accepting: "+mAccepting);
- sb.append("\n Next states:\n");
- Iterator it = mNext.entrySet().iterator();
- while (it.hasNext()) {
- Map.Entry en = (Map.Entry) it.next();
- sb.append(en.getKey());
- sb.append(" -> ");
- DFAState next = (DFAState) en.getValue();
- sb.append(next.getIndex());
- sb.append("\n");
- }
- return sb.toString();
- }
-}
diff -Nru libwoodstox-java-4.1.3/src/java/com/ctc/wstx/dtd/DFAValidator.java libwoodstox-java-5.1.0/src/java/com/ctc/wstx/dtd/DFAValidator.java
--- libwoodstox-java-4.1.3/src/java/com/ctc/wstx/dtd/DFAValidator.java 2012-04-24 04:38:20.000000000 +0000
+++ libwoodstox-java-5.1.0/src/java/com/ctc/wstx/dtd/DFAValidator.java 1970-01-01 00:00:00.000000000 +0000
@@ -1,77 +0,0 @@
-/* Woodstox XML processor
- *
- * Copyright (c) 2004 Tatu Saloranta, tatu.saloranta@iki.fi
- *
- * Licensed under the License specified in the file LICENSE which is
- * included with the source code.
- * You may not use this file except in compliance with the License.
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.ctc.wstx.dtd;
-
-import java.util.*;
-
-import com.ctc.wstx.util.PrefixedName;
-import com.ctc.wstx.util.StringUtil;
-
-/**
- * Validator class that is based on a DFA constructed from DTD content
- * specification.
- */
-public final class DFAValidator
- extends StructValidator
-{
- /**
- * For root validator instance, the start state of DFA; for other
- * instances, current state.
- */
- DFAState mState;
-
- public DFAValidator(DFAState initialState) {
- mState = initialState;
- }
-
- public StructValidator newInstance() {
- return new DFAValidator(mState);
- }
-
- public String tryToValidate(PrefixedName elemName)
- {
- // Do we have a follow state with that key?
- DFAState next = mState.findNext(elemName);
-
- if (next == null) {
- // Nope; let's show what we'd have expected instead...
- TreeSet names = mState.getNextNames();
- if (names.size() == 0) { // expected end tag?
- return "Expected $END";
- }
-
- // Either end tag, or another tag?
- if (mState.isAcceptingState()) {
- return "Expected <"+StringUtil.concatEntries(names, ">, <", null)+"> or $END";
- }
- return "Expected <"+StringUtil.concatEntries(names,
- ">, <", "> or <")+">";
- }
-
- mState = next;
- return null;
- }
-
- public String fullyValid()
- {
- if (mState.isAcceptingState()) {
- return null;
- }
- TreeSet names = mState.getNextNames();
- return "Expected <"+StringUtil.concatEntries(names,
- ">, <", "> or <")+">";
- }
-}
diff -Nru libwoodstox-java-4.1.3/src/java/com/ctc/wstx/dtd/DTDAttribute.java libwoodstox-java-5.1.0/src/java/com/ctc/wstx/dtd/DTDAttribute.java
--- libwoodstox-java-4.1.3/src/java/com/ctc/wstx/dtd/DTDAttribute.java 2012-04-24 04:38:20.000000000 +0000
+++ libwoodstox-java-5.1.0/src/java/com/ctc/wstx/dtd/DTDAttribute.java 1970-01-01 00:00:00.000000000 +0000
@@ -1,508 +0,0 @@
-/* Woodstox XML processor
- *
- * Copyright (c) 2004- Tatu Saloranta, tatu.saloranta@iki.fi
- *
- * Licensed under the License specified in the file LICENSE which is
- * included with the source code.
- * You may not use this file except in compliance with the License.
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.ctc.wstx.dtd;
-
-import java.util.Map;
-
-import javax.xml.stream.XMLStreamException;
-
-import org.codehaus.stax2.validation.ValidationContext;
-import org.codehaus.stax2.validation.XMLValidator;
-
-import com.ctc.wstx.ent.EntityDecl;
-import com.ctc.wstx.io.WstxInputData;
-import com.ctc.wstx.sr.InputProblemReporter;
-import com.ctc.wstx.util.PrefixedName;
-import com.ctc.wstx.util.StringUtil;
-import com.ctc.wstx.util.WordResolver;
-
-/**
- * Base class for objects that contain attribute definitions from DTD.
- * Sub-classes exists for specific typed attributes (enumeration-valued,
- * non-CDATA ones); base class itself is used for attributes of type
- * CDATA.
- */
-public abstract class DTDAttribute
-{
- final static char CHAR_SPACE = (char) 0x0020;
-
- /*
- ///////////////////////////////////////////////////
- // Type constants
- ///////////////////////////////////////////////////
- */
-
- // // // Value types
-
- public final static int TYPE_CDATA = 0; // default...
- public final static int TYPE_ENUMERATED = 1;
-
- public final static int TYPE_ID = 2;
- public final static int TYPE_IDREF = 3;
- public final static int TYPE_IDREFS = 4;
-
- public final static int TYPE_ENTITY = 5;
- public final static int TYPE_ENTITIES = 6;
-
- public final static int TYPE_NOTATION = 7;
- public final static int TYPE_NMTOKEN = 8;
- public final static int TYPE_NMTOKENS = 9;
-
- /**
- * Array that has String constants matching above mentioned
- * value types
- */
- final static String[] sTypes = new String[] {
- "CDATA",
- /* 05-Feb-2006, TSa: Hmmh. Apparently SAX specs indicate that
- * enumerated type should be listed as "NMTOKEN"... but most
- * SAX parsers use ENUMERATED, plus this way application can
- * distinguish real NMTOKEN from enumerated type.
- */
- /* 26-Nov-2006, TSa: Either way, we can change type to SAX
- * compatible within SAX classes, not here.
- */
- //"NMTOKEN"
- "ENUMERATED",
- "ID",
- "IDREF",
- "IDREFS",
- "ENTITY",
- "ENTITIES",
- "NOTATION",
- "NMTOKEN",
- "NMTOKENS",
- };
-
- /*
- ///////////////////////////////////////////////////
- // Information about the attribute itself
- ///////////////////////////////////////////////////
- */
-
- protected final PrefixedName mName;
-
- /**
- * Index number amongst "special" attributes (required ones, attributes
- * that have default values), if attribute is one: -1 if not.
- */
- protected final int mSpecialIndex;
-
- protected final DefaultAttrValue mDefValue;
-
- protected final boolean mCfgNsAware;
- protected final boolean mCfgXml11;
-
- /*
- ///////////////////////////////////////////////////
- // Life-cycle
- ///////////////////////////////////////////////////
- */
-
- public DTDAttribute(PrefixedName name, DefaultAttrValue defValue, int specIndex,
- boolean nsAware, boolean xml11)
- {
- mName = name;
- mDefValue = defValue;
- mSpecialIndex = specIndex;
- mCfgNsAware = nsAware;
- mCfgXml11 = xml11;
- }
-
- public abstract DTDAttribute cloneWith(int specIndex);
-
- /*
- ///////////////////////////////////////////////////
- // Public API, accessors
- ///////////////////////////////////////////////////
- */
-
- public final PrefixedName getName() { return mName; }
-
- public final String toString() {
- return mName.toString();
- }
-
- public final String getDefaultValue(ValidationContext ctxt, XMLValidator dtd)
- throws XMLStreamException
- {
- String val = mDefValue.getValueIfOk();
- if (val == null) {
- mDefValue.reportUndeclared(ctxt, dtd);
- /* should never get here, but just to be safe, let's use
- * the 'raw' value (one that does not have undeclared entities
- * included, most likely)
- */
- val = mDefValue.getValue();
- }
- return val;
- }
-
- public final int getSpecialIndex() {
- return mSpecialIndex;
- }
-
- public final boolean needsValidation() {
- return (getValueType() != TYPE_CDATA);
- }
-
- public final boolean isFixed() {
- return mDefValue.isFixed();
- }
-
- public final boolean isRequired() {
- return mDefValue.isRequired();
- }
-
- /**
- * Method used by the element to figure out if attribute needs "special"
- * checking; basically if it's required, and/or has a default value.
- * In both cases missing the attribute has specific consequences, either
- * exception or addition of a default value.
- */
- public final boolean isSpecial() {
- return mDefValue.isSpecial();
- }
-
- public final boolean hasDefaultValue() {
- return mDefValue.hasDefaultValue();
- }
-
- /**
- * Returns the value type of this attribute as an enumerated int
- * to match type (CDATA, ...)
- *
- * Note:
- */
- public int getValueType() {
- return TYPE_CDATA;
- }
-
- public String getValueTypeString()
- {
- return sTypes[getValueType()];
- }
-
- public boolean typeIsId() {
- return false;
- }
-
- public boolean typeIsNotation() {
- return false;
- }
-
- /*
- ///////////////////////////////////////////////////
- // Public API, validation
- ///////////////////////////////////////////////////
- */
-
- public abstract String validate(DTDValidatorBase v, char[] cbuf, int start, int end, boolean normalize)
- throws XMLStreamException;
-
- /**
- *
- * Note: the default implementation is not optimized, as it does
- * a potentially unnecessary copy of the contents. It is expected that
- * this method is seldom called (Woodstox never directly calls it; it
- * only gets called for chained validators when one validator normalizes
- * the value, and then following validators are passed a String, not
- * char array)
- */
- public String validate(DTDValidatorBase v, String value, boolean normalize)
- throws XMLStreamException
- {
- int len = value.length();
- /* Temporary buffer has to come from the validator itself, since
- * attribute objects are stateless and shared...
- */
- char[] cbuf = v.getTempAttrValueBuffer(value.length());
- if (len > 0) {
- value.getChars(0, len, cbuf, 0);
- }
- return validate(v, cbuf, 0, len, normalize);
- }
-
- /**
- * Method called by the {@link DTDValidator}
- * to ask attribute to verify that the default it has (if any) is
- * valid for such type.
- */
- public abstract void validateDefault(InputProblemReporter rep, boolean normalize)
- throws XMLStreamException;
-
- /**
- * Method called when no validation is to be done, but value is still
- * to be normalized as much as it can. What this usually means is that
- * all regular space (parser earlier on converts other white space to
- * spaces, except for specific character entities; and these special
- * cases are NOT to be normalized).
- *
- * The only exception is that CDATA will not do any normalization. But
- * for now, let's implement basic functionality that CDTA instance will
- * override
- *
- * @return Normalized value as a String, if any changes were done;
- * null if input was normalized
- */
- public String normalize(DTDValidatorBase v, char[] cbuf, int start, int end)
- {
- return StringUtil.normalizeSpaces(cbuf, start, end);
- }
-
- /**
- * Method called to do initial normalization of the default attribute
- * value, without trying to verify its validity. Thus, it's
- * called independent of whether we are fully validating the document.
- */
- public void normalizeDefault()
- {
- String val = mDefValue.getValue();
- if (val.length() > 0) {
- char[] cbuf = val.toCharArray();
- String str = StringUtil.normalizeSpaces(cbuf, 0, cbuf.length);
- if (str != null) {
- mDefValue.setValue(str);
- }
- }
- }
-
- /*
- ///////////////////////////////////////////////////
- // Package methods, validation helper methods
- ///////////////////////////////////////////////////
- */
-
- protected String validateDefaultName(InputProblemReporter rep, boolean normalize)
- throws XMLStreamException
- {
- String origDefValue = mDefValue.getValue();
- String defValue = origDefValue.trim();
-
- if (defValue.length() == 0) {
- reportValidationProblem(rep, "Invalid default value '"+defValue
- +"'; empty String is not a valid name");
- }
-
- // Ok, needs to be a valid XML name:
- int illegalIx = WstxInputData.findIllegalNameChar(defValue, mCfgNsAware, mCfgXml11);
- if (illegalIx >= 0) {
- if (illegalIx == 0) {
- reportValidationProblem(rep, "Invalid default value '"+defValue+"'; character "
- +WstxInputData.getCharDesc(defValue.charAt(0))
- +") not valid first character of a name");
- } else {
- reportValidationProblem(rep, "Invalid default value '"+defValue+"'; character #"+illegalIx+" ("
- +WstxInputData.getCharDesc(defValue.charAt(illegalIx))
- +") not valid name character");
- }
- }
-
- // Ok, cool it's ok...
- return normalize ? defValue : origDefValue;
- }
-
- protected String validateDefaultNames(InputProblemReporter rep, boolean normalize)
- throws XMLStreamException
- {
- String defValue = mDefValue.getValue().trim();
- int len = defValue.length();
-
- // Then code similar to actual value validation:
- StringBuffer sb = null;
- int count = 0;
- int start = 0;
-
- main_loop:
- while (start < len) {
- char c = defValue.charAt(start);
-
- // Ok, any white space to skip?
- while (true) {
- if (!WstxInputData.isSpaceChar(c)) {
- break;
- }
- if (++start >= len) {
- break main_loop;
- }
- c = defValue.charAt(start);
- }
-
- // Then need to find the token itself:
- int i = start+1;
-
- for (; i < len; ++i) {
- if (WstxInputData.isSpaceChar(defValue.charAt(i))) {
- break;
- }
- }
- String token = defValue.substring(start, i);
- int illegalIx = WstxInputData.findIllegalNameChar(token, mCfgNsAware, mCfgXml11);
- if (illegalIx >= 0) {
- if (illegalIx == 0) {
- reportValidationProblem(rep, "Invalid default value '"+defValue
- +"'; character "
- +WstxInputData.getCharDesc(defValue.charAt(start))
- +") not valid first character of a name token");
- } else {
- reportValidationProblem(rep, "Invalid default value '"+defValue
- +"'; character "
- +WstxInputData.getCharDesc(c)
- +") not a valid name character");
- }
- }
- ++count;
- if (normalize) {
- if (sb == null) {
- sb = new StringBuffer(i - start + 32);
- } else {
- sb.append(' ');
- }
- sb.append(token);
- }
- start = i+1;
- }
-
- if (count == 0) {
- reportValidationProblem(rep, "Invalid default value '"+defValue
- +"'; empty String is not a valid name value");
- }
-
- return normalize ? sb.toString() : defValue;
- }
-
- protected String validateDefaultNmToken(InputProblemReporter rep, boolean normalize)
- throws XMLStreamException
- {
- String origDefValue = mDefValue.getValue();
- String defValue = origDefValue.trim();
-
- if (defValue.length() == 0) {
- reportValidationProblem(rep, "Invalid default value '"+defValue+"'; empty String is not a valid NMTOKEN");
- }
- int illegalIx = WstxInputData.findIllegalNmtokenChar(defValue, mCfgNsAware, mCfgXml11);
- if (illegalIx >= 0) {
- reportValidationProblem(rep, "Invalid default value '"+defValue
- +"'; character #"+illegalIx+" ("
- +WstxInputData.getCharDesc(defValue.charAt(illegalIx))
- +") not valid NMTOKEN character");
- }
- // Ok, cool it's ok...
- return normalize ? defValue : origDefValue;
- }
-
- /**
- * Method called by validation/normalization code for enumeration-valued
- * attributes, to trim
- * specified attribute value (full normalization not needed -- called
- * for values that CAN NOT have spaces inside; such values can not
- * be legal), and then check whether it is included
- * in set of words (tokens) passed in. If actual value was included,
- * will return the normalized word (as well as store shared String
- * locally); otherwise will return null.
- */
- public String validateEnumValue(char[] cbuf, int start, int end,
- boolean normalize,
- WordResolver res)
- {
- /* Better NOT to build temporary Strings quite yet; can resolve
- * matches via resolver more efficiently.
- */
- // Note: at this point, should only have real spaces...
- if (normalize) {
- while (start < end && cbuf[start] <= CHAR_SPACE) {
- ++start;
- }
- while (--end > start && cbuf[end] <= CHAR_SPACE) {
- ;
- }
- ++end; // so it'll point to the first char (or beyond end of buffer)
- }
-
- // Empty String is never legal for enums:
- if (start >= end) {
- return null;
- }
- return res.find(cbuf, start, end);
- }
-
- protected EntityDecl findEntityDecl(DTDValidatorBase v,
- char[] ch, int start, int len, int hash)
- throws XMLStreamException
- {
- Map entMap = v.getEntityMap();
- /* !!! 13-Nov-2005, TSa: If this was to become a bottle-neck, we
- * could use/share a symbol table. Or at least reuse Strings...
- */
- String id = new String(ch, start, len);
- EntityDecl ent = (EntityDecl) entMap.get(id);
-
- if (ent == null) {
- reportValidationProblem(v, "Referenced entity '"+id+"' not defined");
- } else if (ent.isParsed()) {
- reportValidationProblem(v, "Referenced entity '"+id+"' is not an unparsed entity");
- }
- return ent;
- }
-
- /* Too bad this method can not be combined with previous segment --
- * the reason is that DTDValidator does not implement
- * InputProblemReporter...
- */
-
- protected void checkEntity(InputProblemReporter rep, String id, EntityDecl ent)
- throws XMLStreamException
- {
- if (ent == null) {
- rep.reportValidationProblem("Referenced entity '"+id+"' not defined");
- } else if (ent.isParsed()) {
- rep.reportValidationProblem("Referenced entity '"+id+"' is not an unparsed entity");
- }
- }
-
- /*
- ///////////////////////////////////////////////////
- // Package methods, error reporting
- ///////////////////////////////////////////////////
- */
-
- protected String reportInvalidChar(DTDValidatorBase v, char c, String msg)
- throws XMLStreamException
- {
- reportValidationProblem(v, "Invalid character "+WstxInputData.getCharDesc(c)+": "+msg);
- return null;
- }
-
- protected String reportValidationProblem(DTDValidatorBase v, String msg)
- throws XMLStreamException
- {
- v.reportValidationProblem("Attribute '"+mName+"': "+msg);
- return null;
- }
-
- /**
- * Method called during parsing of DTD schema, to report a problem.
- * Note that unlike during actual validation, we have no option of
- * just gracefully listing problems and ignoring them; an exception
- * is always thrown.
- */
- protected String reportValidationProblem(InputProblemReporter rep, String msg)
- throws XMLStreamException
- {
- rep.reportValidationProblem("Attribute definition '"+mName+"': "+msg);
- return null;
- }
-}
diff -Nru libwoodstox-java-4.1.3/src/java/com/ctc/wstx/dtd/DTDCdataAttr.java libwoodstox-java-5.1.0/src/java/com/ctc/wstx/dtd/DTDCdataAttr.java
--- libwoodstox-java-4.1.3/src/java/com/ctc/wstx/dtd/DTDCdataAttr.java 2012-04-24 04:38:20.000000000 +0000
+++ libwoodstox-java-5.1.0/src/java/com/ctc/wstx/dtd/DTDCdataAttr.java 1970-01-01 00:00:00.000000000 +0000
@@ -1,61 +0,0 @@
-package com.ctc.wstx.dtd;
-
-import org.codehaus.stax2.validation.XMLValidationException;
-
-import com.ctc.wstx.sr.InputProblemReporter;
-import com.ctc.wstx.util.PrefixedName;
-
-/**
- * Simple {@link DTDAttribute} sub-class used for plain vanilla CDATA
- * valued attributes. Although base class implements most of the methods,
- * it's better designwise to keep that base class abstract and have
- * separate CDATA type as well.
- */
-public final class DTDCdataAttr
- extends DTDAttribute
-{
- public DTDCdataAttr(PrefixedName name, DefaultAttrValue defValue, int specIndex,
- boolean nsAware, boolean xml11)
- {
- super(name, defValue, specIndex, nsAware, xml11);
- }
-
- public DTDAttribute cloneWith(int specIndex)
- {
- return new DTDCdataAttr(mName, mDefValue, specIndex, mCfgNsAware, mCfgXml11);
- }
-
- /*
- ///////////////////////////////////////////////////
- // Public API, validation
- ///////////////////////////////////////////////////
- */
-
- // @Override
- public String validate(DTDValidatorBase v, char[] cbuf, int start, int end, boolean normalize)
- throws XMLValidationException
- {
- // Nothing to do for pure CDATA attributes...
- return null;
- }
-
- // @Override
- public void validateDefault(InputProblemReporter rep, boolean normalize)
- throws javax.xml.stream.XMLStreamException
- {
- // Nothing to do for CDATA; all values are fine
- }
-
- // @Override
- public String normalize(DTDValidatorBase v, char[] cbuf, int start, int end)
- {
- // Nothing to do for pure CDATA attributes...
- return null;
- }
-
- // @Override
- public void normalizeDefault()
- {
- // Nothing to do for pure CDATA attributes...
- }
-}
diff -Nru libwoodstox-java-4.1.3/src/java/com/ctc/wstx/dtd/DTDElement.java libwoodstox-java-5.1.0/src/java/com/ctc/wstx/dtd/DTDElement.java
--- libwoodstox-java-4.1.3/src/java/com/ctc/wstx/dtd/DTDElement.java 2012-04-24 04:38:20.000000000 +0000
+++ libwoodstox-java-5.1.0/src/java/com/ctc/wstx/dtd/DTDElement.java 1970-01-01 00:00:00.000000000 +0000
@@ -1,576 +0,0 @@
-/* Woodstox XML processor
- *
- * Copyright (c) 2004- Tatu Saloranta, tatu.saloranta@iki.fi
- *
- * Licensed under the License specified in the file LICENSE which is
- * included with the source code.
- * You may not use this file except in compliance with the License.
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.ctc.wstx.dtd;
-
-import java.util.*;
-
-import javax.xml.stream.Location;
-import javax.xml.stream.XMLStreamException;
-
-import org.codehaus.stax2.validation.XMLValidator;
-
-import com.ctc.wstx.api.ReaderConfig;
-import com.ctc.wstx.cfg.ErrorConsts;
-import com.ctc.wstx.sr.InputProblemReporter;
-import com.ctc.wstx.util.ExceptionUtil;
-import com.ctc.wstx.util.PrefixedName;
-import com.ctc.wstx.util.WordResolver;
-
-/**
- * Class that contains element definitions from DTD.
- *
- * Notes about thread-safety: this class is not thread-safe, since it does
- * not have to be, in general case. That is, the only instances that can
- * be shared are external subset instances, and those are used in read-only
- * manner (with the exception of temporary arrays constructed on-demand).
- */
-public final class DTDElement
-{
-
- /*
- ///////////////////////////////////////////////////
- // Information about the element itself
- ///////////////////////////////////////////////////
- */
-
- final PrefixedName mName;
-
- /**
- * Location of the (real) definition of the element; may be null for
- * placeholder elements created to hold ATTLIST definitions
- */
- final Location mLocation;
-
- /**
- * Base validator object for validating content model of this element;
- * may be null for some simple content models (ANY, EMPTY).
- */
- StructValidator mValidator;
-
- int mAllowedContent;
-
- /**
- * True if the DTD was parsed (and is to be used) in namespace-aware
- * mode.
- * Affects (name) validation amongst other things.
- */
- final boolean mNsAware;
-
- /**
- * True if the DTD was parsed in xml1.1 compliant mode (referenced to
- * from an xml 1.1 document).
- * Affects (name) validation amongst other things.
- */
- final boolean mXml11;
-
- /*
- ///////////////////////////////////////////////////
- // Attribute info
- ///////////////////////////////////////////////////
- */
-
- HashMap mAttrMap = null;
-
- /**
- * Ordered list of attributes that have 'special' properties (attribute
- * is required, has a default value [regular or fixed]); these attributes
- * have to be specifically checked after actual values have been resolved.
- */
- ArrayList mSpecAttrList = null;
-
- boolean mAnyFixed = false;
-
- /**
- * Flag set to true if there are any attributes that have either
- * basic default value, or #FIXED default value.
- */
- boolean mAnyDefaults = false;
-
- /**
- * Flag that is set to true if there is at least one attribute that
- * has type that requires normalization and/or validation; that is,
- * is of some other type than CDATA.
- */
- boolean mValidateAttrs = false;
-
- /**
- * Id attribute instance, if one already declared for this element;
- * can only have up to one such attribute per element.
- */
- DTDAttribute mIdAttr;
-
- /**
- * Notation attribute instance, if one already declared for this element;
- * can only have up to one such attribute per element.
- */
- DTDAttribute mNotationAttr;
-
- // // // !! If you add new attributes, make sure they get copied
- // // // in #define() method !!
-
- /*
- ///////////////////////////////////////////////////
- // Namespace declaration defaulting...
- ///////////////////////////////////////////////////
- */
-
- /**
- * Set of namespace declarations with default values, if any
- * (regular ns pseudo-attr declarations are just ignored)
- */
- HashMap mNsDefaults = null; // [String : DTDAttribute]
-
- /*
- ///////////////////////////////////////////////////
- // Life-cycle
- ///////////////////////////////////////////////////
- */
-
- private DTDElement(Location loc, PrefixedName name,
- StructValidator val, int allowedContent,
- boolean nsAware, boolean xml11)
- {
- mName = name;
- mLocation = loc;
- mValidator = val;
- mAllowedContent = allowedContent;
- mNsAware = nsAware;
- mXml11 = xml11;
- }
-
- /**
- * Method called to create an actual element definition, matching
- * an ELEMENT directive in a DTD subset.
- */
- public static DTDElement createDefined(ReaderConfig cfg, Location loc, PrefixedName name,
- StructValidator val, int allowedContent)
- {
- if (allowedContent == XMLValidator.CONTENT_ALLOW_UNDEFINED) { // sanity check
- ExceptionUtil.throwInternal("trying to use XMLValidator.CONTENT_ALLOW_UNDEFINED via createDefined()");
- }
- return new DTDElement(loc, name, val, allowedContent,
- cfg.willSupportNamespaces(), cfg.isXml11());
- }
-
- /**
- * Method called to create a "placeholder" element definition, needed to
- * contain attribute definitions.
- */
- public static DTDElement createPlaceholder(ReaderConfig cfg, Location loc, PrefixedName name)
- {
- return new DTDElement(loc, name, null, XMLValidator.CONTENT_ALLOW_UNDEFINED,
- cfg.willSupportNamespaces(), cfg.isXml11());
- }
-
- /**
- * Method called on placeholder element, to create a real instance that
- * has all attribute definitions placeholder had (it'll always have at
- * least one -- otherwise no placeholder was needed).
- */
- public DTDElement define(Location loc, StructValidator val,
- int allowedContent)
- {
- verifyUndefined();
- if (allowedContent == XMLValidator.CONTENT_ALLOW_UNDEFINED) { // sanity check
- ExceptionUtil.throwInternal("trying to use CONTENT_ALLOW_UNDEFINED via define()");
- }
-
- DTDElement elem = new DTDElement(loc, mName, val, allowedContent,
- mNsAware, mXml11);
-
- // Ok, need to copy state collected so far:
- elem.mAttrMap = mAttrMap;
- elem.mSpecAttrList = mSpecAttrList;
- elem.mAnyFixed = mAnyFixed;
- elem.mValidateAttrs = mValidateAttrs;
- elem.mAnyDefaults = mAnyDefaults;
- elem.mIdAttr = mIdAttr;
- elem.mNotationAttr = mNotationAttr;
- elem.mNsDefaults = mNsDefaults;
-
- return elem;
- }
-
- /**
- * Method called to "upgrade" a placeholder using a defined element,
- * including adding attributes.
- */
- public void defineFrom(InputProblemReporter rep, DTDElement definedElem,
- boolean fullyValidate)
- throws XMLStreamException
- {
- if (fullyValidate) {
- verifyUndefined();
- }
- mValidator = definedElem.mValidator;
- mAllowedContent = definedElem.mAllowedContent;
- mergeMissingAttributesFrom(rep, definedElem, fullyValidate);
- }
-
- private void verifyUndefined()
- {
- if (mAllowedContent != XMLValidator.CONTENT_ALLOW_UNDEFINED) { // sanity check
- ExceptionUtil.throwInternal("redefining defined element spec");
- }
- }
-
- /**
- * Method called by DTD parser when it has read information about
- * an attribute that belong to this element
- *
- * @return Newly created attribute Object if the attribute definition was
- * added (hadn't been declared yet); null if it's a duplicate, in which
- * case original definition sticks.
- */
- public DTDAttribute addAttribute(InputProblemReporter rep,
- PrefixedName attrName, int valueType,
- DefaultAttrValue defValue, WordResolver enumValues,
- boolean fullyValidate)
- throws XMLStreamException
- {
- HashMap m = mAttrMap;
- if (m == null) {
- mAttrMap = m = new HashMap();
- }
-
- List specList = defValue.isSpecial() ? getSpecialList() : null;
-
- DTDAttribute attr;
- int specIndex = (specList == null) ? -1 : specList.size();
-
- switch (valueType) {
- case DTDAttribute.TYPE_CDATA:
- attr = new DTDCdataAttr(attrName, defValue, specIndex, mNsAware, mXml11);
- break;
-
- case DTDAttribute.TYPE_ENUMERATED:
- attr = new DTDEnumAttr(attrName, defValue, specIndex, mNsAware, mXml11, enumValues);
- break;
-
- case DTDAttribute.TYPE_ID:
- /* note: although ID attributes are not to have default value,
- * this is 'only' a validity constraint, and in dtd-aware-but-
- * not-validating mode it is apparently 'legal' to add default
- * values. Bleech.
- */
- attr = new DTDIdAttr(attrName, defValue, specIndex, mNsAware, mXml11);
- break;
-
- case DTDAttribute.TYPE_IDREF:
- attr = new DTDIdRefAttr(attrName, defValue, specIndex, mNsAware, mXml11);
- break;
-
- case DTDAttribute.TYPE_IDREFS:
- attr = new DTDIdRefsAttr(attrName, defValue, specIndex, mNsAware, mXml11);
- break;
-
- case DTDAttribute.TYPE_ENTITY:
- attr = new DTDEntityAttr(attrName, defValue, specIndex, mNsAware, mXml11);
- break;
-
- case DTDAttribute.TYPE_ENTITIES:
- attr = new DTDEntitiesAttr(attrName, defValue, specIndex, mNsAware, mXml11);
- break;
-
- case DTDAttribute.TYPE_NOTATION:
- attr = new DTDNotationAttr(attrName, defValue, specIndex, mNsAware, mXml11, enumValues);
- break;
-
- case DTDAttribute.TYPE_NMTOKEN:
- attr = new DTDNmTokenAttr(attrName, defValue, specIndex, mNsAware, mXml11);
- break;
-
- case DTDAttribute.TYPE_NMTOKENS:
- attr = new DTDNmTokensAttr(attrName, defValue, specIndex, mNsAware, mXml11);
- break;
-
- default:
- // 18-Jan-2006, TSa: should never get here...
- ExceptionUtil.throwGenericInternal();
- attr = null; // unreachable, but compiler wants it
- }
-
- DTDAttribute old = doAddAttribute(m, rep, attr, specList, fullyValidate);
- return (old == null) ? attr : null;
- }
-
- /**
- * Method called to add a definition of a namespace-declaration
- * pseudo-attribute with a default value.
- *
- * @return Attribute that acts as the placeholder, if the declaration
- * was added; null to indicate it
- * was a dup (there was an earlier declaration)
- */
- public DTDAttribute addNsDefault
- (InputProblemReporter rep, PrefixedName attrName, int valueType,
- DefaultAttrValue defValue, boolean fullyValidate)
- throws XMLStreamException
- {
- /* Let's simplify handling a bit: although theoretically all
- * combinations of value can be used, let's really only differentiate
- * between CDATA and 'other' (for which let's use NMTOKEN)
- */
- DTDAttribute nsAttr;
-
- switch (valueType) {
- case DTDAttribute.TYPE_CDATA:
- nsAttr = new DTDCdataAttr(attrName, defValue, -1, mNsAware, mXml11);
- break;
- default: // something else, default to NMTOKEN then
- nsAttr = new DTDNmTokenAttr(attrName, defValue, -1, mNsAware, mXml11);
- break;
- }
-
- // Ok. So which prefix are we to bind? Need to access by prefix...
- String prefix = attrName.getPrefix();
- if (prefix == null || prefix.length() == 0) { // defult NS -> ""
- prefix = "";
- } else { // non-default, use the local name
- prefix = attrName.getLocalName();
- }
-
- if (mNsDefaults == null) {
- mNsDefaults = new HashMap();
- } else {
- if (mNsDefaults.containsKey(prefix)) {
- return null;
- }
- }
- mNsDefaults.put(prefix, nsAttr);
- return nsAttr;
- }
-
- public void mergeMissingAttributesFrom(InputProblemReporter rep, DTDElement other,
- boolean fullyValidate)
- throws XMLStreamException
- {
- Map otherMap = other.getAttributes();
- HashMap m = mAttrMap;
- if (m == null) {
- mAttrMap = m = new HashMap();
- }
-
- //boolean anyAdded = false;
-
- if (otherMap != null && otherMap.size() > 0) {
- Iterator it = otherMap.entrySet().iterator();
- while (it.hasNext()) {
- Map.Entry me = (Map.Entry) it.next();
- Object key = me.getKey();
- // Should only add if no such attribute exists...
- if (!m.containsKey(key)) {
- // can only use as is, if it's not a special attr
- DTDAttribute newAttr = (DTDAttribute) me.getValue();
- List specList;
- // otherwise need to clone
- if (newAttr.isSpecial()) {
- specList = getSpecialList();
- newAttr = newAttr.cloneWith(specList.size());
- } else {
- specList = null;
- }
- doAddAttribute(m, rep, newAttr, specList, fullyValidate);
- }
- }
- }
-
- HashMap otherNs = other.mNsDefaults;
- if (otherNs != null) {
- if (mNsDefaults == null) {
- mNsDefaults = new HashMap();
- }
- Iterator it = otherNs.entrySet().iterator();
- while (it.hasNext()) {
- Map.Entry me = (Map.Entry) it.next();
- Object key = me.getKey();
- // Should only add if no such attribute exists...
- if (!mNsDefaults.containsKey(key)) {
- mNsDefaults.put(key, me.getValue());
- }
- }
- }
- }
-
- /**
- * @return Earlier declaration of the attribute, if any; null if
- * this was a new attribute
- */
- private DTDAttribute doAddAttribute(Map attrMap, InputProblemReporter rep,
- DTDAttribute attr, List specList,
- boolean fullyValidate)
- throws XMLStreamException
- {
- PrefixedName attrName = attr.getName();
-
- // Maybe we already have it? If so, need to ignore
- DTDAttribute old = (DTDAttribute) attrMap.get(attrName);
- if (old != null) {
- rep.reportProblem(null, ErrorConsts.WT_ATTR_DECL, ErrorConsts.W_DTD_DUP_ATTR,
- attrName, mName);
- return old;
- }
-
- switch (attr.getValueType()) {
- case DTDAttribute.TYPE_ID:
- // Only one such attribute per element (Specs, 1.0#3.3.1)
- if (fullyValidate && mIdAttr != null) {
- rep.throwParseError("Invalid id attribute \"{0}\" for element <{1}>: already had id attribute \""+mIdAttr.getName()+"\"", attrName, mName);
- }
- mIdAttr = attr;
- break;
-
- case DTDAttribute.TYPE_NOTATION:
- // Only one such attribute per element (Specs, 1.0#3.3.1)
- if (fullyValidate && mNotationAttr != null) {
- rep.throwParseError("Invalid notation attribute '"+attrName+"' for element <"+mName+">: already had notation attribute '"+mNotationAttr.getName()+"'");
- }
- mNotationAttr = attr;
- break;
- }
-
- attrMap.put(attrName, attr);
- if (specList != null) {
- specList.add(attr);
- }
- if (!mAnyFixed) {
- mAnyFixed = attr.isFixed();
- }
- if (!mValidateAttrs) {
- mValidateAttrs = attr.needsValidation();
- }
- if (!mAnyDefaults) {
- mAnyDefaults = attr.hasDefaultValue();
- }
-
- return null;
- }
-
- /*
- ///////////////////////////////////////////////////
- // Public API, accessors:
- ///////////////////////////////////////////////////
- */
-
- public PrefixedName getName() { return mName; }
-
- public String toString() {
- return mName.toString();
- }
-
- public String getDisplayName() {
- return mName.toString();
- }
-
- public Location getLocation() { return mLocation; }
-
- public boolean isDefined() {
- return (mAllowedContent != XMLValidator.CONTENT_ALLOW_UNDEFINED);
- }
-
- /**
- * @return Constant that identifies what kind of nodes are in general
- * allowed inside this element.
- */
- public int getAllowedContent() {
- return mAllowedContent;
- }
-
- /**
- * Specialized accessor used by non-validating but typing 'validator':
- * essentially, used to figure out whether #PCDATA is allowed or not;
- * and based on that, return one of 2 allowable text values (only
- * space, or anything). This is the relevant subset in non-validating
- * modes, needed to properly type resulting character events.
- */
- public int getAllowedContentIfSpace()
- {
- int vld = mAllowedContent;
- return (vld <= XMLValidator.CONTENT_ALLOW_WS) ?
- XMLValidator.CONTENT_ALLOW_WS_NONSTRICT :
- XMLValidator.CONTENT_ALLOW_ANY_TEXT;
- }
-
- public HashMap getAttributes() {
- return mAttrMap;
- }
-
- public int getSpecialCount() {
- return (mSpecAttrList == null) ? 0 : mSpecAttrList.size();
- }
-
- public List getSpecialAttrs() {
- return mSpecAttrList;
- }
-
- /**
- * @return True if at least one of the attributes has type other than
- * CDATA; false if not
- */
- public boolean attrsNeedValidation() {
- return mValidateAttrs;
- }
-
- public boolean hasFixedAttrs() {
- return mAnyFixed;
- }
-
- public boolean hasAttrDefaultValues() {
- return mAnyDefaults;
- }
-
- public DTDAttribute getIdAttribute() {
- return mIdAttr;
- }
-
- public DTDAttribute getNotationAttribute() {
- return mNotationAttr;
- }
-
- public boolean hasNsDefaults() {
- return (mNsDefaults != null);
- }
-
- /*
- ///////////////////////////////////////////////////
- // Public API, factory methods:
- ///////////////////////////////////////////////////
- */
-
- public StructValidator getValidator()
- {
- return (mValidator == null) ? null : mValidator.newInstance();
- }
-
- protected HashMap getNsDefaults() {
- return mNsDefaults;
- }
-
- /*
- ///////////////////////////////////////////////////
- // Internal methods
- ///////////////////////////////////////////////////
- */
-
- private List getSpecialList()
- {
- ArrayList l = mSpecAttrList;
- if (l == null) {
- mSpecAttrList = l = new ArrayList();
- }
- return l;
- }
-}
diff -Nru libwoodstox-java-4.1.3/src/java/com/ctc/wstx/dtd/DTDEntitiesAttr.java libwoodstox-java-5.1.0/src/java/com/ctc/wstx/dtd/DTDEntitiesAttr.java
--- libwoodstox-java-4.1.3/src/java/com/ctc/wstx/dtd/DTDEntitiesAttr.java 2012-04-24 04:38:20.000000000 +0000
+++ libwoodstox-java-5.1.0/src/java/com/ctc/wstx/dtd/DTDEntitiesAttr.java 1970-01-01 00:00:00.000000000 +0000
@@ -1,177 +0,0 @@
-package com.ctc.wstx.dtd;
-
-import java.util.StringTokenizer;
-
-import javax.xml.stream.XMLStreamException;
-
-import com.ctc.wstx.ent.EntityDecl;
-import com.ctc.wstx.io.WstxInputData;
-import com.ctc.wstx.sr.InputProblemReporter;
-import com.ctc.wstx.util.PrefixedName;
-
-/**
- * Specific attribute class for attributes that contain (unique)
- * identifiers.
- */
-public final class DTDEntitiesAttr
- extends DTDAttribute
-{
- /*
- ///////////////////////////////////////////////////
- // Life-cycle
- ///////////////////////////////////////////////////
- */
-
- /**
- * Main constructor. Note that id attributes can never have
- * default values.
- */
- public DTDEntitiesAttr(PrefixedName name, DefaultAttrValue defValue, int specIndex,
- boolean nsAware, boolean xml11)
-
- {
- super(name, defValue, specIndex, nsAware, xml11);
- }
-
- public DTDAttribute cloneWith(int specIndex)
- {
- return new DTDEntitiesAttr(mName, mDefValue, specIndex, mCfgNsAware, mCfgXml11);
- }
-
- /*
- ///////////////////////////////////////////////////
- // Public API
- ///////////////////////////////////////////////////
- */
-
- public int getValueType() {
- return TYPE_ENTITIES;
- }
-
- /*
- ///////////////////////////////////////////////////
- // Public API, validation
- ///////////////////////////////////////////////////
- */
-
- /**
- * Method called by the {@link DTDValidatorBase}
- * to let the attribute do necessary normalization and/or validation
- * for the value.
- *
- */
- public String validate(DTDValidatorBase v, char[] cbuf, int start, int end, boolean normalize)
- throws XMLStreamException
- {
- /* Let's skip leading/trailing white space, even if we are not
- * to normalize visible attribute value. This allows for better
- * round-trip handling (no changes for physical value caller
- * gets), but still allows succesful validation.
- */
- while (start < end && WstxInputData.isSpaceChar(cbuf[start])) {
- ++start;
- }
-
- // Empty value?
- if (start >= end) {
- return reportValidationProblem(v, "Empty ENTITIES value");
- }
- --end; // so that it now points to the last char
- while (end > start && WstxInputData.isSpaceChar(cbuf[end])) {
- --end;
- }
-
- // Ok; now start points to first, last to last char (both inclusive)
- String idStr = null;
- StringBuffer sb = null;
-
- while (start <= end) {
- // Ok, need to check char validity, and also calc hash code:
- char c = cbuf[start];
- if (!WstxInputData.isNameStartChar(c, mCfgNsAware, mCfgXml11)) {
- return reportInvalidChar(v, c, "not valid as the first ENTITIES character");
- }
- int hash = (int) c;
- int i = start+1;
- for (; i <= end; ++i) {
- c = cbuf[i];
- if (WstxInputData.isSpaceChar(c)) {
- break;
- }
- if (!WstxInputData.isNameChar(c, mCfgNsAware, mCfgXml11)) {
- return reportInvalidChar(v, c, "not valid as an ENTITIES character");
- }
- hash = (hash * 31) + (int) c;
- }
-
- EntityDecl ent = findEntityDecl(v, cbuf, start, (i - start), hash);
- // only returns if entity was found...
-
- // Can skip the trailing space char (if there was one)
- start = i+1;
-
- /* When normalizing, we can possibly share id String, or
- * alternatively, compose normalized String if multiple
- */
- if (normalize) {
- if (idStr == null) { // first idref
- idStr = ent.getName();
- } else {
- if (sb == null) {
- sb = new StringBuffer(idStr);
- }
- idStr = ent.getName();
- sb.append(' ');
- sb.append(idStr);
- }
- }
-
- // Ok, any white space to skip?
- while (start <= end && WstxInputData.isSpaceChar(cbuf[start])) {
- ++start;
- }
- }
-
- if (normalize) {
- if (sb != null) {
- idStr = sb.toString();
- }
- return idStr;
- }
-
- return null;
- }
-
- /**
- * Method called by the validator object
- * to ask attribute to verify that the default it has (if any) is
- * valid for such type.
- */
- public void validateDefault(InputProblemReporter rep, boolean normalize)
- throws XMLStreamException
- {
- String normStr = validateDefaultNames(rep, true);
- if (normalize) {
- mDefValue.setValue(normStr);
- }
-
- // Ok, but were they declared?
-
- /* Performance really shouldn't be critical here (only called when
- * parsing DTDs, which get cached) -- let's just
- * tokenize using standard StringTokenizer
- */
- StringTokenizer st = new StringTokenizer(normStr);
- /* !!! 03-Dec-2004, TSa: This is rather ugly -- need to know we
- * actually really get a DTD reader, and DTD reader needs
- * to expose a special method... but it gets things done.
- */
- MinimalDTDReader dtdr = (MinimalDTDReader) rep;
- while (st.hasMoreTokens()) {
- String str = st.nextToken();
- EntityDecl ent = dtdr.findEntity(str);
- // Needs to exists, and be an unparsed entity...
- checkEntity(rep, normStr, ent);
- }
- }
-}
diff -Nru libwoodstox-java-4.1.3/src/java/com/ctc/wstx/dtd/DTDEntityAttr.java libwoodstox-java-5.1.0/src/java/com/ctc/wstx/dtd/DTDEntityAttr.java
--- libwoodstox-java-4.1.3/src/java/com/ctc/wstx/dtd/DTDEntityAttr.java 2012-04-24 04:38:20.000000000 +0000
+++ libwoodstox-java-5.1.0/src/java/com/ctc/wstx/dtd/DTDEntityAttr.java 1970-01-01 00:00:00.000000000 +0000
@@ -1,118 +0,0 @@
-package com.ctc.wstx.dtd;
-
-import javax.xml.stream.XMLStreamException;
-
-import com.ctc.wstx.ent.EntityDecl;
-import com.ctc.wstx.io.WstxInputData;
-import com.ctc.wstx.sr.InputProblemReporter;
-import com.ctc.wstx.util.PrefixedName;
-
-/**
- * Specific attribute class for attributes that contain (unique)
- * identifiers.
- */
-public final class DTDEntityAttr
- extends DTDAttribute
-{
- /*
- ///////////////////////////////////////////////////
- // Life-cycle
- ///////////////////////////////////////////////////
- */
-
- /**
- * Main constructor. Note that id attributes can never have
- * default values.
- */
- public DTDEntityAttr(PrefixedName name, DefaultAttrValue defValue, int specIndex,
- boolean nsAware, boolean xml11)
- {
- super(name, defValue, specIndex, nsAware, xml11);
- }
-
- public DTDAttribute cloneWith(int specIndex)
- {
- return new DTDEntityAttr(mName, mDefValue, specIndex, mCfgNsAware, mCfgXml11);
- }
-
- /*
- ///////////////////////////////////////////////////
- // Public API
- ///////////////////////////////////////////////////
- */
-
- public int getValueType() {
- return TYPE_ENTITY;
- }
-
- /*
- ///////////////////////////////////////////////////
- // Public API, validation
- ///////////////////////////////////////////////////
- */
-
- /**
- * Method called by the {@link DTDValidatorBase}
- * to let the attribute do necessary normalization and/or validation
- * for the value.
- */
- public String validate(DTDValidatorBase v, char[] cbuf, int start, int end, boolean normalize)
- throws XMLStreamException
- {
- while (start < end && WstxInputData.isSpaceChar(cbuf[start])) {
- ++start;
- }
-
- // Empty value?
- if (start >= end) {
- return reportValidationProblem(v, "Empty ENTITY value");
- }
- --end; // so that it now points to the last char
- while (end > start && WstxInputData.isSpaceChar(cbuf[end])) {
- --end;
- }
-
- // Ok, need to check char validity, and also calc hash code:
- char c = cbuf[start];
- if (!WstxInputData.isNameStartChar(c, mCfgNsAware, mCfgXml11) && c != ':') {
- return reportInvalidChar(v, c, "not valid as the first ID character");
- }
- int hash = (int) c;
-
- for (int i = start+1; i <= end; ++i) {
- c = cbuf[i];
- if (!WstxInputData.isNameChar(c, mCfgNsAware, mCfgXml11)) {
- return reportInvalidChar(v, c, "not valid as an ID character");
- }
- hash = (hash * 31) + (int) c;
- }
-
- EntityDecl ent = findEntityDecl(v, cbuf, start, (end - start + 1), hash);
- // only returns if it succeeded...
-
- return normalize ? ent.getName() : null;
- }
-
- /**
- * Method called by the validator object
- * to ask attribute to verify that the default it has (if any) is
- * valid for such type.
- */
- public void validateDefault(InputProblemReporter rep, boolean normalize)
- throws XMLStreamException
- {
- String normStr = validateDefaultName(rep, normalize);
- if (normalize) {
- mDefValue.setValue(normStr);
- }
-
- // Ok, but was it declared?
-
- /* 03-Dec-2004, TSa: This is rather ugly -- need to know we
- * actually really get a DTD reader, and DTD reader needs
- * to expose a special method... but it gets things done.
- */
- EntityDecl ent = ((MinimalDTDReader) rep).findEntity(normStr);
- checkEntity(rep, normStr, ent);
- }
-}
diff -Nru libwoodstox-java-4.1.3/src/java/com/ctc/wstx/dtd/DTDEnumAttr.java libwoodstox-java-5.1.0/src/java/com/ctc/wstx/dtd/DTDEnumAttr.java
--- libwoodstox-java-4.1.3/src/java/com/ctc/wstx/dtd/DTDEnumAttr.java 2012-04-24 04:38:20.000000000 +0000
+++ libwoodstox-java-5.1.0/src/java/com/ctc/wstx/dtd/DTDEnumAttr.java 1970-01-01 00:00:00.000000000 +0000
@@ -1,93 +0,0 @@
-package com.ctc.wstx.dtd;
-
-import javax.xml.stream.XMLStreamException;
-
-import com.ctc.wstx.sr.InputProblemReporter;
-import com.ctc.wstx.util.PrefixedName;
-import com.ctc.wstx.util.WordResolver;
-
-/**
- * Specific attribute class for attributes that have enumerated values.
- */
-public final class DTDEnumAttr
- extends DTDAttribute
-{
- final WordResolver mEnumValues;
-
- /*
- ///////////////////////////////////////////////////
- // Life-cycle
- ///////////////////////////////////////////////////
- */
-
- public DTDEnumAttr(PrefixedName name, DefaultAttrValue defValue,
- int specIndex, boolean nsAware, boolean xml11,
- WordResolver enumValues)
- {
- super(name, defValue, specIndex, nsAware, xml11);
- mEnumValues = enumValues;
- }
-
- public DTDAttribute cloneWith(int specIndex)
- {
- return new DTDEnumAttr(mName, mDefValue, specIndex, mCfgNsAware,
- mCfgXml11, mEnumValues);
- }
-
- /*
- ///////////////////////////////////////////////////
- // Public API
- ///////////////////////////////////////////////////
- */
-
- public int getValueType() {
- return TYPE_ENUMERATED;
- }
-
- /*
- ///////////////////////////////////////////////////
- // Public API, validation
- ///////////////////////////////////////////////////
- */
-
- /**
- * Method called by the validator
- * to let the attribute do necessary normalization and/or validation
- * for the value.
- */
- public String validate(DTDValidatorBase v, char[] cbuf, int start, int end, boolean normalize)
- throws XMLStreamException
- {
- String ok = validateEnumValue(cbuf, start, end, normalize, mEnumValues);
- if (ok == null) {
- String val = new String(cbuf, start, (end-start));
- return reportValidationProblem(v, "Invalid enumerated value '"+val+"': has to be one of ("
- +mEnumValues+")");
- }
- return ok;
- }
-
- /**
- * Method called by the validator
- * to ask attribute to verify that the default it has (if any) is
- * valid for such type.
- */
- public void validateDefault(InputProblemReporter rep, boolean normalize)
- throws XMLStreamException
- {
- String def = validateDefaultNmToken(rep, normalize);
-
- // And then that it's one of listed values:
- String shared = mEnumValues.find(def);
- if (shared == null) {
- reportValidationProblem(rep, "Invalid default value '"+def+"': has to be one of ("
- +mEnumValues+")");
- return;
- }
-
- // Ok, cool it's ok...
- if (normalize) {
- mDefValue.setValue(shared);
- }
- }
-}
diff -Nru libwoodstox-java-4.1.3/src/java/com/ctc/wstx/dtd/DTDEventListener.java libwoodstox-java-5.1.0/src/java/com/ctc/wstx/dtd/DTDEventListener.java
--- libwoodstox-java-4.1.3/src/java/com/ctc/wstx/dtd/DTDEventListener.java 2012-04-24 04:38:20.000000000 +0000
+++ libwoodstox-java-5.1.0/src/java/com/ctc/wstx/dtd/DTDEventListener.java 1970-01-01 00:00:00.000000000 +0000
@@ -1,51 +0,0 @@
-/* Woodstox XML processor
- *
- * Copyright (c) 2004- 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 com.ctc.wstx.dtd;
-
-import java.net.URL;
-
-import javax.xml.stream.XMLStreamException;
-
-public interface DTDEventListener
-{
- // Configuration
-
- /**
- * @return True, if there is a listener interested in getting comment
- * events within DTD subset (since that's optional)
- */
- public boolean dtdReportComments();
-
- // Basic content events
-
- public void dtdProcessingInstruction(String target, String data);
- public void dtdComment(char[] data, int offset, int len);
- public void dtdSkippedEntity(String name);
-
- // DTD declarations that must be exposed
- public void dtdNotationDecl(String name, String publicId, String systemId, URL baseURL)
- throws XMLStreamException;
-
- public void dtdUnparsedEntityDecl(String name, String publicId, String systemId, String notationName, URL baseURL)
- throws XMLStreamException;
-
- // DTD declarations that can be exposed
-
- public void attributeDecl(String eName, String aName, String type, String mode, String value);
- public void dtdElementDecl(String name, String model);
- public void dtdExternalEntityDecl(String name, String publicId, String systemId);
- public void dtdInternalEntityDecl(String name, String value);
-}
diff -Nru libwoodstox-java-4.1.3/src/java/com/ctc/wstx/dtd/DTDIdAttr.java libwoodstox-java-5.1.0/src/java/com/ctc/wstx/dtd/DTDIdAttr.java
--- libwoodstox-java-4.1.3/src/java/com/ctc/wstx/dtd/DTDIdAttr.java 2012-04-24 04:38:20.000000000 +0000
+++ libwoodstox-java-5.1.0/src/java/com/ctc/wstx/dtd/DTDIdAttr.java 1970-01-01 00:00:00.000000000 +0000
@@ -1,131 +0,0 @@
-package com.ctc.wstx.dtd;
-
-import javax.xml.stream.Location;
-import javax.xml.stream.XMLStreamException;
-
-import com.ctc.wstx.cfg.ErrorConsts;
-import com.ctc.wstx.io.WstxInputData;
-import com.ctc.wstx.sr.InputProblemReporter;
-import com.ctc.wstx.util.ElementId;
-import com.ctc.wstx.util.ElementIdMap;
-import com.ctc.wstx.util.PrefixedName;
-
-/**
- * Specific attribute class for attributes that contain (unique)
- * identifiers.
- */
-public final class DTDIdAttr
- extends DTDAttribute
-{
- /*
- ///////////////////////////////////////////////////
- // Life-cycle
- ///////////////////////////////////////////////////
- */
-
- /**
- * Main constructor. Note that id attributes can never have
- * default values.
- *
- * note: although ID attributes are not to have default value,
- * this is 'only' a validity constraint, and in dtd-aware-but-
- * not-validating mode it is apparently 'legal' to add default
- * values.
- */
- public DTDIdAttr(PrefixedName name, DefaultAttrValue defValue, int specIndex,
- boolean nsAware, boolean xml11)
- {
- super(name, defValue, specIndex, nsAware, xml11);
- }
-
- public DTDAttribute cloneWith(int specIndex)
- {
- return new DTDIdAttr(mName, mDefValue, specIndex, mCfgNsAware, mCfgXml11);
- }
-
- /*
- ///////////////////////////////////////////////////
- // Public API
- ///////////////////////////////////////////////////
- */
-
- public int getValueType() {
- return TYPE_ID;
- }
-
- public boolean typeIsId() {
- return true;
- }
-
- /*
- ///////////////////////////////////////////////////
- // Public API, validation
- ///////////////////////////////////////////////////
- */
-
- /**
- * Method called by the validator
- * to let the attribute do necessary normalization and/or validation
- * for the value.
- */
- public String validate(DTDValidatorBase v, char[] cbuf, int start, int end, boolean normalize)
- throws XMLStreamException
- {
- // Let's trim leading white space first...
- while (start < end && WstxInputData.isSpaceChar(cbuf[start])) {
- ++start;
- }
-
- // No id?
- if (start >= end) {
- return reportValidationProblem(v, "Empty ID value");
- }
- --end; // so that it now points to the last char
- while (end > start && WstxInputData.isSpaceChar(cbuf[end])) {
- --end;
- }
-
- // Ok, need to check char validity, and also calc hash code:
- char c = cbuf[start];
- if (!WstxInputData.isNameStartChar(c, mCfgNsAware, mCfgXml11)) {
- return reportInvalidChar(v, c, "not valid as the first ID character");
- }
- int hash = (int) c;
- for (int i = start+1; i <= end; ++i) {
- c = cbuf[i];
- if (!WstxInputData.isNameChar(c, mCfgNsAware, mCfgXml11)) {
- return reportInvalidChar(v, c, "not valid as an ID character");
- }
- hash = (hash * 31) + (int) c;
- }
-
- // Either way, we do need to validate characters, and calculate hash
- ElementIdMap m = v.getIdMap();
- PrefixedName elemName = v.getElemName();
- Location loc = v.getLocation();
- ElementId id = m.addDefined(cbuf, start, (end - start + 1), hash,
- loc, elemName, mName);
-
- // We can detect dups by checking if Location is the one we passed:
- if (id.getLocation() != loc) {
- return reportValidationProblem(v, "Duplicate id '"+id.getId()+"', first declared at "
- +id.getLocation());
- }
-
- if (normalize) {
- return id.getId();
- }
- return null;
- }
-
- /**
- * Method called by the validator
- * to ask attribute to verify that the default it has (if any) is
- * valid for such type.
- */
- public void validateDefault(InputProblemReporter rep, boolean normalize)
- {
- // Should never get called
- throw new IllegalStateException(ErrorConsts.ERR_INTERNAL);
- }
-}
diff -Nru libwoodstox-java-4.1.3/src/java/com/ctc/wstx/dtd/DTDId.java libwoodstox-java-5.1.0/src/java/com/ctc/wstx/dtd/DTDId.java
--- libwoodstox-java-4.1.3/src/java/com/ctc/wstx/dtd/DTDId.java 2012-04-24 04:38:20.000000000 +0000
+++ libwoodstox-java-5.1.0/src/java/com/ctc/wstx/dtd/DTDId.java 1970-01-01 00:00:00.000000000 +0000
@@ -1,139 +0,0 @@
-/* Woodstox XML processor
- *
- * Copyright (c) 2004- Tatu Saloranta, tatu.saloranta@iki.fi
- *
- * Licensed under the License specified in the file LICENSE which is
- * included with the source code.
- * You may not use this file except in compliance with the License.
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.ctc.wstx.dtd;
-
-import java.net.URI;
-
-/**
- * Simple key object class, used for accessing (external) DTDs when stored for
- * caching. Main idea is that the primary id of a DTD (public or system id;
- * latter normalized if possible)
- * has to match, as well as couple of on/off settings for parsing (namespace
- * support, text normalization).
- * Latter restriction is needed since although DTDs do not deal
- * with (or understand) namespaces, some parsing is done to be able to validate
- * namespace aware/non-aware documents, and handling differs between the two.
- * As to primary key part, public id is used if one was defined; if so,
- * comparison is String equality. If not, then system id is compared: system
- * id has to be expressed as URL if so.
- */
-public final class DTDId
-{
- protected final String mPublicId;
-
- protected final URI mSystemId;
-
- protected final int mConfigFlags;
-
- protected final boolean mXml11;
-
- protected int mHashCode = 0;
-
- /*
- ///////////////////////////////////////////////////////////////////////
- // Life-cycle:
- ///////////////////////////////////////////////////////////////////////
- */
-
- private DTDId(String publicId, URI systemId, int configFlags, boolean xml11)
- {
- mPublicId = publicId;
- mSystemId = systemId;
- mConfigFlags = configFlags;
- mXml11 = xml11;
- }
-
- public static DTDId constructFromPublicId(String publicId, int configFlags,
- boolean xml11)
- {
- if (publicId == null || publicId.length() == 0) {
- throw new IllegalArgumentException("Empty/null public id.");
- }
- return new DTDId(publicId, null, configFlags, xml11);
- }
-
- public static DTDId constructFromSystemId(URI systemId, int configFlags,
- boolean xml11)
- {
- if (systemId == null) {
- throw new IllegalArgumentException("Null system id.");
- }
- return new DTDId(null, systemId, configFlags, xml11);
- }
-
- public static DTDId construct(String publicId, URI systemId, int configFlags, boolean xml11)
- {
- if (publicId != null && publicId.length() > 0) {
- return new DTDId(publicId, null, configFlags, xml11);
- }
- if (systemId == null) {
- throw new IllegalArgumentException("Illegal arguments; both public and system id null/empty.");
- }
- return new DTDId(null, systemId, configFlags, xml11);
- }
-
- /*
- ///////////////////////////////////////////////////////////////////////
- // Overridden standard methods
- ///////////////////////////////////////////////////////////////////////
- */
-
- public int hashCode() {
- int hash = mHashCode;
- if (hash == 0) {
- hash = mConfigFlags;
- if (mPublicId != null) {
- hash ^= mPublicId.hashCode();
- } else {
- hash ^= mSystemId.hashCode();
- }
- if (mXml11) {
- hash ^= 1;
- }
- mHashCode = hash;
- }
- return hash;
- }
-
- public String toString() {
- StringBuffer sb = new StringBuffer(60);
- sb.append("Public-id: ");
- sb.append(mPublicId);
- sb.append(", system-id: ");
- sb.append(mSystemId);
- sb.append(" [config flags: 0x");
- sb.append(Integer.toHexString(mConfigFlags));
- sb.append("], xml11: ");
- sb.append(mXml11);
- return sb.toString();
- }
-
- public boolean equals(Object o)
- {
- if (o == this) return true;
- if (o == null || o.getClass() != getClass()) return false;
- DTDId other = (DTDId) o;
- if (other.mConfigFlags != mConfigFlags
- || other.mXml11 != mXml11) {
- return false;
- }
- if (mPublicId != null) {
- String op = other.mPublicId;
- return (op != null) && op.equals(mPublicId);
- }
- return mSystemId.equals(other.mSystemId);
- }
-}
diff -Nru libwoodstox-java-4.1.3/src/java/com/ctc/wstx/dtd/DTDIdRefAttr.java libwoodstox-java-5.1.0/src/java/com/ctc/wstx/dtd/DTDIdRefAttr.java
--- libwoodstox-java-4.1.3/src/java/com/ctc/wstx/dtd/DTDIdRefAttr.java 2012-04-24 04:38:20.000000000 +0000
+++ libwoodstox-java-5.1.0/src/java/com/ctc/wstx/dtd/DTDIdRefAttr.java 1970-01-01 00:00:00.000000000 +0000
@@ -1,116 +0,0 @@
-package com.ctc.wstx.dtd;
-
-import javax.xml.stream.Location;
-import javax.xml.stream.XMLStreamException;
-
-import com.ctc.wstx.io.WstxInputData;
-import com.ctc.wstx.sr.InputProblemReporter;
-import com.ctc.wstx.util.ElementId;
-import com.ctc.wstx.util.ElementIdMap;
-import com.ctc.wstx.util.PrefixedName;
-
-/**
- * Attribute class for attributes that contain references
- * to elements that have matching identifier specified.
- */
-public final class DTDIdRefAttr
- extends DTDAttribute
-{
- /*
- ///////////////////////////////////////////////////
- // Life-cycle
- ///////////////////////////////////////////////////
- */
-
- /**
- * Main constructor.
- */
- public DTDIdRefAttr(PrefixedName name, DefaultAttrValue defValue, int specIndex,
- boolean nsAware, boolean xml11)
- {
- super(name, defValue, specIndex, nsAware, xml11);
- }
-
- public DTDAttribute cloneWith(int specIndex)
- {
- return new DTDIdRefAttr(mName, mDefValue, specIndex, mCfgNsAware, mCfgXml11);
- }
-
- /*
- ///////////////////////////////////////////////////
- // Public API
- ///////////////////////////////////////////////////
- */
-
- public int getValueType() {
- return TYPE_IDREF;
- }
-
- /*
- ///////////////////////////////////////////////////
- // Public API, validation
- ///////////////////////////////////////////////////
- */
-
- /**
- * Method called by the validator
- * to let the attribute do necessary normalization and/or validation
- * for the value.
- */
- public String validate(DTDValidatorBase v, char[] cbuf, int start, int end, boolean normalize)
- throws XMLStreamException
- {
- /* Let's skip leading/trailing white space, even if we are not
- * to normalize visible attribute value. This allows for better
- * round-trip handling, but still allow validation.
- */
- while (start < end && WstxInputData.isSpaceChar(cbuf[start])) {
- ++start;
- }
-
- if (start >= end) { // empty (all white space) value?
- return reportValidationProblem(v, "Empty IDREF value");
- }
-
- --end; // so that it now points to the last char
- while (end > start && WstxInputData.isSpaceChar(cbuf[end])) {
- --end;
- }
-
- // Ok, need to check char validity, and also calc hash code:
- char c = cbuf[start];
- if (!WstxInputData.isNameStartChar(c, mCfgNsAware, mCfgXml11)) {
- return reportInvalidChar(v, c, "not valid as the first IDREF character");
- }
- int hash = (int) c;
- for (int i = start+1; i <= end; ++i) {
- c = cbuf[i];
- if (!WstxInputData.isNameChar(c, mCfgNsAware, mCfgXml11)) {
- return reportInvalidChar(v, c, "not valid as an IDREF character");
- }
- hash = (hash * 31) + (int) c;
- }
-
- // Ok, let's check and update id ref list...
- ElementIdMap m = v.getIdMap();
- Location loc = v.getLocation();
- ElementId id = m.addReferenced(cbuf, start, (end - start + 1), hash,
- loc, v.getElemName(), mName);
- // and that's all; no more checks needed here
- return normalize ? id.getId() : null;
- }
-
- /**
- * Method called by the validator
- * to ask attribute to verify that the default it has (if any) is
- * valid for such type.
- */
- public void validateDefault(InputProblemReporter rep, boolean normalize)
- throws XMLStreamException
- {
- String def = validateDefaultName(rep, normalize);
- if (normalize) {
- mDefValue.setValue(def);
- }
- }
-}
diff -Nru libwoodstox-java-4.1.3/src/java/com/ctc/wstx/dtd/DTDIdRefsAttr.java libwoodstox-java-5.1.0/src/java/com/ctc/wstx/dtd/DTDIdRefsAttr.java
--- libwoodstox-java-4.1.3/src/java/com/ctc/wstx/dtd/DTDIdRefsAttr.java 2012-04-24 04:38:20.000000000 +0000
+++ libwoodstox-java-5.1.0/src/java/com/ctc/wstx/dtd/DTDIdRefsAttr.java 1970-01-01 00:00:00.000000000 +0000
@@ -1,158 +0,0 @@
-package com.ctc.wstx.dtd;
-
-import javax.xml.stream.Location;
-import javax.xml.stream.XMLStreamException;
-
-import com.ctc.wstx.io.WstxInputData;
-import com.ctc.wstx.sr.InputProblemReporter;
-import com.ctc.wstx.util.ElementId;
-import com.ctc.wstx.util.ElementIdMap;
-import com.ctc.wstx.util.PrefixedName;
-
-/**
- * Attribute class for attributes that contain multiple references
- * to elements that have matching identifier specified.
- */
-public final class DTDIdRefsAttr
- extends DTDAttribute
-{
- /*
- ///////////////////////////////////////////////////
- // Life-cycle
- ///////////////////////////////////////////////////
- */
-
- /**
- * Main constructor.
- */
- public DTDIdRefsAttr(PrefixedName name, DefaultAttrValue defValue, int specIndex,
- boolean nsAware, boolean xml11)
- {
- super(name, defValue, specIndex, nsAware, xml11);
- }
-
- public DTDAttribute cloneWith(int specIndex)
- {
- return new DTDIdRefsAttr(mName, mDefValue, specIndex, mCfgNsAware, mCfgXml11);
- }
-
- /*
- ///////////////////////////////////////////////////
- // Public API
- ///////////////////////////////////////////////////
- */
-
- public int getValueType() {
- return TYPE_IDREFS;
- }
-
- /*
- ///////////////////////////////////////////////////
- // Public API, validation
- ///////////////////////////////////////////////////
- */
-
- public String validate(DTDValidatorBase v, char[] cbuf, int start, int end, boolean normalize)
- throws XMLStreamException
- {
- /* Let's skip leading/trailing white space, even if we are not
- * to normalize visible attribute value. This allows for better
- * round-trip handling (no changes for physical value caller
- * gets), but still allows succesful validation.
- */
- while (start < end && WstxInputData.isSpaceChar(cbuf[start])) {
- ++start;
- }
-
- // No id?
- if (start >= end) {
- return reportValidationProblem(v, "Empty IDREFS value");
- }
-
- --end; // so that it now points to the last char
- // We now the first char is not a space by now...
- while (end > start && WstxInputData.isSpaceChar(cbuf[end])) {
- --end;
- }
-
- // Ok; now start points to first, end to last char (both inclusive)
- ElementIdMap m = v.getIdMap();
- Location loc = v.getLocation();
-
- String idStr = null;
- StringBuffer sb = null;
- while (start <= end) {
- // Ok, need to check char validity, and also calc hash code:
- char c = cbuf[start];
- if (!WstxInputData.isNameStartChar(c, mCfgNsAware, mCfgXml11)) {
- return reportInvalidChar(v, c, "not valid as the first IDREFS character");
- }
- int hash = (int) c;
- int i = start+1;
- for (; i <= end; ++i) {
- c = cbuf[i];
- if (WstxInputData.isSpaceChar(c)) {
- break;
- }
- if (!WstxInputData.isNameChar(c, mCfgNsAware, mCfgXml11)) {
- return reportInvalidChar(v, c, "not valid as an IDREFS character");
- }
- hash = (hash * 31) + (int) c;
- }
-
- // Ok, got the next id ref...
- ElementId id = m.addReferenced(cbuf, start, i - start, hash,
- loc, v.getElemName(), mName);
-
- // Can skip the trailing space char (if there was one)
- start = i+1;
-
- /* When normalizing, we can possibly share id String, or
- * alternatively, compose normalized String if multiple
- */
- if (normalize) {
- if (idStr == null) { // first idref
- idStr = id.getId();
- } else {
- if (sb == null) {
- sb = new StringBuffer(idStr);
- }
- idStr = id.getId();
- sb.append(' ');
- sb.append(idStr);
- }
- }
-
- // Ok, any white space to skip?
- while (start <= end && WstxInputData.isSpaceChar(cbuf[start])) {
- ++start;
- }
- }
-
- if (normalize) {
- if (sb != null) {
- idStr = sb.toString();
- }
- return idStr;
- }
-
- return null;
- }
-
- /**
- * Method called by the validator
- * to ask attribute to verify that the default it has (if any) is
- * valid for such type.
- *
- * It's unlikely there will be default values... but just in case,
- * let's implement it properly.
- */
- public void validateDefault(InputProblemReporter rep, boolean normalize)
- throws XMLStreamException
- {
- String def = validateDefaultNames(rep, normalize);
- if (normalize) {
- mDefValue.setValue(def);
- }
- }
-}
diff -Nru libwoodstox-java-4.1.3/src/java/com/ctc/wstx/dtd/DTDNmTokenAttr.java libwoodstox-java-5.1.0/src/java/com/ctc/wstx/dtd/DTDNmTokenAttr.java
--- libwoodstox-java-4.1.3/src/java/com/ctc/wstx/dtd/DTDNmTokenAttr.java 2012-04-24 04:38:20.000000000 +0000
+++ libwoodstox-java-5.1.0/src/java/com/ctc/wstx/dtd/DTDNmTokenAttr.java 1970-01-01 00:00:00.000000000 +0000
@@ -1,108 +0,0 @@
-package com.ctc.wstx.dtd;
-
-import javax.xml.stream.XMLStreamException;
-
-import com.ctc.wstx.io.WstxInputData;
-import com.ctc.wstx.sr.InputProblemReporter;
-import com.ctc.wstx.util.PrefixedName;
-
-/**
- * Specific attribute class for attributes that contain (unique)
- * identifiers.
- */
-public final class DTDNmTokenAttr
- extends DTDAttribute
-{
- /*
- ///////////////////////////////////////////////////
- // Life-cycle
- ///////////////////////////////////////////////////
- */
-
- /**
- * Main constructor.
- */
- public DTDNmTokenAttr(PrefixedName name, DefaultAttrValue defValue, int specIndex,
- boolean nsAware, boolean xml11)
- {
- super(name, defValue, specIndex, nsAware, xml11);
- }
-
- public DTDAttribute cloneWith(int specIndex)
- {
- return new DTDNmTokenAttr(mName, mDefValue, specIndex, mCfgNsAware, mCfgXml11);
- }
-
- /*
- ///////////////////////////////////////////////////
- // Public API
- ///////////////////////////////////////////////////
- */
-
- public int getValueType() {
- return TYPE_NMTOKEN;
- }
-
- /*
- ///////////////////////////////////////////////////
- // Public API, validation
- ///////////////////////////////////////////////////
- */
-
- /**
- * Method called by the validator
- * to let the attribute do necessary normalization and/or validation
- * for the value.
- */
- public String validate(DTDValidatorBase v, char[] cbuf, int start, int end, boolean normalize)
- throws XMLStreamException
- {
- int origLen = end-start;
-
- // Let's trim leading white space first...
- while (start < end && WstxInputData.isSpaceChar(cbuf[start])) {
- ++start;
- }
-
- // Empty value?
- if (start >= end) {
- return reportValidationProblem(v, "Empty NMTOKEN value");
- }
-
- --end; // so that it now points to the last char
- while (end > start && WstxInputData.isSpaceChar(cbuf[end])) {
- --end;
- }
-
- // Ok, need to check char validity
- for (int i = start; i <= end; ++i) {
- char c = cbuf[i];
- if (!WstxInputData.isNameChar(c, mCfgNsAware, mCfgXml11)) {
- return reportInvalidChar(v, c, "not valid NMTOKEN character");
- }
- }
-
- if (normalize) {
- // Let's only create the String if we trimmed something
- int len = (end - start)+1;
- if (len != origLen) {
- return new String(cbuf, start, len);
- }
- }
- return null;
- }
-
- /**
- * Method called by the validator
- * to ask attribute to verify that the default it has (if any) is
- * valid for such type.
- */
- public void validateDefault(InputProblemReporter rep, boolean normalize)
- throws XMLStreamException
- {
- String def = validateDefaultNmToken(rep, normalize);
- if (normalize) {
- mDefValue.setValue(def);
- }
- }
-}
diff -Nru libwoodstox-java-4.1.3/src/java/com/ctc/wstx/dtd/DTDNmTokensAttr.java libwoodstox-java-5.1.0/src/java/com/ctc/wstx/dtd/DTDNmTokensAttr.java
--- libwoodstox-java-4.1.3/src/java/com/ctc/wstx/dtd/DTDNmTokensAttr.java 2012-04-24 04:38:20.000000000 +0000
+++ libwoodstox-java-5.1.0/src/java/com/ctc/wstx/dtd/DTDNmTokensAttr.java 1970-01-01 00:00:00.000000000 +0000
@@ -1,205 +0,0 @@
-package com.ctc.wstx.dtd;
-
-import javax.xml.stream.XMLStreamException;
-
-import com.ctc.wstx.io.WstxInputData;
-import com.ctc.wstx.sr.InputProblemReporter;
-import com.ctc.wstx.util.PrefixedName;
-
-/**
- * Specific attribute class for attributes that contain (unique)
- * identifiers.
- */
-public final class DTDNmTokensAttr
- extends DTDAttribute
-{
- /*
- ///////////////////////////////////////////////////
- // Life-cycle
- ///////////////////////////////////////////////////
- */
-
- /**
- * Main constructor.
- */
- public DTDNmTokensAttr(PrefixedName name, DefaultAttrValue defValue, int specIndex,
- boolean nsAware, boolean xml11)
- {
- super(name, defValue, specIndex, nsAware, xml11);
- }
-
- public DTDAttribute cloneWith(int specIndex)
- {
- return new DTDNmTokensAttr(mName, mDefValue, specIndex, mCfgNsAware, mCfgXml11);
- }
-
- /*
- ///////////////////////////////////////////////////
- // Public API
- ///////////////////////////////////////////////////
- */
-
- public int getValueType() {
- return TYPE_NMTOKENS;
- }
-
- /*
- ///////////////////////////////////////////////////
- // Public API, validation
- ///////////////////////////////////////////////////
- */
-
- /**
- * Method called by the validator
- * to let the attribute do necessary normalization and/or validation
- * for the value.
- */
- public String validate(DTDValidatorBase v, char[] cbuf, int start, int end, boolean normalize)
- throws XMLStreamException
- {
- //int origStart = start;
-
- /* First things first; let's ensure value is not empty (all
- * white space)...
- */
- while (start < end && WstxInputData.isSpaceChar(cbuf[start])) {
- ++start;
- }
- // Empty value?
- if (start >= end) {
- return reportValidationProblem(v, "Empty NMTOKENS value");
- }
-
- /* Then, let's have separate handling for normalizing and
- * non-normalizing case, since latter is trivially easy case:
- */
- if (!normalize) {
- for (; start < end; ++start) {
- char c = cbuf[start];
- if (!WstxInputData.isSpaceChar(c)
- && !WstxInputData.isNameChar(c, mCfgNsAware, mCfgXml11)) {
- return reportInvalidChar(v, c, "not valid as NMTOKENS character");
- }
- }
- return null; // ok, all good
- }
-
- //boolean trimmed = (origStart != start);
- //origStart = start;
-
- --end; // so that it now points to the last char
- // Wouldn't absolutely have to trim trailing... but is easy to do
- while (end > start && WstxInputData.isSpaceChar(cbuf[end])) {
- --end;
- //trimmed = true;
- }
-
- /* Ok, now, need to check we only have valid chars, and maybe
- * also coalesce multiple spaces, if any.
- */
- StringBuffer sb = null;
-
- while (start <= end) {
- int i = start;
- for (; i <= end; ++i) {
- char c = cbuf[i];
- if (WstxInputData.isSpaceChar(c)) {
- break;
- }
- if (!WstxInputData.isNameChar(c, mCfgNsAware, mCfgXml11)) {
- return reportInvalidChar(v, c, "not valid as an NMTOKENS character");
- }
- }
-
- if (sb == null) {
- sb = new StringBuffer(end - start + 1);
- } else {
- sb.append(' ');
- }
- sb.append(cbuf, start, (i - start));
-
- start = i + 1;
- // Ok, any white space to skip?
- while (start <= end && WstxInputData.isSpaceChar(cbuf[start])) {
- ++start;
- }
- }
-
- /* 27-Nov-2005, TSa: Could actually optimize trimming, and often
- * avoid using StringBuffer... but let's only do it if it turns
- * out dealing with NMTOKENS normalization shows up on profiling...
- */
- return sb.toString();
- }
-
- /**
- * Method called by the validator
- * to ask attribute to verify that the default it has (if any) is
- * valid for such type.
- */
- public void validateDefault(InputProblemReporter rep, boolean normalize)
- throws XMLStreamException
- {
- String defValue = mDefValue.getValue();
- int len = defValue.length();
-
- // Then code similar to actual value validation:
- StringBuffer sb = null;
- int count = 0;
- int start = 0;
-
- main_loop:
- while (start < len) {
- char c = defValue.charAt(start);
-
- // Ok, any white space to skip?
- while (true) {
- if (!WstxInputData.isSpaceChar(c)) {
- break;
- }
- if (++start >= len) {
- break main_loop;
- }
- c = defValue.charAt(start);
- }
-
- int i = start+1;
-
- do {
- if (++i >= len) {
- break;
- }
- c = defValue.charAt(i);
- } while (!WstxInputData.isSpaceChar(c));
- ++count;
- String token = defValue.substring(start, i);
- int illegalIx = WstxInputData.findIllegalNmtokenChar(token, mCfgNsAware, mCfgXml11);
- if (illegalIx >= 0) {
- reportValidationProblem(rep, "Invalid default value '"+defValue
- +"'; character #"+illegalIx+" ("
- +WstxInputData.getCharDesc(defValue.charAt(illegalIx))
- +") not a valid NMTOKENS character");
- }
-
- if (normalize) {
- if (sb == null) {
- sb = new StringBuffer(i - start + 32);
- } else {
- sb.append(' ');
- }
- sb.append(token);
- }
- start = i+1;
- }
-
- if (count == 0) {
- reportValidationProblem(rep, "Invalid default value '"+defValue
- +"'; empty String is not a valid NMTOKENS value");
- return;
- }
-
- if (normalize) {
- mDefValue.setValue(sb.toString());
- }
- }
-}
diff -Nru libwoodstox-java-4.1.3/src/java/com/ctc/wstx/dtd/DTDNotationAttr.java libwoodstox-java-5.1.0/src/java/com/ctc/wstx/dtd/DTDNotationAttr.java
--- libwoodstox-java-4.1.3/src/java/com/ctc/wstx/dtd/DTDNotationAttr.java 2012-04-24 04:38:20.000000000 +0000
+++ libwoodstox-java-5.1.0/src/java/com/ctc/wstx/dtd/DTDNotationAttr.java 1970-01-01 00:00:00.000000000 +0000
@@ -1,100 +0,0 @@
-package com.ctc.wstx.dtd;
-
-import javax.xml.stream.XMLStreamException;
-
-import com.ctc.wstx.sr.InputProblemReporter;
-import com.ctc.wstx.util.PrefixedName;
-import com.ctc.wstx.util.WordResolver;
-
-/**
- * Specific attribute class for attributes that are of NOTATION type,
- * and also contain enumerated set of legal values.
- */
-public final class DTDNotationAttr
- extends DTDAttribute
-{
- final WordResolver mEnumValues;
-
- /*
- ///////////////////////////////////////////////////
- // Life-cycle
- ///////////////////////////////////////////////////
- */
-
- public DTDNotationAttr(PrefixedName name, DefaultAttrValue defValue,
- int specIndex, boolean nsAware, boolean xml11,
- WordResolver enumValues)
- {
- super(name, defValue, specIndex, nsAware, xml11);
- mEnumValues = enumValues;
- }
-
- public DTDAttribute cloneWith(int specIndex)
- {
- return new DTDNotationAttr(mName, mDefValue, specIndex,
- mCfgNsAware, mCfgXml11, mEnumValues);
- }
-
- /*
- ///////////////////////////////////////////////////
- // Public API
- ///////////////////////////////////////////////////
- */
-
- public int getValueType() {
- return TYPE_NOTATION;
- }
-
- public boolean typeIsNotation() {
- return true;
- }
-
- /*
- ///////////////////////////////////////////////////
- // Public API, validation
- ///////////////////////////////////////////////////
- */
-
- /**
- * Method called by the validator
- * to let the attribute do necessary normalization and/or validation
- * for the value.
- *
- * Note: identical to the implementation in {@link DTDEnumAttr}
- */
- public String validate(DTDValidatorBase v, char[] cbuf, int start, int end, boolean normalize)
- throws XMLStreamException
- {
- String ok = validateEnumValue(cbuf, start, end, normalize, mEnumValues);
- if (ok == null) {
- String val = new String(cbuf, start, (end-start));
- return reportValidationProblem(v, "Invalid notation value '"+val+"': has to be one of ("
- +mEnumValues+")");
- }
- return ok;
- }
-
- /**
- * Method called by the validator
- * to ask attribute to verify that the default it has (if any) is
- * valid for such type.
- */
- public void validateDefault(InputProblemReporter rep, boolean normalize)
- throws XMLStreamException
- {
- // First, basic checks that it's a valid non-empty name:
- String def = validateDefaultName(rep, normalize);
-
- // And then that it's one of listed values:
- String shared = mEnumValues.find(def);
- if (shared == null) {
- reportValidationProblem(rep, "Invalid default value '"+def+"': has to be one of ("
- +mEnumValues+")");
- }
-
- // Ok, cool it's ok...
- if (normalize) {
- mDefValue.setValue(shared);
- }
- }
-}
diff -Nru libwoodstox-java-4.1.3/src/java/com/ctc/wstx/dtd/DTDSchemaFactory.java libwoodstox-java-5.1.0/src/java/com/ctc/wstx/dtd/DTDSchemaFactory.java
--- libwoodstox-java-4.1.3/src/java/com/ctc/wstx/dtd/DTDSchemaFactory.java 2012-04-24 04:38:20.000000000 +0000
+++ libwoodstox-java-5.1.0/src/java/com/ctc/wstx/dtd/DTDSchemaFactory.java 1970-01-01 00:00:00.000000000 +0000
@@ -1,202 +0,0 @@
-/* Woodstox XML processor
- *
- * Copyright (c) 2004- Tatu Saloranta, tatu.saloranta@iki.fi
- *
- * Licensed under the License specified in the file LICENSE which is
- * included with the source code.
- * You may not use this file except in compliance with the License.
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.ctc.wstx.dtd;
-
-import java.io.*;
-import java.net.URL;
-
-import javax.xml.stream.*;
-
-import org.codehaus.stax2.validation.*;
-
-import com.ctc.wstx.api.ReaderConfig;
-import com.ctc.wstx.api.ValidatorConfig;
-import com.ctc.wstx.cfg.XmlConsts;
-import com.ctc.wstx.exc.WstxIOException;
-import com.ctc.wstx.io.*;
-import com.ctc.wstx.util.DefaultXmlSymbolTable;
-import com.ctc.wstx.util.SymbolTable;
-import com.ctc.wstx.util.URLUtil;
-
-/**
- * Factory for creating DTD validator schema objects (shareable stateless
- * "blueprints" for creating actual validators).
- *
- * Due to close coupling of XML and DTD, some of the functionality
- * implemented (like that of reading internal subsets embedded in XML
- * documents) is only accessible by core Woodstox. The externally
- * accessible
- */
-public class DTDSchemaFactory
- extends XMLValidationSchemaFactory
-{
- /*
- /////////////////////////////////////////////////////
- // Objects shared by actual parsers
- /////////////////////////////////////////////////////
- */
-
- /**
- * 'Root' symbol table, used for creating actual symbol table instances,
- * but never as is.
- */
- final static SymbolTable mRootSymbols = DefaultXmlSymbolTable.getInstance();
- static {
- mRootSymbols.setInternStrings(true);
- }
-
- /**
- * Current configurations for this factory
- */
- protected final ValidatorConfig mSchemaConfig;
-
- /**
- * This configuration object is used (instead of a more specific one)
- * since the actual DTD reader uses such configuration object.
- */
- protected final ReaderConfig mReaderConfig;
-
- public DTDSchemaFactory()
- {
- super(XMLValidationSchema.SCHEMA_ID_DTD);
- mReaderConfig = ReaderConfig.createFullDefaults();
- mSchemaConfig = ValidatorConfig.createDefaults();
- }
-
- /*
- ////////////////////////////////////////////////////////////
- // Stax2, Configuration methods
- ////////////////////////////////////////////////////////////
- */
-
- public boolean isPropertySupported(String propName)
- {
- return mSchemaConfig.isPropertySupported(propName);
- }
-
- public boolean setProperty(String propName, Object value)
- {
- return mSchemaConfig.setProperty(propName, value);
- }
-
- public Object getProperty(String propName)
- {
- return mSchemaConfig.getProperty(propName);
- }
-
- /*
- ////////////////////////////////////////////////////////////
- // Stax2, Factory methods
- ////////////////////////////////////////////////////////////
- */
-
- public XMLValidationSchema createSchema(InputStream in, String encoding,
- String publicId, String systemId)
- throws XMLStreamException
- {
- ReaderConfig rcfg = createPrivateReaderConfig();
- return doCreateSchema(rcfg, StreamBootstrapper.getInstance
- (publicId, systemId, in), publicId, systemId, null);
- }
-
- public XMLValidationSchema createSchema(Reader r, String publicId,
- String systemId)
- throws XMLStreamException
- {
- ReaderConfig rcfg = createPrivateReaderConfig();
- return doCreateSchema(rcfg, ReaderBootstrapper.getInstance
- (publicId, systemId, r, null), publicId, systemId, null);
- }
-
- public XMLValidationSchema createSchema(URL url)
- throws XMLStreamException
- {
- ReaderConfig rcfg = createPrivateReaderConfig();
- try {
- InputStream in = URLUtil.inputStreamFromURL(url);
- return doCreateSchema(rcfg, StreamBootstrapper.getInstance
- (null, null, in),
- null, url.toExternalForm(), url);
- } catch (IOException ioe) {
- throw new WstxIOException(ioe);
- }
- }
-
- public XMLValidationSchema createSchema(File f)
- throws XMLStreamException
- {
- ReaderConfig rcfg = createPrivateReaderConfig();
- try {
- URL url = f.toURL();
- return doCreateSchema(rcfg, StreamBootstrapper.getInstance
- (null, null, new FileInputStream(f)),
- null, url.toExternalForm(), url);
- } catch (IOException ioe) {
- throw new WstxIOException(ioe);
- }
- }
-
- /*
- ////////////////////////////////////////////////////////////
- // Woodstox-specific API
- ////////////////////////////////////////////////////////////
- */
-
- /*
- ////////////////////////////////////////////////////////////
- // Internal methods
- ////////////////////////////////////////////////////////////
- */
-
- /**
- * The main validator construction method, called by all externally
- * visible methods.
- */
- protected XMLValidationSchema doCreateSchema
- (ReaderConfig rcfg, InputBootstrapper bs, String publicId, String systemId, URL ctxt)
- throws XMLStreamException
- {
- try {
- Reader r = bs.bootstrapInput(rcfg, false, XmlConsts.XML_V_UNKNOWN);
- if (bs.declaredXml11()) {
- rcfg.enableXml11(true);
- }
- if (ctxt == null) { // this is just needed as context for param entity expansion
- ctxt = URLUtil.urlFromCurrentDir();
- }
- /* Note: need to pass unknown for 'xmlVersion' here (as well as
- * above for bootstrapping), since this is assumed to be the main
- * level parsed document and no xml version compatibility checks
- * should be done.
- */
- WstxInputSource src = InputSourceFactory.constructEntitySource
- (rcfg, null, null, bs, publicId, systemId, XmlConsts.XML_V_UNKNOWN, ctxt, r);
-
- /* true -> yes, fully construct for validation
- * (does not mean it has to be used for validation, but required
- * if it is to be used for that purpose)
- */
- return FullDTDReader.readExternalSubset(src, rcfg, /*int.subset*/null, true, bs.getDeclaredVersion());
- } catch (IOException ioe) {
- throw new WstxIOException(ioe);
- }
- }
-
- private ReaderConfig createPrivateReaderConfig()
- {
- return mReaderConfig.createNonShared(mRootSymbols.makeChild());
- }
-}
diff -Nru libwoodstox-java-4.1.3/src/java/com/ctc/wstx/dtd/DTDSubsetImpl.java libwoodstox-java-5.1.0/src/java/com/ctc/wstx/dtd/DTDSubsetImpl.java
--- libwoodstox-java-4.1.3/src/java/com/ctc/wstx/dtd/DTDSubsetImpl.java 2012-04-24 04:38:20.000000000 +0000
+++ libwoodstox-java-5.1.0/src/java/com/ctc/wstx/dtd/DTDSubsetImpl.java 1970-01-01 00:00:00.000000000 +0000
@@ -1,527 +0,0 @@
-/* Woodstox XML processor
- *
- * Copyright (c) 2004- 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 com.ctc.wstx.dtd;
-
-import java.text.MessageFormat;
-import java.util.*;
-
-import javax.xml.stream.Location;
-import javax.xml.stream.XMLStreamException;
-import javax.xml.stream.events.NotationDeclaration;
-
-import org.codehaus.stax2.validation.*;
-
-import com.ctc.wstx.cfg.ErrorConsts;
-import com.ctc.wstx.exc.WstxParsingException;
-import com.ctc.wstx.sr.InputProblemReporter;
-import com.ctc.wstx.util.DataUtil;
-
-/**
- * The default implementation of {@link DTDSubset}
- */
-public final class DTDSubsetImpl
- extends DTDSubset
-{
- /**
- * Whether this subset is cachable. Only those external
- * subsets that do not refer to PEs defined by internal subsets (or
- * GEs via default attribute value expansion) are cachable.
- */
- final boolean mIsCachable;
-
- /**
- * Whether this subset has full validation information; and
- * consequently whether it will do actual validation, or just allow
- * access to type information, notations, entities, and add default
- * attribute values.
- */
- final boolean mFullyValidating;
-
- /**
- * Flag that indicates whether any of the elements declarared
- * has any attribute default values for namespace pseudo-attributes.
- */
- final boolean mHasNsDefaults;
-
- /*
- //////////////////////////////////////////////////////
- // Entity information
- //////////////////////////////////////////////////////
- */
-
- /**
- * Map (name-to-EntityDecl) of general entity declarations (internal,
- * external) for this DTD subset.
- */
- final HashMap mGeneralEntities;
-
- /**
- * Lazily instantiated List that contains all notations from
- * {@link #mGeneralEntities} (preferably in their declaration order; depends
- * on whether platform, ie. JDK version, has insertion-ordered
- * Maps available), used by DTD event Objects.
- */
- volatile transient List mGeneralEntityList = null;
-
- /**
- * Set of names of general entities references by this subset. Note that
- * only those GEs that are referenced by default attribute value
- * definitions count, since GEs in text content are only expanded
- * when reading documents, but attribute default values are expanded
- * when reading DTD subset itself.
- *
- * Needed
- * for determinining if external subset materially depends on definitions
- * from internal subset; if so, such subset is not cachable.
- * This also
- * means that information is not stored for non-cachable instance.
- */
- final Set mRefdGEs;
-
- // // // Parameter entity info:
-
- /**
- * Map (name-to-WEntityDeclaration) that contains all parameter entities
- * defined by this subset. May be empty if such information will not be
- * needed for use; for example, external subset's definitions are needed,
- * nor are combined DTD set's.
- */
- final HashMap mDefinedPEs;
-
- /**
- * Set of names of parameter entities references by this subset. Needed
- * when determinining if external subset materially depends on definitions
- * from internal subset, which is needed to know when caching external
- * subsets.
- *
- * Needed
- * for determinining if external subset materially depends on definitions
- * from internal subset; if so, such subset is not cachable.
- * This also
- * means that information is not stored for non-cachable instance.
- */
- final Set mRefdPEs;
-
- /*
- //////////////////////////////////////////////////////
- // Notation definitions:
- //////////////////////////////////////////////////////
- */
-
- /**
- * Map (name-to-NotationDecl) that this subset has defined.
- */
- final HashMap mNotations;
-
- /**
- * Lazily instantiated List that contains all notations from
- * {@link #mNotations} (preferably in their declaration order; depends
- * on whether platform, ie. JDK version, has insertion-ordered
- * Maps available), used by DTD event Objects.
- */
- transient List mNotationList = null;
-
-
- /*
- //////////////////////////////////////////////////////
- // Element definitions:
- //////////////////////////////////////////////////////
- */
-
- final HashMap mElements;
-
- /*
- //////////////////////////////////////////////////////
- // Life-cycle
- //////////////////////////////////////////////////////
- */
-
- private DTDSubsetImpl(boolean cachable,
- HashMap genEnt, Set refdGEs,
- HashMap paramEnt, Set peRefs,
- HashMap notations, HashMap elements,
- boolean fullyValidating)
- {
- mIsCachable = cachable;
- mGeneralEntities = genEnt;
- mRefdGEs = refdGEs;
- mDefinedPEs = paramEnt;
- mRefdPEs = peRefs;
- mNotations = notations;
- mElements = elements;
- mFullyValidating = fullyValidating;
-
- boolean anyNsDefs = false;
- if (elements != null) {
- Iterator it = elements.values().iterator();
- while (it.hasNext()) {
- DTDElement elem = (DTDElement) it.next();
- if (elem.hasNsDefaults()) {
- anyNsDefs = true;
- break;
- }
- }
- }
- mHasNsDefaults = anyNsDefs;
- }
-
- public static DTDSubsetImpl constructInstance(boolean cachable,
- HashMap genEnt, Set refdGEs,
- HashMap paramEnt, Set refdPEs,
- HashMap notations, HashMap elements,
- boolean fullyValidating)
- {
- return new DTDSubsetImpl(cachable, genEnt, refdGEs,
- paramEnt, refdPEs,
- notations, elements,
- fullyValidating);
- }
-
- /**
- * Method that will combine definitions from internal and external subsets,
- * producing a single DTD set.
- */
- public DTDSubset combineWithExternalSubset(InputProblemReporter rep, DTDSubset extSubset)
- throws XMLStreamException
- {
- /* First let's see if we can just reuse GE Map used by int or ext
- * subset; (if only one has contents), or if not, combine them.
- */
- HashMap ge1 = getGeneralEntityMap();
- HashMap ge2 = extSubset.getGeneralEntityMap();
- if (ge1 == null || ge1.isEmpty()) {
- ge1 = ge2;
- } else {
- if (ge2 != null && !ge2.isEmpty()) {
- /* Internal subset Objects are never shared or reused (and by
- * extension, neither are objects they contain), so we can just
- * modify GE map if necessary
- */
- combineMaps(ge1, ge2);
- }
- }
-
- // Ok, then, let's combine notations similarly
- HashMap n1 = getNotationMap();
- HashMap n2 = extSubset.getNotationMap();
- if (n1 == null || n1.isEmpty()) {
- n1 = n2;
- } else {
- if (n2 != null && !n2.isEmpty()) {
- /* First; let's make sure there are no colliding notation
- * definitions: it's an error to try to redefine notations.
- */
- checkNotations(n1, n2);
-
- /* Internal subset Objects are never shared or reused (and by
- * extension, neither are objects they contain), so we can just
- * modify notation map if necessary
- */
- combineMaps(n1, n2);
- }
- }
-
-
- // And finally elements, rather similarly:
- HashMap e1 = getElementMap();
- HashMap e2 = extSubset.getElementMap();
- if (e1 == null || e1.isEmpty()) {
- e1 = e2;
- } else {
- if (e2 != null && !e2.isEmpty()) {
- /* Internal subset Objects are never shared or reused (and by
- * extension, neither are objects they contain), so we can just
- * modify element map if necessary
- */
- combineElements(rep, e1, e2);
- }
- }
-
- /* Combos are not cachable, and because of that, there's no point
- * in storing any PE info either.
- */
- return constructInstance(false, ge1, null, null, null, n1, e1,
- mFullyValidating);
- }
-
- /*
- //////////////////////////////////////////////////////
- // XMLValidationSchema implementation
- //////////////////////////////////////////////////////
- */
-
- public XMLValidator createValidator(ValidationContext ctxt)
- throws XMLStreamException
- {
- if (mFullyValidating) {
- return new DTDValidator(this, ctxt, mHasNsDefaults,
- getElementMap(), getGeneralEntityMap());
- }
- return new DTDTypingNonValidator(this, ctxt, mHasNsDefaults,
- getElementMap(), getGeneralEntityMap());
-
- }
-
- /*
- //////////////////////////////////////////////////////
- // DTDValidationSchema implementation
- //////////////////////////////////////////////////////
- */
-
- public int getEntityCount() {
- return (mGeneralEntities == null) ? 0 : mGeneralEntities.size();
- }
-
- public int getNotationCount() {
- return (mNotations == null) ? 0 : mNotations.size();
- }
-
- /*
- //////////////////////////////////////////////////////
- // Woodstox-specific public API
- //////////////////////////////////////////////////////
- */
-
- public boolean isCachable() {
- return mIsCachable;
- }
-
- public HashMap getGeneralEntityMap() {
- return mGeneralEntities;
- }
-
- public List getGeneralEntityList()
- {
- List l = mGeneralEntityList;
- if (l == null) {
- if (mGeneralEntities == null || mGeneralEntities.size() == 0) {
- l = Collections.EMPTY_LIST;
- } else {
- l = Collections.unmodifiableList(new ArrayList(mGeneralEntities.values()));
- }
- mGeneralEntityList = l;
- }
-
- return l;
- }
-
- public HashMap getParameterEntityMap() {
- return mDefinedPEs;
- }
-
- public HashMap getNotationMap() {
- return mNotations;
- }
-
- public synchronized List getNotationList()
- {
- List l = mNotationList;
- if (l == null) {
- if (mNotations == null || mNotations.size() == 0) {
- l = Collections.EMPTY_LIST;
- } else {
- l = Collections.unmodifiableList(new ArrayList(mNotations.values()));
- }
- mNotationList = l;
- }
-
- return l;
- }
-
- public HashMap getElementMap() {
- return mElements;
- }
-
- /**
- * Method used in determining whether cached external subset instance
- * can be used with specified internal subset. If ext. subset references
- * any parameter/general entities int subset (re-)defines, it can not;
- * otherwise it can be used.
- *
- * @return True if this (external) subset refers to a parameter entity
- * defined in passed-in internal subset.
- */
- public boolean isReusableWith(DTDSubset intSubset)
- {
- Set refdPEs = mRefdPEs;
-
- if (refdPEs != null && refdPEs.size() > 0) {
- HashMap intPEs = intSubset.getParameterEntityMap();
- if (intPEs != null && intPEs.size() > 0) {
- if (DataUtil.anyValuesInCommon(refdPEs, intPEs.keySet())) {
- return false;
- }
- }
- }
- Set refdGEs = mRefdGEs;
-
- if (refdGEs != null && refdGEs.size() > 0) {
- HashMap intGEs = intSubset.getGeneralEntityMap();
- if (intGEs != null && intGEs.size() > 0) {
- if (DataUtil.anyValuesInCommon(refdGEs, intGEs.keySet())) {
- return false;
- }
- }
- }
- return true; // yep, no dependencies overridden
- }
-
- /*
- //////////////////////////////////////////////////////
- // Overridden default methods:
- //////////////////////////////////////////////////////
- */
-
- public String toString() {
- StringBuffer sb = new StringBuffer();
- sb.append("[DTDSubset: ");
- int count = getEntityCount();
- sb.append(count);
- sb.append(" general entities");
- sb.append(']');
- return sb.toString();
- }
-
- /*
- //////////////////////////////////////////////////////
- // Convenience methods used by other classes
- //////////////////////////////////////////////////////
- */
-
- public static void throwNotationException(NotationDeclaration oldDecl, NotationDeclaration newDecl)
- throws XMLStreamException
- {
- throw new WstxParsingException
- (MessageFormat.format(ErrorConsts.ERR_DTD_NOTATION_REDEFD,
- new Object[] {
- newDecl.getName(),
- oldDecl.getLocation().toString()}),
- newDecl.getLocation());
- }
-
- public static void throwElementException(DTDElement oldElem, Location loc)
- throws XMLStreamException
- {
- throw new WstxParsingException
- (MessageFormat.format(ErrorConsts.ERR_DTD_ELEM_REDEFD,
- new Object[] {
- oldElem.getDisplayName(),
- oldElem.getLocation().toString() }),
- loc);
- }
-
- /*
- //////////////////////////////////////////////////////
- // Internal methods
- //////////////////////////////////////////////////////
- */
-
- /**
- *
- * Note: The first Map argument WILL be modified; second one
- * not. Caller needs to ensure this is acceptable.
- */
- private static void combineMaps(HashMap m1, HashMap m2)
- {
- Iterator it = m2.entrySet().iterator();
- while (it.hasNext()) {
- Map.Entry me = (Map.Entry) it.next();
- Object key = me.getKey();
- /* Int. subset has precedence, but let's guess most of
- * the time there are no collisions:
- */
- Object old = m1.put(key, me.getValue());
- // Oops, got value! Let's put it back
- if (old != null) {
- m1.put(key, old);
- }
- }
- }
-
- /**
- * Method that will try to merge in elements defined in the external
- * subset, into internal subset; it will also check for redeclarations
- * when doing this, as it's invalid to redeclare elements. Care has to
- * be taken to only check actual redeclarations: placeholders should
- * not cause problems.
- */
- private void combineElements(InputProblemReporter rep, HashMap intElems, HashMap extElems)
- throws XMLStreamException
- {
- Iterator it = extElems.entrySet().iterator();
- while (it.hasNext()) {
- Map.Entry me = (Map.Entry) it.next();
- Object key = me.getKey();
- Object extVal = me.getValue();
- Object oldVal = intElems.get(key);
-
- // If there was no old value, can just merge new one in and continue
- if (oldVal == null) {
- intElems.put(key, extVal);
- continue;
- }
-
- DTDElement extElem = (DTDElement) extVal;
- DTDElement intElem = (DTDElement) oldVal;
-
- // Which one is defined (if either)?
- if (extElem.isDefined()) { // one from the ext subset
- if (intElem.isDefined()) { // but both can't be; that's an error
- throwElementException(intElem, extElem.getLocation());
- } else {
- /* Note: can/should not modify the external element (by
- * for example adding attributes); external element may
- * be cached and shared... so, need to do the reverse,
- * define the one from internal subset.
- */
- intElem.defineFrom(rep, extElem, mFullyValidating);
- }
- } else {
- if (!intElem.isDefined()) {
- /* ??? Should we warn about neither of them being really
- * declared?
- */
- rep.reportProblem(intElem.getLocation(),
- ErrorConsts.WT_ENT_DECL,
- ErrorConsts.W_UNDEFINED_ELEM,
- extElem.getDisplayName(), null);
-
- } else {
- intElem.mergeMissingAttributesFrom(rep, extElem, mFullyValidating);
- }
- }
- }
- }
-
- private static void checkNotations(HashMap fromInt, HashMap fromExt)
- throws XMLStreamException
- {
- /* Since it's external subset that would try to redefine things
- * defined in internal subset, let's traverse definitions in
- * the ext. subset first (even though that may not be the fastest
- * way), so that we have a chance of catching the first problem
- * (As long as Maps iterate in insertion order).
- */
- Iterator it = fromExt.entrySet().iterator();
- while (it.hasNext()) {
- Map.Entry en = (Map.Entry) it.next();
- if (fromInt.containsKey(en.getKey())) {
- throwNotationException((NotationDeclaration) fromInt.get(en.getKey()),
- (NotationDeclaration) en.getValue());
- }
- }
- }
-}
diff -Nru libwoodstox-java-4.1.3/src/java/com/ctc/wstx/dtd/DTDSubset.java libwoodstox-java-5.1.0/src/java/com/ctc/wstx/dtd/DTDSubset.java
--- libwoodstox-java-4.1.3/src/java/com/ctc/wstx/dtd/DTDSubset.java 2012-04-24 04:38:20.000000000 +0000
+++ libwoodstox-java-5.1.0/src/java/com/ctc/wstx/dtd/DTDSubset.java 1970-01-01 00:00:00.000000000 +0000
@@ -1,115 +0,0 @@
-/* Woodstox XML processor
- *
- * Copyright (c) 2004- Tatu Saloranta, tatu.saloranta@iki.fi
- *
- * Licensed under the License specified in the file LICENSE which is
- * included with the source code.
- * You may not use this file except in compliance with the License.
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.ctc.wstx.dtd;
-
-import java.util.*;
-
-import javax.xml.stream.XMLStreamException;
-
-import org.codehaus.stax2.validation.*;
-
-import com.ctc.wstx.sr.InputProblemReporter;
-
-/**
- * This is the abstract base class that implements the standard Stax2
- * validation schema base class ({@link XMLValidationSchema}, as well
- * as specifies extended Woodstox-specific interface for accessing
- * DTD-specific things like entity expansions and notation properties.
- *
- * API is separated from its implementation to reduce coupling; for example,
- * it is possible to have DTD subset implementations that do not implement
- * validation logics, just entity expansion.
- */
-public abstract class DTDSubset
- implements DTDValidationSchema
-{
- /*
- //////////////////////////////////////////////////////
- // Life-cycle
- //////////////////////////////////////////////////////
- */
-
- protected DTDSubset() { }
-
- /**
- * Method that will combine definitions from this internal subset with
- * definitions from passed-in external subset, producing a new combined
- * DTDSubset instance.
- */
- public abstract DTDSubset combineWithExternalSubset(InputProblemReporter rep,
- DTDSubset extSubset)
- throws XMLStreamException;
-
- /*
- //////////////////////////////////////////////////////
- // XMLValidationSchema implementation
- //////////////////////////////////////////////////////
- */
-
- public abstract XMLValidator createValidator(ValidationContext ctxt)
- throws XMLStreamException;
-
- public String getSchemaType() {
- return XMLValidationSchema.SCHEMA_ID_DTD;
- }
-
- /*
- //////////////////////////////////////////////////////
- // And extended DTDValidationSchema
- //////////////////////////////////////////////////////
- */
-
- public abstract int getEntityCount();
-
- public abstract int getNotationCount();
-
- /*
- //////////////////////////////////////////////////////
- // Woodstox-specific API, caching support
- //////////////////////////////////////////////////////
- */
-
- public abstract boolean isCachable();
-
- /**
- * Method used in determining whether cached external subset instance
- * can be used with specified internal subset. If ext. subset references
- * any parameter entities int subset (re-)defines, it can not; otherwise
- * it can be used.
- *
- * @return True if this (external) subset refers to a parameter entity
- * defined in passed-in internal subset.
- */
- public abstract boolean isReusableWith(DTDSubset intSubset);
-
- /*
- //////////////////////////////////////////////////////
- // Woodstox-specific API, entity/notation handling
- //////////////////////////////////////////////////////
- */
-
- public abstract HashMap getGeneralEntityMap();
-
- public abstract List getGeneralEntityList();
-
- public abstract HashMap getParameterEntityMap();
-
- public abstract HashMap getNotationMap();
-
- public abstract List getNotationList();
-
- public abstract HashMap getElementMap();
-}
diff -Nru libwoodstox-java-4.1.3/src/java/com/ctc/wstx/dtd/DTDTypingNonValidator.java libwoodstox-java-5.1.0/src/java/com/ctc/wstx/dtd/DTDTypingNonValidator.java
--- libwoodstox-java-4.1.3/src/java/com/ctc/wstx/dtd/DTDTypingNonValidator.java 2012-04-24 04:38:20.000000000 +0000
+++ libwoodstox-java-5.1.0/src/java/com/ctc/wstx/dtd/DTDTypingNonValidator.java 1970-01-01 00:00:00.000000000 +0000
@@ -1,315 +0,0 @@
-/* Woodstox XML processor
- *
- * Copyright (c) 2004- 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 com.ctc.wstx.dtd;
-
-import java.util.*;
-
-import javax.xml.stream.XMLStreamException;
-
-import org.codehaus.stax2.validation.*;
-
-import com.ctc.wstx.util.DataUtil;
-import com.ctc.wstx.util.ElementIdMap;
-import com.ctc.wstx.util.ExceptionUtil;
-
-/**
- * This class is a "non-validating validator"; a validator-like object
- * that handles DTD-based non-validation functionality: determining type
- * information and default values. This instance does NOT implement any
- * actual DTD-validation, and is to be used in DTD-aware non-validating
- * mode.
- */
-public class DTDTypingNonValidator
- extends DTDValidatorBase
-{
- /*
- ///////////////////////////////////////////
- // Element def/spec/validator stack, state
- ///////////////////////////////////////////
- */
-
- /**
- * Flag that indicates if current element has any attributes that
- * have default values.
- */
- protected boolean mHasAttrDefaults = false;
-
- /**
- * Bitset used for keeping track of defaulted attributes for which values
- * have been found. Only non-null when current element does have such
- * attributes
- */
- protected BitSet mCurrDefaultAttrs = null;
-
- /**
- * Flag that indicates whether any of the attributes is potentially
- * normalizable, and we are in attribute-normalizing mode.
- */
- protected boolean mHasNormalizableAttrs = false;
-
- /*
- ///////////////////////////////////////
- // Temporary helper objects
- ///////////////////////////////////////
- */
-
- /**
- * Reusable lazily instantiated BitSet; needed to keep track of
- * 'missing' attributes with default values (normal default, #FIXED).
- */
- BitSet mTmpDefaultAttrs;
-
- /*
- ///////////////////////////////////////////
- // Life-cycle
- ///////////////////////////////////////////
- */
-
- public DTDTypingNonValidator(DTDSubset schema, ValidationContext ctxt, boolean hasNsDefaults,
- Map elemSpecs, Map genEntities)
- {
- super(schema, ctxt, hasNsDefaults, elemSpecs, genEntities);
- }
-
- /**
- * @return False, since this is not a real validator
- */
- public final boolean reallyValidating() { return false; }
-
- /*
- ///////////////////////////////////////
- // Configuration
- ///////////////////////////////////////
- */
-
- /**
- * This 'validator' will not normalize any attributes,
- * so let's implement this as no-op.
- */
- public void setAttrValueNormalization(boolean state) {
- // nop
- }
-
- /*
- ///////////////////////////////////////
- // XMLValidator implementation
- ///////////////////////////////////////
- */
-
- //public XMLValidationSchema getSchema()
-
- public void validateElementStart(String localName, String uri, String prefix)
- throws XMLStreamException
- {
- // Ok, can we find the element definition?
- mTmpKey.reset(prefix, localName);
- DTDElement elem = (DTDElement) mElemSpecs.get(mTmpKey);
- // whether it's found or not, let's add a stack frame:
- int elemCount = mElemCount++;
- if (elemCount >= mElems.length) {
- mElems = (DTDElement[]) DataUtil.growArrayBy50Pct(mElems);
- }
-
- mElems[elemCount] = mCurrElem = elem;
- mAttrCount = 0;
- mIdAttrIndex = -2; // -2 as a "don't know yet" marker
-
- /* but if not found, can not obtain any type information. Not
- * a validation problem though, since we are doing none...
- * Oh, also, unlike with real validation, not having actual element
- * information is ok; can still have attributes!
- */
- if (elem == null) { // || !elem.isDefined())
- mCurrAttrDefs = EMPTY_MAP;
- mHasAttrDefaults = false;
- mCurrDefaultAttrs = null;
- mHasNormalizableAttrs = false;
- return;
- }
-
- // If element found, does it have any attributes?
- mCurrAttrDefs = elem.getAttributes();
- if (mCurrAttrDefs == null) {
- mCurrAttrDefs = EMPTY_MAP;
- mHasAttrDefaults = false;
- mCurrDefaultAttrs = null;
- mHasNormalizableAttrs = false;
- return;
- }
-
- // Any normalization needed?
- mHasNormalizableAttrs = mNormAttrs || elem.attrsNeedValidation();
-
- // Any default values?
- mHasAttrDefaults = elem.hasAttrDefaultValues();
- if (mHasAttrDefaults) {
- /* Special count also contains ones with #REQUIRED value, but
- * that's a minor sub-optimality...
- */
- int specCount = elem.getSpecialCount();
- BitSet bs = mTmpDefaultAttrs;
- if (bs == null) {
- mTmpDefaultAttrs = bs = new BitSet(specCount);
- } else {
- bs.clear();
- }
- mCurrDefaultAttrs = bs;
- } else {
- mCurrDefaultAttrs = null;
- }
- }
-
- public String validateAttribute(String localName, String uri,
- String prefix, String value)
- throws XMLStreamException
- {
- /* no need to do any validation; however, need to do following:
- *
- * (a) Figure out type info, if any (to get data type, id index etc);
- * if yes, do:
- * (1) If attribute has default value, note down it's not needed due
- * to explicit definition
- * (2) If attribute is normalizable, normalize it without validation
- */
- DTDAttribute attr = (DTDAttribute) mCurrAttrDefs.get(mTmpKey.reset(prefix, localName));
- int index = mAttrCount++;
- if (index >= mAttrSpecs.length) {
- mAttrSpecs = (DTDAttribute[]) DataUtil.growArrayBy50Pct(mAttrSpecs);
- }
- mAttrSpecs[index] = attr;
-
- /* Although undeclared attribute would be a validation error,
- * we don't care here... just need to skip it
- */
- if (attr != null) {
- if (mHasAttrDefaults) {
- /* Once again, let's use more generic 'special' index,
- * even though it also includes #REQUIRED values
- */
- int specIndex = attr.getSpecialIndex();
- if (specIndex >= 0) {
- mCurrDefaultAttrs.set(specIndex);
- }
- }
- if (mHasNormalizableAttrs) {
- // !!! TBI
- }
- }
- return null; // fine as is
- }
-
- public String validateAttribute(String localName, String uri,
- String prefix,
- char[] valueChars, int valueStart,
- int valueEnd)
- throws XMLStreamException
- {
- // note: cut'n pasted from above...
- DTDAttribute attr = (DTDAttribute) mCurrAttrDefs.get(mTmpKey.reset(prefix, localName));
- int index = mAttrCount++;
- if (index >= mAttrSpecs.length) {
- mAttrSpecs = (DTDAttribute[]) DataUtil.growArrayBy50Pct(mAttrSpecs);
- }
- mAttrSpecs[index] = attr;
- if (attr != null) {
- if (mHasAttrDefaults) {
- int specIndex = attr.getSpecialIndex();
- if (specIndex >= 0) {
- mCurrDefaultAttrs.set(specIndex);
- }
- }
- if (mHasNormalizableAttrs) { // may get normalized, after all
- return attr.normalize(this, valueChars, valueStart, valueEnd);
- }
- }
- return null; // fine as is
- }
-
- public int validateElementAndAttributes()
- throws XMLStreamException
- {
- /* Ok; since we are not really validating, we just need to add possible
- * attribute default values, and return "anything goes"
- * as the allowable content:
- */
- DTDElement elem = mCurrElem;
- if (mHasAttrDefaults) {
- BitSet specBits = mCurrDefaultAttrs;
- int specCount = elem.getSpecialCount();
- int ix = specBits.nextClearBit(0);
- while (ix < specCount) { // something amiss!
- List specAttrs = elem.getSpecialAttrs();
- DTDAttribute attr = (DTDAttribute) specAttrs.get(ix);
- if (attr.hasDefaultValue()) { // no default for #REQUIRED...
- doAddDefaultValue(attr);
- }
- ix = specBits.nextClearBit(ix+1);
- }
- }
- /* However: we should indicate cases where PCDATA is not supposed
- * to occur -- although it won't be considered an error, when not
- * validating, info is needed to determine type of SPACE instead
- * of CHARACTERS. Other validation types are not to be returned,
- * however, since caller doesn't know how to deal with such
- * cases.
- */
- return (elem == null) ? XMLValidator.CONTENT_ALLOW_ANY_TEXT :
- elem.getAllowedContentIfSpace();
- }
-
- public int validateElementEnd(String localName, String uri, String prefix)
- throws XMLStreamException
- {
- /* Since we are not really validating, only need to maintain
- * the element stack, and return "anything goes" as allowable content:
- */
- int ix = --mElemCount;
- mElems[ix] = null;
- if (ix < 1) {
- return XMLValidator.CONTENT_ALLOW_ANY_TEXT;
- }
- DTDElement elem = mElems[ix-1];
- return (elem == null) ? XMLValidator.CONTENT_ALLOW_ANY_TEXT :
- mElems[ix-1].getAllowedContentIfSpace();
- }
-
- // base class implements these ok:
- //public void validateText(String text, boolean lastTextSegment)
- //public void validateText(char[] cbuf, int textStart, int textEnd, boolean lastTextSegment)
-
- public void validationCompleted(boolean eod)
- //throws XMLStreamException
- {
- // fine, great, nothing to do...
- }
-
- /*
- ///////////////////////////////////////
- // Package methods, accessors
- ///////////////////////////////////////
- */
-
- protected ElementIdMap getIdMap()
- {
- /* should never be called; for now let's throw an exception, if it
- * turns out it does get called can/should return an empty immutable
- * map or something
- */
- ExceptionUtil.throwGenericInternal();
- return null; // never gets here
- }
-
-}
diff -Nru libwoodstox-java-4.1.3/src/java/com/ctc/wstx/dtd/DTDValidatorBase.java libwoodstox-java-5.1.0/src/java/com/ctc/wstx/dtd/DTDValidatorBase.java
--- libwoodstox-java-4.1.3/src/java/com/ctc/wstx/dtd/DTDValidatorBase.java 2012-04-24 04:38:20.000000000 +0000
+++ libwoodstox-java-5.1.0/src/java/com/ctc/wstx/dtd/DTDValidatorBase.java 1970-01-01 00:00:00.000000000 +0000
@@ -1,531 +0,0 @@
-/* Woodstox XML processor
- *
- * Copyright (c) 2004- 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 com.ctc.wstx.dtd;
-
-import java.text.MessageFormat;
-import java.util.*;
-
-import javax.xml.stream.Location;
-import javax.xml.stream.XMLStreamException;
-
-import org.codehaus.stax2.validation.*;
-
-import com.ctc.wstx.api.WstxInputProperties;
-import com.ctc.wstx.sr.NsDefaultProvider;
-import com.ctc.wstx.sr.InputElementStack;
-import com.ctc.wstx.util.DataUtil;
-import com.ctc.wstx.util.ElementIdMap;
-import com.ctc.wstx.util.ExceptionUtil;
-import com.ctc.wstx.util.PrefixedName;
-
-/**
- * Shared abstract base class for Woodstox implementations
- * of {@link XMLValidator} for DTD validation.
- * Since there are 2 sub-types -- full actual DTD validator, and a dummy
- * one that only adds type information and default values, with no actual
- * validation -- common functionality was refactored into this base
- * class.
- */
-public abstract class DTDValidatorBase
- extends XMLValidator
- implements NsDefaultProvider // for namespace attr defaults
-{
- /*
- /////////////////////////////////////////////////////
- // Constants
- /////////////////////////////////////////////////////
- */
-
- /**
- * Estimated maximum depth of typical documents; used to allocate
- * the array for element stack
- */
- final static int DEFAULT_STACK_SIZE = 16;
-
- /**
- * Estimated maximum number of attributes for a single element
- */
- final static int EXP_MAX_ATTRS = 16;
-
- /**
- * Let's actually just reuse a local Map...
- */
- protected final static HashMap EMPTY_MAP = new HashMap();
-
- /*
- ///////////////////////////////////////
- // Configuration
- ///////////////////////////////////////
- */
-
- /**
- * Flag that indicates whether any of the elements declared has default
- * attribute values for namespace declaration pseudo-attributes.
- */
- final boolean mHasNsDefaults;
-
- /**
- * DTD schema ({@link DTDSubsetImpl}) object that created this validator
- * instance.
- */
- final DTDSubset mSchema;
-
- /**
- * Validation context (owner) for this validator. Needed for adding
- * default attribute values, for example.
- */
- final ValidationContext mContext;
-
- /**
- * Map that contains element specifications from DTD; null if no
- * DOCTYPE declaration found.
- */
- final Map mElemSpecs;
-
- /**
- * General entities defined in DTD subsets; needed for validating
- * ENTITY/ENTITIES attributes.
- */
- final Map mGeneralEntities;
-
- /**
- * Flag that indicates whether parser wants the attribute values
- * to be normalized (according to XML specs) or not (which may be
- * more efficient, although not compliant with the specs)
- */
- protected boolean mNormAttrs;
-
- /*
- ///////////////////////////////////////////
- // Element def/spec/validator stack, state
- ///////////////////////////////////////////
- */
-
- /**
- * This is the element that is currently being validated; valid
- * during
- * validateElementStart
,
- * validateAttribute
,
- * validateElementAndAttributes
calls.
- */
- protected DTDElement mCurrElem = null;
-
- /**
- * Stack of element definitions matching the current active element stack.
- * Instances are elements definitions read from DTD.
- */
- protected DTDElement[] mElems = null;
-
- /**
- * Number of elements in {@link #mElems}.
- */
- protected int mElemCount = 0;
-
- /**
- * Attribute definitions for attributes the current element may have
- */
- protected HashMap mCurrAttrDefs = null;
-
- /**
- * List of attribute declarations/specifications, one for each
- * attribute of the current element, for which there is a matching
- * value (either explicitly defined, or assigned via defaulting).
- */
- protected DTDAttribute[] mAttrSpecs = new DTDAttribute[EXP_MAX_ATTRS];
-
- /**
- * Number of attribute specification Objects in
- * {@link #mAttrSpecs}; needed to store in case type information
- * is requested later on.
- */
- protected int mAttrCount = 0;
-
- /**
- * Index of the attribute of type ID, within current element's
- * attribute list. Track of this is kept separate from other
- * attribute since id attributes often need to be used for resolving
- * cross-references.
- */
- protected int mIdAttrIndex = -1;
-
- /*
- ///////////////////////////////////////
- // Temporary helper objects
- ///////////////////////////////////////
- */
-
- protected final transient PrefixedName mTmpKey = new PrefixedName(null, null);
-
- /**
- * Temporary buffer attribute instances can share for validation
- * purposes
- */
- char[] mTmpAttrValueBuffer = null;
-
- /*
- ///////////////////////////////////////
- // Life-cycle
- ///////////////////////////////////////
- */
-
- public DTDValidatorBase(DTDSubset schema, ValidationContext ctxt, boolean hasNsDefaults,
- Map elemSpecs, Map genEntities)
- {
- mSchema = schema;
- mContext = ctxt;
- mHasNsDefaults = hasNsDefaults;
- mElemSpecs = (elemSpecs == null || elemSpecs.size() == 0) ?
- Collections.EMPTY_MAP : elemSpecs;
- mGeneralEntities = genEntities;
- // By default, let's assume attrs are to be normalized (fully xml compliant)
- mNormAttrs = true;
- mElems = new DTDElement[DEFAULT_STACK_SIZE];
- }
-
- /*
- ///////////////////////////////////////
- // Configuration
- ///////////////////////////////////////
- */
-
- /**
- * Method that allows enabling/disabling attribute value normalization.
- * In general, readers by default enable normalization (to be fully xml
- * compliant),
- * whereas writers do not (since there is usually little to gain, if
- * anything -- it is even possible value may be written before validation
- * is called in some cases)
- */
- public void setAttrValueNormalization(boolean state) {
- mNormAttrs = state;
- }
-
- /**
- * @return True for validator object that actually do validate
- * content; false for objects that only use DTD type information.
- */
- public abstract boolean reallyValidating();
-
- /*
- ///////////////////////////////////////
- // XMLValidator implementation
- ///////////////////////////////////////
- */
-
- public final XMLValidationSchema getSchema() {
- return mSchema;
- }
-
- /**
- * Method called to update information about the newly encountered (start)
- * element. At this point namespace information has been resolved, but
- * no DTD validation has been done. Validator is to do these validations,
- * including checking for attribute value (and existence) compatibility.
- */
- public abstract void validateElementStart(String localName, String uri, String prefix)
- throws XMLStreamException;
-
- public abstract String validateAttribute(String localName, String uri,
- String prefix, String value)
- throws XMLStreamException;
-
- public abstract String validateAttribute(String localName, String uri,
- String prefix,
- char[] valueChars, int valueStart,
- int valueEnd)
- throws XMLStreamException;
-
- public abstract int validateElementAndAttributes()
- throws XMLStreamException;
-
- /**
- * @return Validation state that should be effective for the parent
- * element state
- */
- public abstract int validateElementEnd(String localName, String uri, String prefix)
- throws XMLStreamException;
-
- public void validateText(String text, boolean lastTextSegment)
- throws XMLStreamException
- {
- /* This method is a NOP, since basic DTD has no mechanism for
- * validating textual content.
- */
- }
-
- public void validateText(char[] cbuf, int textStart, int textEnd,
- boolean lastTextSegment)
- throws XMLStreamException
- {
- /* This method is a NOP, since basic DTD has no mechanism for
- * validating textual content.
- */
- }
-
- public abstract void validationCompleted(boolean eod)
- throws XMLStreamException;
-
- /*
- ///////////////////////////////////////
- // Attribute info access
- ///////////////////////////////////////
- */
-
- // // // Access to type info
-
- public String getAttributeType(int index)
- {
- DTDAttribute attr = mAttrSpecs[index];
- return (attr == null) ? WstxInputProperties.UNKNOWN_ATTR_TYPE :
- attr.getValueTypeString();
- }
-
- /**
- * Method for finding out the index of the attribute (collected using
- * the attribute collector; having DTD-derived info in same order)
- * that is of type ID. DTD 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 int getIdAttrIndex()
- {
- // Let's figure out the index only when needed
- int ix = mIdAttrIndex;
- if (ix == -2) {
- ix = -1;
- if (mCurrElem != null) {
- DTDAttribute idAttr = mCurrElem.getIdAttribute();
- if (idAttr != null) {
- DTDAttribute[] attrs = mAttrSpecs;
- for (int i = 0, len = attrs.length; i < len; ++i) {
- if (attrs[i] == idAttr) {
- ix = i;
- break;
- }
- }
- }
- }
- mIdAttrIndex = ix;
- }
- return ix;
- }
-
- /**
- * Method for finding out the index of the attribute (collected using
- * the attribute collector; having DTD-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 int getNotationAttrIndex()
- {
- /* If necessary, we could find this index when resolving the
- * element, could avoid linear search. But who knows how often
- * it's really needed...
- */
- for (int i = 0, len = mAttrCount; i < len; ++i) {
- if (mAttrSpecs[i].typeIsNotation()) {
- return i;
- }
- }
- return -1;
- }
-
- /*
- /////////////////////////////////////////////////////
- // NsDefaultProvider interface
- /////////////////////////////////////////////////////
- */
-
- /**
- * Calling this method before {@link #checkNsDefaults} is necessary
- * to pass information regarding the current element; although
- * it will become available later on (via normal XMLValidator interface),
- * that's too late (after namespace binding and resolving).
- */
- public boolean mayHaveNsDefaults(String elemPrefix, String elemLN)
- {
- mTmpKey.reset(elemPrefix, elemLN);
- DTDElement elem = (DTDElement) mElemSpecs.get(mTmpKey);
- mCurrElem = elem;
- return (elem != null) && elem.hasNsDefaults();
- }
-
- public void checkNsDefaults(InputElementStack nsStack)
- throws XMLStreamException
- {
- // We only get called if mCurrElem != null, and has defaults
- HashMap m = mCurrElem.getNsDefaults();
- if (m != null) {
- Iterator it = m.entrySet().iterator();
- while (it.hasNext()) {
- Map.Entry me = (Map.Entry) it.next();
- String prefix = (String) me.getKey();
- if (!nsStack.isPrefixLocallyDeclared(prefix)) {
- DTDAttribute attr = (DTDAttribute) me.getValue();
- String uri = attr.getDefaultValue(mContext, this);
- nsStack.addNsBinding(prefix, uri);
- }
- }
- }
- }
-
- /*
- ///////////////////////////////////////
- // Package methods, accessors
- ///////////////////////////////////////
- */
-
- /**
- * Name of current element on the top of the element stack.
- */
- PrefixedName getElemName() {
- DTDElement elem = mElems[mElemCount-1];
- return elem.getName();
- }
-
- Location getLocation() {
- return mContext.getValidationLocation();
- }
-
- protected abstract ElementIdMap getIdMap();
-
- Map getEntityMap() {
- return mGeneralEntities;
- }
-
- char[] getTempAttrValueBuffer(int neededLength)
- {
- if (mTmpAttrValueBuffer == null
- || mTmpAttrValueBuffer.length < neededLength) {
- int size = (neededLength < 100) ? 100 : neededLength;
- mTmpAttrValueBuffer = new char[size];
- }
- return mTmpAttrValueBuffer;
- }
-
- public boolean hasNsDefaults() {
- return mHasNsDefaults;
- }
-
- /*
- ///////////////////////////////////////
- // Package methods, error handling
- ///////////////////////////////////////
- */
-
- /**
- * Method called to report validity problems; depending on mode, will
- * either throw an exception, or add a problem notification to the
- * list of problems.
- */
- void reportValidationProblem(String msg)
- throws XMLStreamException
- {
- doReportValidationProblem(msg, null);
- }
-
- void reportValidationProblem(String msg, Location loc)
- throws XMLStreamException
- {
- doReportValidationProblem(msg, loc);
- }
-
- void reportValidationProblem(String format, Object arg)
- throws XMLStreamException
- {
- doReportValidationProblem(MessageFormat.format(format, new Object[] { arg }),
- null);
- }
-
- void reportValidationProblem(String format, Object arg1, Object arg2)
- throws XMLStreamException
- {
- doReportValidationProblem(MessageFormat.format(format, new Object[] { arg1, arg2 }),
- null);
- }
-
- /*
- ///////////////////////////////////////
- // Private/sub-class methods
- ///////////////////////////////////////
- */
-
- protected void doReportValidationProblem(String msg, Location loc)
- throws XMLStreamException
- {
- if (loc == null) {
- loc = getLocation();
- }
- XMLValidationProblem prob = new XMLValidationProblem(loc, msg, XMLValidationProblem.SEVERITY_ERROR);
- prob.setReporter(this);
- mContext.reportProblem(prob);
- }
-
- protected void doAddDefaultValue(DTDAttribute attr)
- throws XMLStreamException
- {
- /* If we get here, we should have a non-null (possibly empty) default
- * value:
- */
- String def = attr.getDefaultValue(mContext, this);
- if (def == null) {
- ExceptionUtil.throwInternal("null default attribute value");
- }
- PrefixedName an = attr.getName();
- // Ok, do we need to find the URI?
- String prefix = an.getPrefix();
- String uri = "";
- if (prefix != null && prefix.length() > 0) {
- uri = mContext.getNamespaceURI(prefix);
- // Can not map to empty NS!
- if (uri == null || uri.length() == 0) {
- /* Hmmh. This is a weird case where we do have to
- * throw a validity exception; even though it really
- * is more a ns-well-formedness error...
- */
- reportValidationProblem("Unbound namespace prefix \"{0}\" for default attribute \"{1}\"", prefix, attr);
- // May continue if we don't throw errors, just collect them to a list
- uri = "";
- }
- }
- int defIx = mContext.addDefaultAttribute(an.getLocalName(), uri, prefix, def);
- if (defIx < 0) {
- /* 13-Dec-2005, Tatus: Hmmh. For readers this is an error
- * condition, but writers may just indicate they are not
- * interested in defaults. So let's let context report
- * problem(s) if it has any regarding the request.
- */
- // nop
- } else {
- while (defIx >= mAttrSpecs.length) {
- mAttrSpecs = (DTDAttribute[]) DataUtil.growArrayBy50Pct(mAttrSpecs);
- }
- /* Any intervening empty slots? (can happen if other
- * validators add default attributes...)
- */
- while (mAttrCount < defIx) {
- mAttrSpecs[mAttrCount++] = null;
- }
- mAttrSpecs[defIx] = attr;
- mAttrCount = defIx+1;
- }
- }
-}
diff -Nru libwoodstox-java-4.1.3/src/java/com/ctc/wstx/dtd/DTDValidator.java libwoodstox-java-5.1.0/src/java/com/ctc/wstx/dtd/DTDValidator.java
--- libwoodstox-java-4.1.3/src/java/com/ctc/wstx/dtd/DTDValidator.java 2012-04-24 04:38:20.000000000 +0000
+++ libwoodstox-java-5.1.0/src/java/com/ctc/wstx/dtd/DTDValidator.java 1970-01-01 00:00:00.000000000 +0000
@@ -1,406 +0,0 @@
-/* Woodstox XML processor
- *
- * Copyright (c) 2004- 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 com.ctc.wstx.dtd;
-
-import java.util.*;
-
-import javax.xml.stream.XMLStreamException;
-
-import org.codehaus.stax2.validation.*;
-
-import com.ctc.wstx.cfg.ErrorConsts;
-import com.ctc.wstx.util.DataUtil;
-import com.ctc.wstx.util.ElementId;
-import com.ctc.wstx.util.ElementIdMap;
-import com.ctc.wstx.util.StringUtil;
-
-/**
- * Woodstox implementation of {@link XMLValidator}; the class that
- * handles DTD-based validation.
- */
-public class DTDValidator
- extends DTDValidatorBase
-{
- /*
- ///////////////////////////////////////
- // Configuration
- ///////////////////////////////////////
- */
-
- /**
- * Determines if identical problems (definition of the same element,
- * for example) should cause multiple error notifications or not:
- * if true, will get one error per instance, if false, only the first
- * one will get reported.
- */
- protected boolean mReportDuplicateErrors = false;
-
- /*
- ///////////////////////////////////////
- // Id/idref state
- ///////////////////////////////////////
- */
-
- /**
- * Information about declared and referenced element ids (unique
- * ids that attributes may defined, as defined by DTD)
- */
- protected ElementIdMap mIdMap = null;
-
- /*
- ///////////////////////////////////////////
- // Element def/spec/validator stack, state
- ///////////////////////////////////////////
- */
-
- /**
- * Stack of validators for open elements
- */
- protected StructValidator[] mValidators = null;
-
- /**
- * Bitset used for keeping track of required and defaulted attributes
- * for which values have been found.
- */
- protected BitSet mCurrSpecialAttrs = null;
-
- boolean mCurrHasAnyFixed = false;
-
- /*
- ///////////////////////////////////////
- // Temporary helper objects
- ///////////////////////////////////////
- */
-
- /**
- * Reusable lazily instantiated BitSet; needed to keep track of
- * missing 'special' attributes (required ones, ones with default
- * values)
- */
- BitSet mTmpSpecialAttrs;
-
- /*
- ///////////////////////////////////////
- // Life-cycle
- ///////////////////////////////////////
- */
-
- public DTDValidator(DTDSubset schema, ValidationContext ctxt, boolean hasNsDefaults,
- Map elemSpecs, Map genEntities)
- {
- super(schema, ctxt, hasNsDefaults, elemSpecs, genEntities);
- mValidators = new StructValidator[DEFAULT_STACK_SIZE];
- }
-
- public final boolean reallyValidating() { return true; }
-
- /*
- ///////////////////////////////////////
- // XMLValidator implementation
- ///////////////////////////////////////
- */
-
- //public XMLValidationSchema getSchema();
-
- /**
- * Method called to update information about the newly encountered (start)
- * element. At this point namespace information has been resolved, but
- * no DTD validation has been done. Validator is to do these validations,
- * including checking for attribute value (and existence) compatibility.
- */
- public void validateElementStart(String localName, String uri, String prefix)
- throws XMLStreamException
- {
- /* Ok, need to find the element definition; if not found (or
- * only implicitly defined), need to throw the exception.
- */
- mTmpKey.reset(prefix, localName);
-
- DTDElement elem = (DTDElement) mElemSpecs.get(mTmpKey);
-
- /* Let's add the entry in (even if it's a null); this is necessary
- * to keep things in-sync if allowing graceful handling of validity
- * errors
- */
- int elemCount = mElemCount++;
- if (elemCount >= mElems.length) {
- mElems = (DTDElement[]) DataUtil.growArrayBy50Pct(mElems);
- mValidators = (StructValidator[]) DataUtil.growArrayBy50Pct(mValidators);
- }
- mElems[elemCount] = mCurrElem = elem;
- if (elem == null || !elem.isDefined()) {
- reportValidationProblem(ErrorConsts.ERR_VLD_UNKNOWN_ELEM, mTmpKey.toString());
- }
-
- // Is this element legal under the parent element?
- StructValidator pv = (elemCount > 0) ? mValidators[elemCount-1] : null;
-
- if (pv != null && elem != null) {
- String msg = pv.tryToValidate(elem.getName());
- if (msg != null) {
- int ix = msg.indexOf("$END");
- String pname = mElems[elemCount-1].toString();
- if (ix >= 0) {
- msg = msg.substring(0, ix) + ""+pname+">"
- +msg.substring(ix+4);
- }
- reportValidationProblem("Validation error, encountered element <"
- +elem.getName()+"> as a child of <"
- +pname+">: "+msg);
- }
- }
-
- mAttrCount = 0;
- mIdAttrIndex = -2; // -2 as a "don't know yet" marker
-
- // Ok, need to get the child validator, then:
- if (elem == null) {
- mValidators[elemCount] = null;
- mCurrAttrDefs = EMPTY_MAP;
- mCurrHasAnyFixed = false;
- mCurrSpecialAttrs = null;
- } else {
- mValidators[elemCount] = elem.getValidator();
- mCurrAttrDefs = elem.getAttributes();
- if (mCurrAttrDefs == null) {
- mCurrAttrDefs = EMPTY_MAP;
- }
- mCurrHasAnyFixed = elem.hasFixedAttrs();
- int specCount = elem.getSpecialCount();
- if (specCount == 0) {
- mCurrSpecialAttrs = null;
- } else {
- BitSet bs = mTmpSpecialAttrs;
- if (bs == null) {
- mTmpSpecialAttrs = bs = new BitSet(specCount);
- } else {
- bs.clear();
- }
- mCurrSpecialAttrs = bs;
- }
- }
- }
-
- public String validateAttribute(String localName, String uri,
- String prefix, String value)
- throws XMLStreamException
- {
- DTDAttribute attr = (DTDAttribute) mCurrAttrDefs.get(mTmpKey.reset(prefix, localName));
- if (attr == null) {
- // Only report error if not already covering from an error:
- if (mCurrElem != null) {
- reportValidationProblem(ErrorConsts.ERR_VLD_UNKNOWN_ATTR,
- mCurrElem.toString(), mTmpKey.toString());
- }
- /* [WSTX-190] NPE if we continued (after reported didn't
- * throw an exception); nothing more to do, let's leave
- */
- return value;
- }
- int index = mAttrCount++;
- if (index >= mAttrSpecs.length) {
- mAttrSpecs = (DTDAttribute[]) DataUtil.growArrayBy50Pct(mAttrSpecs);
- }
- mAttrSpecs[index] = attr;
- if (mCurrSpecialAttrs != null) { // Need to mark that we got it
- int specIndex = attr.getSpecialIndex();
- if (specIndex >= 0) {
- mCurrSpecialAttrs.set(specIndex);
- }
- }
- String result = attr.validate(this, value, mNormAttrs);
- if (mCurrHasAnyFixed && attr.isFixed()) {
- String act = (result == null) ? value : result;
- String exp = attr.getDefaultValue(mContext, this);
- if (!act.equals(exp)) {
- reportValidationProblem("Value of attribute \""+attr+"\" (element <"+mCurrElem+">) not \""+exp+"\" as expected, but \""+act+"\"");
- }
- }
- return result;
- }
-
- public String validateAttribute(String localName, String uri,
- String prefix,
- char[] valueChars, int valueStart,
- int valueEnd)
- throws XMLStreamException
- {
- DTDAttribute attr = (DTDAttribute) mCurrAttrDefs.get(mTmpKey.reset(prefix, localName));
- if (attr == null) {
- // Only report error if not already covering from an error:
- if (mCurrElem != null) {
- reportValidationProblem(ErrorConsts.ERR_VLD_UNKNOWN_ATTR,
- mCurrElem.toString(), mTmpKey.toString());
- }
- /* [WSTX-190] NPE if we continued (after reported didn't
- * throw an exception); nothing more to do, let's leave
- */
- return new String(valueChars, valueStart, valueEnd);
- }
- int index = mAttrCount++;
- if (index >= mAttrSpecs.length) {
- mAttrSpecs = (DTDAttribute[]) DataUtil.growArrayBy50Pct(mAttrSpecs);
- }
- mAttrSpecs[index] = attr;
- if (mCurrSpecialAttrs != null) { // Need to mark that we got it
- int specIndex = attr.getSpecialIndex();
- if (specIndex >= 0) {
- mCurrSpecialAttrs.set(specIndex);
- }
- }
- String result = attr.validate(this, valueChars, valueStart, valueEnd, mNormAttrs);
- if (mCurrHasAnyFixed && attr.isFixed()) {
- String exp = attr.getDefaultValue(mContext, this);
- boolean match;
- if (result == null) {
- match = StringUtil.matches(exp, valueChars, valueStart, valueEnd - valueStart);
- } else {
- match = exp.equals(result);
- }
- if (!match) {
- String act = (result == null) ?
- new String(valueChars, valueStart, valueEnd) : result;
- reportValidationProblem("Value of #FIXED attribute \""+attr+"\" (element <"+mCurrElem+">) not \""+exp+"\" as expected, but \""+act+"\"");
- }
- }
- return result;
- }
-
- public int validateElementAndAttributes()
- throws XMLStreamException
- {
- // Ok: are we fine with the attributes?
- DTDElement elem = mCurrElem;
- if (elem == null) { // had an error, most likely no such element defined...
- // need to just return, nothing to do here
- return XMLValidator.CONTENT_ALLOW_ANY_TEXT;
- }
-
- // Any special attributes missing?
- if (mCurrSpecialAttrs != null) {
- BitSet specBits = mCurrSpecialAttrs;
- int specCount = elem.getSpecialCount();
- int ix = specBits.nextClearBit(0);
- while (ix < specCount) { // something amiss!
- List specAttrs = elem.getSpecialAttrs();
- DTDAttribute attr = (DTDAttribute) specAttrs.get(ix);
-
- /* [WSTX-155]: Problems if reportValidationProblem returns
- * ok (which happens if a reporter handles it). So what
- * to do with missing required value? First thought is
- * to just leave it as is.
- */
- if (attr.isRequired()) {
- reportValidationProblem("Required attribute \"{0}\" missing from element <{1}>", attr, elem);
- } else {
- doAddDefaultValue(attr);
- }
- ix = specBits.nextClearBit(ix+1);
- }
- }
-
- return elem.getAllowedContent();
- }
-
- /**
- * @return Validation state that should be effective for the parent
- * element state
- */
- public int validateElementEnd(String localName, String uri, String prefix)
- throws XMLStreamException
- {
- // First, let's remove the top:
- int ix = mElemCount-1;
- /* [WSTX-200]: need to avoid problems when doing sub-tree
- * validation...
- */
- if (ix < 0) {
- return XMLValidator.CONTENT_ALLOW_WS;
- }
- mElemCount = ix;
-
- DTDElement closingElem = mElems[ix];
- mElems[ix] = null;
- StructValidator v = mValidators[ix];
- mValidators[ix] = null;
-
- // Validation?
- if (v != null) {
- String msg = v.fullyValid();
- if (msg != null) {
- reportValidationProblem("Validation error, element "
- +closingElem+">: "+msg);
- }
- }
-
- // Then let's get info from parent, if any
- if (ix < 1) { // root element closing..
- // doesn't really matter; epilog/prolog differently handled:
- return XMLValidator.CONTENT_ALLOW_WS;
- }
- return mElems[ix-1].getAllowedContent();
- }
-
- //public void validateText(String text, boolean lastTextSegment) ;
- //public void validateText(char[] cbuf, int textStart, int textEnd, boolean lastTextSegment) ;
-
- public void validationCompleted(boolean eod)
- throws XMLStreamException
- {
- /* Need to now ensure that all IDREF/IDREFS references
- * point to defined ID attributes
- */
- checkIdRefs();
- }
-
- /*
- ///////////////////////////////////////
- // Package methods, accessors
- ///////////////////////////////////////
- */
-
- protected ElementIdMap getIdMap() {
- if (mIdMap == null) {
- mIdMap = new ElementIdMap();
- }
- return mIdMap;
- }
-
- /*
- ///////////////////////////////////////
- // Internal methods
- ///////////////////////////////////////
- */
-
- protected void checkIdRefs()
- throws XMLStreamException
- {
- /* 02-Oct-2004, TSa: Now we can also check that all id references
- * pointed to ids that actually are defined
- */
- if (mIdMap != null) {
- ElementId ref = mIdMap.getFirstUndefined();
- if (ref != null) { // problem!
- reportValidationProblem("Undefined id '"+ref.getId()
- +"': referenced from element <"
- +ref.getElemName()+">, attribute '"
- +ref.getAttrName()+"'",
- ref.getLocation());
- }
- }
- }
-
-}
diff -Nru libwoodstox-java-4.1.3/src/java/com/ctc/wstx/dtd/DTDWriter.java libwoodstox-java-5.1.0/src/java/com/ctc/wstx/dtd/DTDWriter.java
--- libwoodstox-java-4.1.3/src/java/com/ctc/wstx/dtd/DTDWriter.java 2012-04-24 04:38:20.000000000 +0000
+++ libwoodstox-java-5.1.0/src/java/com/ctc/wstx/dtd/DTDWriter.java 1970-01-01 00:00:00.000000000 +0000
@@ -1,164 +0,0 @@
-package com.ctc.wstx.dtd;
-
-import java.io.IOException;
-import java.io.Writer;
-
-import javax.xml.stream.XMLStreamException;
-
-import com.ctc.wstx.exc.WstxIOException;
-
-/**
- * Simple utility class used by {@link DTDReader} when writing out
- * flattened external DTD subset file. Writing functionality encapsulated
- * here since it's specific to one mode of operation (flattening).
- *
- * Note, too, that underlying {@link IOException}s are generally wrapped
- * as {@link XMLStreamException}s. This is needed to reduce amount of
- * work caller has to do for wrapping. It will still be possible to
- * unwrap these exceptions further up the call stack if need be.
- */
-final class DTDWriter
-{
- /*
- //////////////////////////////////////////////////
- // Configuration
- //////////////////////////////////////////////////
- */
-
- final Writer mWriter;
-
- final boolean mIncludeComments;
-
- final boolean mIncludeConditionals;
-
- final boolean mIncludePEs;
-
- /*
- //////////////////////////////////////////////////
- // Output status
- //////////////////////////////////////////////////
- */
-
- /**
- * Counter that indicates whether flattened output should be written to
- * (non-null) mWriter; values above zero indicate output is enabled,
- * zero and below that output is disabled.
- * Only enabled if mWriter is not
- * null; will be temporarily disabled during processing of content
- * that is not to be included (PE reference; or comments / conditional
- * sections if comment/cs output is suppressed)
- */
- int mIsFlattening = 0;
-
- /**
- * Pointer to first character in the current input buffer that
- * has not yet been written to flatten writer.
- */
- int mFlattenStart = 0;
-
- /*
- //////////////////////////////////////////////////
- // Life-cycle
- //////////////////////////////////////////////////
- */
-
- public DTDWriter(Writer out, boolean inclComments, boolean inclCond,
- boolean inclPEs)
- {
- mWriter = out;
- mIncludeComments = inclComments;
- mIncludeConditionals = inclCond;
- mIncludePEs = inclPEs;
-
- mIsFlattening = 1; // starts enabled
- }
-
- /*
- //////////////////////////////////////////////////
- // Public API, accessors, state change
- //////////////////////////////////////////////////
- */
-
- public boolean includeComments() {
- return mIncludeComments;
- }
-
- public boolean includeConditionals() {
- return mIncludeConditionals;
- }
-
- public boolean includeParamEntities() {
- return mIncludePEs;
- }
-
- public void disableOutput()
- {
- --mIsFlattening;
- }
-
- public void enableOutput(int newStart)
- {
- ++mIsFlattening;
- mFlattenStart = newStart;
- }
-
- public void setFlattenStart(int ptr) {
- mFlattenStart = ptr;
- }
-
- public int getFlattenStart() {
- return mFlattenStart;
- }
-
- /*
- //////////////////////////////////////////////////
- // Public API, output methods:
- //////////////////////////////////////////////////
- */
-
- public void flush(char[] buf, int upUntil)
- throws XMLStreamException
- {
- if (mFlattenStart < upUntil) {
- if (mIsFlattening > 0) {
- try {
- mWriter.write(buf, mFlattenStart, upUntil - mFlattenStart);
- } catch (IOException ioe) {
- throw new WstxIOException(ioe);
- }
- }
- mFlattenStart = upUntil;
- }
- }
-
- /**
- * Method called when explicit output has to be done for flatten output:
- * this is usually done when there's need to do speculative checks
- * before it's known if some chars are output (when suppressing comments
- * or conditional sections)
- */
- public void output(String output)
- throws XMLStreamException
- {
- if (mIsFlattening > 0) {
- try {
- mWriter.write(output);
- } catch (IOException ioe) {
- throw new WstxIOException(ioe);
- }
- }
- }
-
- public void output(char c)
- throws XMLStreamException
- {
- if (mIsFlattening > 0) {
- try {
- mWriter.write(c);
- } catch (IOException ioe) {
- throw new WstxIOException(ioe);
- }
- }
- }
-}
-
diff -Nru libwoodstox-java-4.1.3/src/java/com/ctc/wstx/dtd/EmptyValidator.java libwoodstox-java-5.1.0/src/java/com/ctc/wstx/dtd/EmptyValidator.java
--- libwoodstox-java-4.1.3/src/java/com/ctc/wstx/dtd/EmptyValidator.java 2012-04-24 04:38:20.000000000 +0000
+++ libwoodstox-java-5.1.0/src/java/com/ctc/wstx/dtd/EmptyValidator.java 1970-01-01 00:00:00.000000000 +0000
@@ -1,48 +0,0 @@
-package com.ctc.wstx.dtd;
-
-import com.ctc.wstx.util.PrefixedName;
-
-/**
- * Simple content model validator that accepts no elements, ever; this
- * is true for pure #PCDATA content model as well as EMPTY content model.
- * Can be used as a singleton, since all info needed for diagnostics
- * is passed via methods.
- */
-public class EmptyValidator
- extends StructValidator
-{
- final static EmptyValidator sPcdataInstance = new EmptyValidator("No elements allowed in pure #PCDATA content model");
-
- final static EmptyValidator sEmptyInstance = new EmptyValidator("No elements allowed in EMPTY content model");
-
- final String mErrorMsg;
-
- private EmptyValidator(String errorMsg) {
- mErrorMsg = errorMsg;
- }
-
- public static EmptyValidator getPcdataInstance() { return sPcdataInstance; }
- public static EmptyValidator getEmptyInstance() { return sPcdataInstance; }
-
- /**
- * Simple; can always (re)use instance itself; no state information
- * is kept.
- */
- public StructValidator newInstance() {
- return this;
- }
-
- public String tryToValidate(PrefixedName elemName)
- {
- return mErrorMsg;
- }
-
- /**
- * If we ever get as far as element closing, things are all good;
- * can just return null.
- */
- public String fullyValid()
- {
- return null;
- }
-}
diff -Nru libwoodstox-java-4.1.3/src/java/com/ctc/wstx/dtd/FullDTDReader.java libwoodstox-java-5.1.0/src/java/com/ctc/wstx/dtd/FullDTDReader.java
--- libwoodstox-java-4.1.3/src/java/com/ctc/wstx/dtd/FullDTDReader.java 2012-04-24 04:38:20.000000000 +0000
+++ libwoodstox-java-5.1.0/src/java/com/ctc/wstx/dtd/FullDTDReader.java 1970-01-01 00:00:00.000000000 +0000
@@ -1,3499 +0,0 @@
-/* Woodstox XML processor
- *
- * Copyright (c) 2004- 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 com.ctc.wstx.dtd;
-
-import java.io.IOException;
-import java.io.Writer;
-import java.net.URL;
-import java.text.MessageFormat;
-import java.util.*;
-
-import javax.xml.stream.Location;
-import javax.xml.stream.XMLReporter;
-import javax.xml.stream.XMLStreamException;
-import javax.xml.stream.events.NotationDeclaration;
-
-import org.codehaus.stax2.validation.XMLValidationProblem;
-import org.codehaus.stax2.validation.XMLValidator;
-
-import com.ctc.wstx.api.ReaderConfig;
-import com.ctc.wstx.cfg.ErrorConsts;
-import com.ctc.wstx.cfg.XmlConsts;
-import com.ctc.wstx.ent.*;
-import com.ctc.wstx.evt.WNotationDeclaration;
-import com.ctc.wstx.io.WstxInputData;
-import com.ctc.wstx.io.WstxInputSource;
-import com.ctc.wstx.util.*;
-
-/**
- * Reader that reads in DTD information from internal or external subset.
- *
- * There are 2 main modes for DTDReader, depending on whether it is parsing
- * internal or external subset. Parsing of internal subset is somewhat
- * simpler, since no dependency checking is needed. For external subset,
- * handling of parameter entities is bit more complicated, as care has to
- * be taken to distinguish between using PEs defined in int. subset, and
- * ones defined in ext. subset itself. This determines cachability of
- * external subsets.
- *
- * Reader also implements simple stand-alone functionality for flattening
- * DTD files (expanding all references to their eventual textual form);
- * this is sometimes useful when optimizing modularized DTDs
- * (which are more maintainable) into single monolithic DTDs (which in
- * general can be more performant).
- *
- * @author Tatu Saloranta
- */
-public class FullDTDReader
- extends MinimalDTDReader
-{
- /**
- * Flag that can be changed to enable or disable interning of shared
- * names; shared names are used for enumerated values to reduce
- * memory usage.
- */
- final static boolean INTERN_SHARED_NAMES = false;
-
- // // // Entity expansion types:
-
- final static Boolean ENTITY_EXP_GE = Boolean.FALSE;
-
- final static Boolean ENTITY_EXP_PE = Boolean.TRUE;
-
- /*
- //////////////////////////////////////////////////
- // Configuration
- //////////////////////////////////////////////////
- */
-
- final int mConfigFlags;
-
- // Extracted wstx-specific settings:
-
- final boolean mCfgSupportDTDPP;
-
- /**
- * This flag indicates whether we should build a validating 'real'
- * validator (true, the usual case),
- * or a simpler pseudo-validator that can do all non-validation tasks
- * that are based on DTD info (entity expansion, notation references,
- * default attribute values). Latter is used in non-validating mode.
- *
- */
- final boolean mCfgFullyValidating;
-
- /*
- //////////////////////////////////////////////////
- // Entity handling, parameter entities (PEs)
- //////////////////////////////////////////////////
- */
-
- /**
- * Set of parameter entities defined so far in the currently parsed
- * subset. Note: the first definition sticks, entities can not be
- * redefined.
- *
- * Keys are entity name Strings; values are instances of EntityDecl
- */
- HashMap mParamEntities;
-
- /**
- * Set of parameter entities already defined for the subset being
- * parsed; namely, PEs defined in the internal subset passed when
- * parsing matching external subset. Null when parsing internal
- * subset.
- */
- final HashMap mPredefdPEs;
-
- /**
- * Set of parameter entities (ids) that have been referenced by this
- * DTD; only maintained for external subsets, and only as long as
- * no pre-defined PE has been referenced.
- */
- Set mRefdPEs;
-
- /*
- //////////////////////////////////////////////////
- // Entity handling, general entities (GEs)
- //////////////////////////////////////////////////
- */
-
- /**
- * Set of generic entities defined so far in this subset.
- * As with parameter entities, the first definition sticks.
- *
- * Keys are entity name Strings; values are instances of EntityDecl
- *
- * Note: this Map only contains entities declared and defined in the
- * subset being parsed; no previously defined values are passed.
- */
- HashMap mGeneralEntities;
-
- /**
- * Set of general entities already defined for the subset being
- * parsed; namely, PEs defined in the internal subset passed when
- * parsing matching external subset. Null when parsing internal
- * subset. Such entities are only needed directly for one purpose;
- * to be expanded when reading attribute default value definitions.
- */
- final HashMap mPredefdGEs;
-
- /**
- * Set of general entities (ids) that have been referenced by this
- * DTD; only maintained for external subsets, and only as long as
- * no pre-defined GEs have been referenced.
- */
- Set mRefdGEs;
-
- /*
- //////////////////////////////////////////////////
- // Entity handling, both PEs and GEs
- //////////////////////////////////////////////////
- */
-
- /**
- * Flag used to keep track of whether current (external) subset
- * has referenced at least one PE that was pre-defined.
- */
- boolean mUsesPredefdEntities = false;
-
- /*
- //////////////////////////////////////////////////
- // Notation settings
- //////////////////////////////////////////////////
- */
-
- /**
- * Set of notations defined so far. Since it's illegal to (try to)
- * redefine notations, there's no specific precedence.
- *
- * Keys are entity name Strings; values are instances of
- * NotationDecl objects
- */
- HashMap/**/ mNotations;
-
- /**
- * Notations already parsed before current subset; that is,
- * notations from the internal subset if we are currently
- * parsing matching external subset.
- */
- final HashMap/**/ mPredefdNotations;
-
- /**
- * Flag used to keep track of whether current (external) subset
- * has referenced at least one notation that was defined in internal
- * subset. If so, can not cache the external subset
- */
- boolean mUsesPredefdNotations = false;
-
- /**
- * Finally, we need to keep track of Notation references that were
- * made prior to declaration. This is needed to ensure that all
- * references can be properly resolved.
- */
- HashMap/**/ mNotationForwardRefs;
-
- /*
- //////////////////////////////////////////////////
- // Element specifications
- //////////////////////////////////////////////////
- */
-
- /**
- * Map used to shared PrefixedName instances, to reduce memory usage
- * of (qualified) element and attribute names
- */
- HashMap mSharedNames = null;
-
- /**
- * Contains definition of elements and matching content specifications.
- * Also contains temporary placeholders for elements that are indirectly
- * "created" by ATTLIST declarations that precede actual declaration
- * for the ELEMENT referred to.
- */
- HashMap mElements;
-
- /**
- * Map used for sharing legal enumeration values; used since oftentimes
- * same enumeration values are used with multiple attributes
- */
- HashMap mSharedEnumValues = null;
-
- /*
- //////////////////////////////////////////////////
- // Entity expansion state:
- //////////////////////////////////////////////////
- */
-
- /**
- * This is the attribute default value that is currently being parsed.
- * Needs to be a global member due to the way entity expansion failures
- * are reported: problems need to be attached to this object, even
- * thought the default value itself will not be passed through.
- */
- DefaultAttrValue mCurrAttrDefault = null;
-
- /**
- * Flag that indicates if the currently expanding (or last expanded)
- * entity is a Parameter Entity or General Entity.
- */
- boolean mExpandingPE = false;
-
- /**
- * Text buffer used for constructing expansion value of the internal
- * entities, and for default attribute values.
- * Lazily constructed when needed, reused.
- */
- TextBuffer mValueBuffer = null;
-
- /*
- //////////////////////////////////////////////////
- // Reader state
- //////////////////////////////////////////////////
- */
-
- /**
- * Nesting count for conditionally included sections; 0 means that
- * we are not inside such a section. Note that condition ignore is
- * handled separately.
- */
- int mIncludeCount = 0;
-
- /**
- * This flag is used to catch uses of PEs in the internal subset
- * within declarations (full declarations are ok, but not other types)
- */
- boolean mCheckForbiddenPEs = false;
-
- /**
- * Keyword of the declaration being currently parsed (if any). Can be
- * used for error reporting purposes.
- */
- String mCurrDeclaration;
-
- /*
- //////////////////////////////////////////////////
- // DTD++ support information
- //////////////////////////////////////////////////
- */
-
- /**
- * Flag that indicates if any DTD++ features have been encountered
- * (in DTD++-supporting mode).
- */
- boolean mAnyDTDppFeatures = false;
-
- /**
- * Currently active default namespace URI.
- */
- String mDefaultNsURI = "";
-
- /**
- * Prefix-to-NsURI mappings for this DTD, if any: lazily
- * constructed when needed
- */
- HashMap mNamespaces = null;
-
- /*
- //////////////////////////////////////////////////
- // Additional support for creating expanded output
- // of processed DTD.
- //////////////////////////////////////////////////
- */
-
- DTDWriter mFlattenWriter = null;
-
- /*
- //////////////////////////////////////////////////
- // Support for SAX API impl:
- //////////////////////////////////////////////////
- */
-
- final DTDEventListener mEventListener;
-
- transient TextBuffer mTextBuffer = null;
-
- /*
- //////////////////////////////////////////////////
- // Life-cycle
- //////////////////////////////////////////////////
- */
-
- /**
- * Constructor used for reading/skipping internal subset.
- */
- private FullDTDReader(WstxInputSource input, ReaderConfig cfg,
- boolean constructFully, int xmlVersion)
- {
- this(input, cfg, false, null, constructFully, xmlVersion);
- }
-
- /**
- * Constructor used for reading external subset.
- */
- private FullDTDReader(WstxInputSource input, ReaderConfig cfg,
- DTDSubset intSubset,
- boolean constructFully, int xmlVersion)
- {
- this(input, cfg, true, intSubset, constructFully, xmlVersion);
-
- // Let's make sure line/col offsets are correct...
- input.initInputLocation(this, mCurrDepth);
- }
-
- /**
- * Common initialization part of int/ext subset constructors.
- */
- private FullDTDReader(WstxInputSource input, ReaderConfig cfg,
- boolean isExt, DTDSubset intSubset,
- boolean constructFully, int xmlVersion)
- {
- super(input, cfg, isExt);
- /* What matters here is what the main xml doc had; that determines
- * xml conformance level to use.
- */
- mDocXmlVersion = xmlVersion;
- mXml11 = cfg.isXml11();
- int cfgFlags = cfg.getConfigFlags();
- mConfigFlags = cfgFlags;
- mCfgSupportDTDPP = (cfgFlags & CFG_SUPPORT_DTDPP) != 0;
- mCfgFullyValidating = constructFully;
-
- mUsesPredefdEntities = false;
- mParamEntities = null;
- mRefdPEs = null;
- mRefdGEs = null;
- mGeneralEntities = null;
-
- // Did we get any existing parameter entities?
- HashMap pes = (intSubset == null) ?
- null : intSubset.getParameterEntityMap();
- if (pes == null || pes.isEmpty()) {
- mPredefdPEs = null;
- } else {
- mPredefdPEs = pes;
- }
-
- // How about general entities (needed only for attr. def. values)
- HashMap ges = (intSubset == null) ?
- null : intSubset.getGeneralEntityMap();
- if (ges == null || ges.isEmpty()) {
- mPredefdGEs = null;
- } else {
- mPredefdGEs = ges;
- }
-
- // And finally, notations
- HashMap not = (intSubset == null) ?
- null : intSubset.getNotationMap();
- if (not == null || not.isEmpty()) {
- mPredefdNotations = null;
- } else {
- mPredefdNotations = not;
- }
- mEventListener = mConfig.getDTDEventListener();
- }
-
- /**
- * Method called to read in the internal subset definition.
- */
- public static DTDSubset readInternalSubset(WstxInputData srcData,
- WstxInputSource input,
- ReaderConfig cfg,
- boolean constructFully,
- int xmlVersion)
- throws XMLStreamException
- {
- FullDTDReader r = new FullDTDReader(input, cfg, constructFully, xmlVersion);
- // Need to read using the same low-level reader interface:
- r.copyBufferStateFrom(srcData);
- DTDSubset ss;
-
- try {
- ss = r.parseDTD();
- } finally {
- /* And then need to restore changes back to owner (line nrs etc);
- * effectively means that we'll stop reading external DTD subset,
- * if so.
- */
- srcData.copyBufferStateFrom(r);
- }
- return ss;
- }
-
- /**
- * Method called to read in the external subset definition.
- */
- public static DTDSubset readExternalSubset
- (WstxInputSource src, ReaderConfig cfg, DTDSubset intSubset,
- boolean constructFully, int xmlVersion)
- throws XMLStreamException
- {
- FullDTDReader r = new FullDTDReader(src, cfg, intSubset, constructFully, xmlVersion);
- return r.parseDTD();
- }
-
- /**
- * Method that will parse, process and output contents of an external
- * DTD subset. It will do processing similar to
- * {@link #readExternalSubset}, but additionally will copy its processed
- * ("flattened") input to specified writer.
- *
- * @param src Input source used to read the main external subset
- * @param flattenWriter Writer to output processed DTD content to
- * @param inclComments If true, will pass comments to the writer; if false,
- * will strip comments out
- * @param inclConditionals If true, will include conditional block markers,
- * as well as intervening content; if false, will strip out both markers
- * and ignorable sections.
- * @param inclPEs If true, will output parameter entity declarations; if
- * false will parse and use them, but not output.
- */
- public static DTDSubset flattenExternalSubset(WstxInputSource src, Writer flattenWriter,
- boolean inclComments, boolean inclConditionals,
- boolean inclPEs)
- throws IOException, XMLStreamException
- {
- ReaderConfig cfg = ReaderConfig.createFullDefaults();
- // Need to create a non-shared copy to populate symbol table field
- cfg = cfg.createNonShared(new SymbolTable());
-
- /* Let's assume xml 1.0... can be taken as an arg later on, if we
- * truly care.
- */
- FullDTDReader r = new FullDTDReader(src, cfg, null, true, XmlConsts.XML_V_UNKNOWN);
- r.setFlattenWriter(flattenWriter, inclComments, inclConditionals,
- inclPEs);
- DTDSubset ss = r.parseDTD();
- r.flushFlattenWriter();
- flattenWriter.flush();
- return ss;
- }
-
- private TextBuffer getTextBuffer()
- {
- if (mTextBuffer == null) {
- mTextBuffer = TextBuffer.createTemporaryBuffer();
- mTextBuffer.resetInitialized();
- } else {
- mTextBuffer.resetWithEmpty();
- }
- return mTextBuffer;
- }
-
- /*
- //////////////////////////////////////////////////
- // Configuration
- //////////////////////////////////////////////////
- */
-
- /**
- * Method that will set specified Writer as the 'flattening writer';
- * writer used to output flattened version of DTD read in. This is
- * similar to running a C-preprocessor on C-sources, except that
- * defining writer will not prevent normal parsing of DTD itself.
- */
- public void setFlattenWriter(Writer w, boolean inclComments,
- boolean inclConditionals, boolean inclPEs)
- {
- mFlattenWriter = new DTDWriter(w, inclComments, inclConditionals,
- inclPEs);
- }
-
- private void flushFlattenWriter()
- throws XMLStreamException
- {
- mFlattenWriter.flush(mInputBuffer, mInputPtr);
- }
-
- /*
- //////////////////////////////////////////////////
- // Internal API
- //////////////////////////////////////////////////
- */
-
- /**
- * Method that may need to be called by attribute default value
- * validation code, during parsing....
- *
- * Note: see base class for some additional remarks about this
- * method.
- */
- public EntityDecl findEntity(String entName)
- {
- if (mPredefdGEs != null) {
- EntityDecl decl = (EntityDecl) mPredefdGEs.get(entName);
- if (decl != null) {
- return decl;
- }
- }
- return (EntityDecl) mGeneralEntities.get(entName);
- }
-
- /*
- //////////////////////////////////////////////////
- // Main-level parsing methods
- //////////////////////////////////////////////////
- */
-
- protected DTDSubset parseDTD()
- throws XMLStreamException
- {
- while (true) {
- mCheckForbiddenPEs = false; // PEs are ok at this point
- int i = getNextAfterWS();
- if (i < 0) {
- if (mIsExternal) { // ok for external DTDs
- break;
- }
- // Error for internal subset
- throwUnexpectedEOF(SUFFIX_IN_DTD_INTERNAL);
- }
- if (i == '%') { // parameter entity
- expandPE();
- continue;
- }
-
- /* First, let's keep track of start of the directive; needed for
- * entity and notation declaration events.
- */
- mTokenInputTotal = mCurrInputProcessed + mInputPtr;
- mTokenInputRow = mCurrInputRow;
- mTokenInputCol = mInputPtr - mCurrInputRowStart;
-
- if (i == '<') {
- // PEs not allowed within declarations, in the internal subset proper
- mCheckForbiddenPEs = !mIsExternal && (mInput == mRootInput);
- if (mFlattenWriter == null) {
- parseDirective();
- } else {
- parseDirectiveFlattened();
- }
- continue;
- }
-
- if (i == ']') {
- if (mIncludeCount == 0 && !mIsExternal) { // End of internal subset
- break;
- }
- if (mIncludeCount > 0) { // active INCLUDE block(s) open?
- boolean suppress = (mFlattenWriter != null) && !mFlattenWriter.includeConditionals();
-
- if (suppress) {
- mFlattenWriter.flush(mInputBuffer, mInputPtr-1);
- mFlattenWriter.disableOutput();
- }
-
- try {
- // ]]> needs to be a token, can not come from PE:
- char c = dtdNextFromCurr();
- if (c == ']') {
- c = dtdNextFromCurr();
- if (c == '>') {
- // Ok, fine, conditional include section ended.
- --mIncludeCount;
- continue;
- }
- }
- throwDTDUnexpectedChar(c, "; expected ']]>' to close conditional include section");
- } finally {
- if (suppress) {
- mFlattenWriter.enableOutput(mInputPtr);
- }
- }
- }
- // otherwise will fall through, and give an error
- }
-
- if (mIsExternal) {
- throwDTDUnexpectedChar(i, "; expected a '<' to start a directive");
- }
- throwDTDUnexpectedChar(i, "; expected a '<' to start a directive, or \"]>\" to end internal subset");
- }
-
- /* 05-Feb-2006, TSa: Not allowed to have unclosed INCLUDE/IGNORE
- * blocks...
- */
- if (mIncludeCount > 0) { // active INCLUDE block(s) open?
- String suffix = (mIncludeCount == 1) ? "an INCLUDE block" : (""+mIncludeCount+" INCLUDE blocks");
- throwUnexpectedEOF(getErrorMsg()+"; expected closing marker for "+suffix);
- }
-
- /* First check: have all notation references been resolved?
- * (related to [WSTX-121])
- */
- if (mNotationForwardRefs != null && mNotationForwardRefs.size() > 0) {
- _reportUndefinedNotationRefs();
- }
-
- // Ok; time to construct and return DTD data object.
- DTDSubset ss;
-
- // There are more settings for ext. subsets:
- if (mIsExternal) {
- /* External subsets are cachable if they did not refer to any
- * PEs or GEs defined in internal subset passed in (if any),
- * nor to any notations.
- * We don't care about PEs it defined itself, but need to pass
- * in Set of PEs it refers to, to check if cached copy can be
- * used with different int. subsets.
- * We need not worry about notations referred, since they are
- * not allowed to be re-defined.
- */
- boolean cachable = !mUsesPredefdEntities && !mUsesPredefdNotations;
- ss = DTDSubsetImpl.constructInstance(cachable,
- mGeneralEntities, mRefdGEs,
- null, mRefdPEs,
- mNotations, mElements,
- mCfgFullyValidating);
- } else {
- /* Internal subsets are not cachable (no unique way to refer
- * to unique internal subsets), and there can be no references
- * to pre-defined PEs, as none were passed.
- */
- ss = DTDSubsetImpl.constructInstance(false, mGeneralEntities, null,
- mParamEntities, null,
- mNotations, mElements,
- mCfgFullyValidating);
- }
-
- return ss;
- }
-
- protected void parseDirective()
- throws XMLStreamException
- {
- /* Hmmh. Don't think PEs are allowed to contain starting
- * '!' (or '?')... and it has to come from the same
- * input source too (no splits)
- */
- char c = dtdNextFromCurr();
- if (c == '?') { // xml decl?
- readPI();
- return;
- }
- if (c != '!') { // nothing valid
- throwDTDUnexpectedChar(c, "; expected '!' to start a directive");
- }
-
- /* ignore/include, comment, or directive; we are still getting
- * token from same section though
- */
- c = dtdNextFromCurr();
- if (c == '-') { // plain comment
- c = dtdNextFromCurr();
- if (c != '-') {
- throwDTDUnexpectedChar(c, "; expected '-' for a comment");
- }
- if (mEventListener != null && mEventListener.dtdReportComments()) {
- readComment(mEventListener);
- } else {
- skipComment();
- }
- } else if (c == '[') {
- checkInclusion();
- } else if (c >= 'A' && c <= 'Z') {
- handleDeclaration(c);
- } else {
- throwDTDUnexpectedChar(c, ErrorConsts.ERR_DTD_MAINLEVEL_KEYWORD);
- }
- }
-
- /**
- * Method similar to {@link #parseDirective}, but one that takes care
- * to properly output dtd contents via {@link com.ctc.wstx.dtd.DTDWriter}
- * as necessary.
- * Separated to simplify both methods; otherwise would end up with
- * 'if (... flatten...) ... else ...' spaghetti code.
- */
- protected void parseDirectiveFlattened()
- throws XMLStreamException
- {
- /* First, need to flush any flattened output there may be, at
- * this point (except for opening lt char): and then need to
- * temporarily disable more output until we know the type and
- * whether it should be output or not:
- */
- mFlattenWriter.flush(mInputBuffer, mInputPtr-1);
- mFlattenWriter.disableOutput();
-
- /* Let's determine type here, and call appropriate skip/parse
- * methods.
- */
- char c = dtdNextFromCurr();
- if (c == '?') { // xml decl?
- mFlattenWriter.enableOutput(mInputPtr);
- mFlattenWriter.output("");
- readPI();
- //throwDTDUnexpectedChar(c, " expected '!' to start a directive");
- return;
- }
- if (c != '!') { // nothing valid
- throwDTDUnexpectedChar(c, ErrorConsts.ERR_DTD_MAINLEVEL_KEYWORD);
- }
-
- // ignore/include, comment, or directive
-
- c = dtdNextFromCurr();
- if (c == '-') { // plain comment
- c = dtdNextFromCurr();
- if (c != '-') {
- throwDTDUnexpectedChar(c, "; expected '-' for a comment");
- }
- boolean comm = mFlattenWriter.includeComments();
- if (comm) {
- mFlattenWriter.enableOutput(mInputPtr);
- mFlattenWriter.output("");
- }
-
- public final void writePIStart(String target, boolean addSpace)
- throws IOException
- {
- fastWriteRaw('<', '?');
- fastWriteRaw(target);
- if (addSpace) {
- fastWriteRaw(' ');
- }
- }
-
- public final void writePIEnd()
- throws IOException
- {
- fastWriteRaw('?', '>');
- }
-
- /*
- ////////////////////////////////////////////////
- // Higher-level output methods, text output
- ////////////////////////////////////////////////
- */
-
- public int writeCData(String data)
- throws IOException
- {
- if (mCheckContent) {
- int ix = verifyCDataContent(data);
- if (ix >= 0) {
- if (!mFixContent) { // Can we fix it?
- return ix;
- }
- // Yes we can! (...Bob the Builder...)
- writeSegmentedCData(data, ix);
- return -1;
- }
- }
- fastWriteRaw("");
- return -1;
- }
-
- public int writeCData(char[] cbuf, int offset, int len)
- throws IOException
- {
- if (mCheckContent) {
- int ix = verifyCDataContent(cbuf, offset, len);
- if (ix >= 0) {
- if (!mFixContent) { // Can we fix it?
- return ix;
- }
- // Yes we can! (...Bob the Builder...)
- writeSegmentedCData(cbuf, offset, len, ix);
- return -1;
- }
- }
- fastWriteRaw("");
- return -1;
- }
-
- public void writeCharacters(String text)
- throws IOException
- {
- if (mOut == null) {
- return;
- }
- if (mTextWriter != null) { // custom escaping?
- mTextWriter.write(text);
- return;
- }
- int inPtr = 0;
- final int len = text.length();
- int highChar = mEncHighChar;
-
- main_loop:
- while (true) {
- String ent = null;
-
- inner_loop:
- while (true) {
- if (inPtr >= len) {
- break main_loop;
- }
- char c = text.charAt(inPtr++);
- if (c <= HIGHEST_ENCODABLE_TEXT_CHAR) {
- if (c <= 0x0020) {
- if (c != ' ' && c != '\n' && c != '\t') { // fine as is
- if (c == '\r') {
- if (mEscapeCR) {
- break inner_loop;
- }
- } else {
- if (!mXml11 || c == 0) {
- c = handleInvalidChar(c); // throws an error usually
- } else {
- break inner_loop; // need quoting
- }
- }
- }
- } else if (c == '<') {
- ent = "<";
- break inner_loop;
- } else if (c == '&') {
- ent = "&";
- break inner_loop;
- } else if (c == '>') {
- // Let's be conservative; and if there's any
- // change it might be part of "]]>" quote it
- if (inPtr < 2 || text.charAt(inPtr-2) == ']') {
- ent = ">";
- break inner_loop;
- }
- }
- } else if (c >= highChar) {
- break inner_loop;
- }
- if (mOutputPtr >= mOutputBufLen) {
- flushBuffer();
- }
- mOutputBuffer[mOutputPtr++] = c;
- }
- if (ent != null) {
- writeRaw(ent);
- } else {
- writeAsEntity(text.charAt(inPtr-1));
- }
- }
- }
-
- public void writeCharacters(char[] cbuf, int offset, int len)
- throws IOException
- {
- if (mOut == null) {
- return;
- }
-
- if (mTextWriter != null) { // custom escaping?
- mTextWriter.write(cbuf, offset, len);
- } else { // nope, default:
- len += offset;
- do {
- int c = 0;
- int highChar = mEncHighChar;
- int start = offset;
- String ent = null;
-
- for (; offset < len; ++offset) {
- c = cbuf[offset];
- if (c <= HIGHEST_ENCODABLE_TEXT_CHAR) {
- if (c == '<') {
- ent = "<";
- break;
- } else if (c == '&') {
- ent = "&";
- break;
- } else if (c == '>') {
- /* Let's be conservative; and if there's any
- * change it might be part of "]]>" quote it
- */
- if ((offset == start) || cbuf[offset-1] == ']') {
- ent = ">";
- break;
- }
- } else if (c < 0x0020) {
- if (c == '\n' || c == '\t') { // fine as is
- ;
- } else if (c == '\r') {
- if (mEscapeCR) {
- break;
- }
- } else {
- if (!mXml11 || c == 0) {
- c = handleInvalidChar(c);
- // Hmmh. This is very inefficient, but...
- ent = String.valueOf((char) c);
- }
- break; // need quoting
- }
- }
- } else if (c >= highChar) {
- break;
- }
- // otherwise ok
- }
- int outLen = offset - start;
- if (outLen > 0) {
- writeRaw(cbuf, start, outLen);
- }
- if (ent != null) {
- writeRaw(ent);
- ent = null;
- } else if (offset < len) {
- writeAsEntity(c);
- }
- } while (++offset < len);
- }
- }
-
- /**
- * Method that will try to output the content as specified. If
- * the content passed in has embedded "--" in it, it will either
- * add an intervening space between consequtive hyphens (if content
- * fixing is enabled), or return the offset of the first hyphen in
- * multi-hyphen sequence.
- */
- public int writeComment(String data)
- throws IOException
- {
- if (mCheckContent) {
- int ix = verifyCommentContent(data);
- if (ix >= 0) {
- if (!mFixContent) { // Can we fix it?
- return ix;
- }
- // Yes we can! (...Bob the Builder...)
- writeSegmentedComment(data, ix);
- return -1;
- }
- }
- fastWriteRaw("");
- return -1;
- }
-
- public void writeDTD(String data)
- throws IOException
- {
- writeRaw(data);
- }
-
- public void writeDTD(String rootName, String systemId, String publicId,
- String internalSubset)
- throws IOException, XMLStreamException
- {
- fastWriteRaw(" 0) {
- fastWriteRaw(' ', '[');
- fastWriteRaw(internalSubset);
- fastWriteRaw(']');
- }
- fastWriteRaw('>');
- }
-
- public void writeEntityReference(String name)
- throws IOException, XMLStreamException
- {
- if (mCheckNames) {
- verifyNameValidity(name, mNsAware);
- }
- fastWriteRaw('&');
- fastWriteRaw(name);
- fastWriteRaw(';');
- }
-
- public void writeXmlDeclaration(String version, String encoding, String standalone)
- throws IOException
- {
- fastWriteRaw(" 0) {
- fastWriteRaw(" encoding='");
- fastWriteRaw(encoding);
- fastWriteRaw('\'');
- }
- if (standalone != null) {
- fastWriteRaw(" standalone='");
- fastWriteRaw(standalone);
- fastWriteRaw('\'');
- }
- fastWriteRaw('?', '>');
- }
-
- public int writePI(String target, String data)
- throws IOException, XMLStreamException
- {
- if (mCheckNames) {
- // As per namespace specs, can not have colon(s)
- verifyNameValidity(target, mNsAware);
- }
- fastWriteRaw('<', '?');
- fastWriteRaw(target);
- if (data != null && data.length() > 0) {
- if (mCheckContent) {
- int ix = data.indexOf('?');
- if (ix >= 0) {
- ix = data.indexOf("?>", ix);
- if (ix >= 0) {
- return ix;
- }
- }
- }
- fastWriteRaw(' ');
- // Data may be longer, let's call regular writeRaw method
- writeRaw(data);
- }
- fastWriteRaw('?', '>');
- return -1;
- }
-
- /*
- ////////////////////////////////////////////////////
- // Write methods, elements
- ////////////////////////////////////////////////////
- */
-
- public void writeStartTagStart(String localName)
- throws IOException, XMLStreamException
- {
- if (mCheckNames) {
- verifyNameValidity(localName, mNsAware);
- }
-
- int ptr = mOutputPtr;
- int extra = (mOutputBufLen - ptr) - (1 + localName.length());
- if (extra < 0) { // split on boundary, slower
- fastWriteRaw('<');
- fastWriteRaw(localName);
- } else {
- char[] buf = mOutputBuffer;
- buf[ptr++] = '<';
- int len = localName.length();
- localName.getChars(0, len, buf, ptr);
- mOutputPtr = ptr+len;
- }
- }
-
- public void writeStartTagStart(String prefix, String localName)
- throws IOException, XMLStreamException
- {
- if (prefix == null || prefix.length() == 0) { // shouldn't happen
- writeStartTagStart(localName);
- return;
- }
-
- if (mCheckNames) {
- verifyNameValidity(prefix, mNsAware);
- verifyNameValidity(localName, mNsAware);
- }
-
- int ptr = mOutputPtr;
- int len = prefix.length();
- int extra = (mOutputBufLen - ptr) - (2 + localName.length() + len);
- if (extra < 0) { // across buffer boundary, slow case
- fastWriteRaw('<');
- fastWriteRaw(prefix);
- fastWriteRaw(':');
- fastWriteRaw(localName);
- } else { // fast case, all inlined
- char[] buf = mOutputBuffer;
- buf[ptr++] = '<';
- prefix.getChars(0, len, buf, ptr);
- ptr += len;
- buf[ptr++] = ':';
- len = localName.length();
- localName.getChars(0, len, buf, ptr);
- mOutputPtr = ptr+len;
- }
- }
-
- public void writeStartTagEnd()
- throws IOException
- {
- fastWriteRaw('>');
- }
-
- public void writeStartTagEmptyEnd()
- throws IOException
- {
- int ptr = mOutputPtr;
- if ((ptr + 3) >= mOutputBufLen) {
- if (mOut == null) {
- return;
- }
- flushBuffer();
- ptr = mOutputPtr;
- }
- char[] buf = mOutputBuffer;
- if (mAddSpaceAfterEmptyElem) {
- buf[ptr++] = ' ';
- }
- buf[ptr++] = '/';
- buf[ptr++] = '>';
- mOutputPtr = ptr;
- }
-
- public void writeEndTag(String localName)
- throws IOException
- {
- int ptr = mOutputPtr;
- int extra = (mOutputBufLen - ptr) - (3 + localName.length());
- if (extra < 0) {
- fastWriteRaw('<', '/');
- fastWriteRaw(localName);
- fastWriteRaw('>');
- } else {
- char[] buf = mOutputBuffer;
- buf[ptr++] = '<';
- buf[ptr++] = '/';
- int len = localName.length();
- localName.getChars(0, len, buf, ptr);
- ptr += len;
- buf[ptr++] = '>';
- mOutputPtr = ptr;
- }
- }
-
- public void writeEndTag(String prefix, String localName)
- throws IOException
- {
- if (prefix == null || prefix.length() == 0) {
- writeEndTag(localName);
- return;
- }
- int ptr = mOutputPtr;
- int len = prefix.length();
- int extra = (mOutputBufLen - ptr) - (4 + localName.length() + len);
- if (extra < 0) {
- fastWriteRaw('<', '/');
- /* At this point, it is assumed caller knows that end tag
- * matches with start tag, and that it (by extension) has been
- * validated if and as necessary
- */
- fastWriteRaw(prefix);
- fastWriteRaw(':');
- fastWriteRaw(localName);
- fastWriteRaw('>');
- } else {
- char[] buf = mOutputBuffer;
- buf[ptr++] = '<';
- buf[ptr++] = '/';
- prefix.getChars(0, len, buf, ptr);
- ptr += len;
- buf[ptr++] = ':';
- len = localName.length();
- localName.getChars(0, len, buf, ptr);
- ptr += len;
- buf[ptr++] = '>';
- mOutputPtr = ptr;
- }
- }
-
- /*
- ////////////////////////////////////////////////////
- // Write methods, attributes/ns
- ////////////////////////////////////////////////////
- */
-
- public void writeAttribute(String localName, String value)
- throws IOException, XMLStreamException
- {
- if (mOut == null) {
- return;
- }
- if (mCheckNames) {
- verifyNameValidity(localName, mNsAware);
- }
- int len = localName.length();
- if (((mOutputBufLen - mOutputPtr) - (3 + len)) < 0) {
- fastWriteRaw(' ');
- fastWriteRaw(localName);
- fastWriteRaw('=', '"');
- } else {
- int ptr = mOutputPtr;
- char[] buf = mOutputBuffer;
- buf[ptr++] = ' ';
- localName.getChars(0, len, buf, ptr);
- ptr += len;
- buf[ptr++] = '=';
- buf[ptr++] = '"';
- mOutputPtr = ptr;
- }
-
- len = (value == null) ? 0 : value.length();
- if (len > 0) {
- if (mAttrValueWriter != null) { // custom escaping?
- mAttrValueWriter.write(value, 0, len);
- } else { // nope, default
- writeAttrValue(value, len);
- }
- }
- fastWriteRaw('"');
- }
-
- public void writeAttribute(String localName, char[] value, int offset, int vlen)
- throws IOException, XMLStreamException
- {
- if (mOut == null) {
- return;
- }
- if (mCheckNames) {
- verifyNameValidity(localName, mNsAware);
- }
- int len = localName.length();
- if (((mOutputBufLen - mOutputPtr) - (3 + len)) < 0) {
- fastWriteRaw(' ');
- fastWriteRaw(localName);
- fastWriteRaw('=', '"');
- } else {
- int ptr = mOutputPtr;
- char[] buf = mOutputBuffer;
- buf[ptr++] = ' ';
- localName.getChars(0, len, buf, ptr);
- ptr += len;
- buf[ptr++] = '=';
- buf[ptr++] = '"';
- mOutputPtr = ptr;
- }
-
- if (vlen > 0) {
- if (mAttrValueWriter != null) { // custom escaping?
- mAttrValueWriter.write(value, offset, vlen);
- } else { // nope, default
- writeAttrValue(value, offset, vlen);
- }
- }
- fastWriteRaw('"');
- }
-
- public void writeAttribute(String prefix, String localName, String value)
- throws IOException, XMLStreamException
- {
- if (mOut == null) {
- return;
- }
- if (mCheckNames) {
- verifyNameValidity(prefix, mNsAware);
- verifyNameValidity(localName, mNsAware);
- }
- int len = prefix.length();
- if (((mOutputBufLen - mOutputPtr) - (4 + localName.length() + len)) < 0) {
- fastWriteRaw(' ');
- if (len > 0) {
- fastWriteRaw(prefix);
- fastWriteRaw(':');
- }
- fastWriteRaw(localName);
- fastWriteRaw('=', '"');
- } else {
- int ptr = mOutputPtr;
- char[] buf = mOutputBuffer;
- buf[ptr++] = ' ';
- prefix.getChars(0, len, buf, ptr);
- ptr += len;
- buf[ptr++] = ':';
- len = localName.length();
- localName.getChars(0, len, buf, ptr);
- ptr += len;
- buf[ptr++] = '=';
- buf[ptr++] = '"';
- mOutputPtr = ptr;
- }
-
- len = (value == null) ? 0 : value.length();
- if (len > 0) {
- if (mAttrValueWriter != null) { // custom escaping?
- mAttrValueWriter.write(value, 0, len);
- } else { // nope, default
- writeAttrValue(value, len);
- }
- }
- fastWriteRaw('"');
- }
-
- public void writeAttribute(String prefix, String localName, char[] value, int offset, int vlen)
- throws IOException, XMLStreamException
- {
- if (mOut == null) {
- return;
- }
- if (mCheckNames) {
- verifyNameValidity(prefix, mNsAware);
- verifyNameValidity(localName, mNsAware);
- }
- int len = prefix.length();
- if (((mOutputBufLen - mOutputPtr) - (4 + localName.length() + len)) < 0) {
- fastWriteRaw(' ');
- if (len > 0) {
- fastWriteRaw(prefix);
- fastWriteRaw(':');
- }
- fastWriteRaw(localName);
- fastWriteRaw('=', '"');
- } else {
- int ptr = mOutputPtr;
- char[] buf = mOutputBuffer;
- buf[ptr++] = ' ';
- prefix.getChars(0, len, buf, ptr);
- ptr += len;
- buf[ptr++] = ':';
- len = localName.length();
- localName.getChars(0, len, buf, ptr);
- ptr += len;
- buf[ptr++] = '=';
- buf[ptr++] = '"';
- mOutputPtr = ptr;
- }
- if (vlen > 0) {
- if (mAttrValueWriter != null) { // custom escaping?
- mAttrValueWriter.write(value, offset, vlen);
- } else { // nope, default
- writeAttrValue(value, offset, vlen);
- }
- }
- fastWriteRaw('"');
- }
-
- private final void writeAttrValue(String value, int len)
- throws IOException
- {
- int inPtr = 0;
- final char qchar = mEncQuoteChar;
- int highChar = mEncHighChar;
-
- main_loop:
- while (true) { // main_loop
- String ent = null;
-
- inner_loop:
- while (true) {
- if (inPtr >= len) {
- break main_loop;
- }
- char c = value.charAt(inPtr++);
- if (c <= HIGHEST_ENCODABLE_ATTR_CHAR) { // special char?
- if (c < 0x0020) { // tab, cr/lf need encoding too
- if (c == '\r') {
- if (mEscapeCR) {
- break inner_loop; // quoting
- }
- } else if (c != '\n' && c != '\t'
- && (!mXml11 || c == 0)) {
- c = handleInvalidChar(c);
- } else {
- break inner_loop; // need quoting
- }
- } else if (c == qchar) {
- ent = mEncQuoteEntity;
- break inner_loop;
- } else if (c == '<') {
- ent = "<";
- break inner_loop;
- } else if (c == '&') {
- ent = "&";
- break inner_loop;
- }
- } else if (c >= highChar) { // out of range, have to escape
- break inner_loop;
- }
- if (mOutputPtr >= mOutputBufLen) {
- flushBuffer();
- }
- mOutputBuffer[mOutputPtr++] = c;
- }
- if (ent != null) {
- writeRaw(ent);
- } else {
- writeAsEntity(value.charAt(inPtr-1));
- }
- }
- }
-
- private final void writeAttrValue(char[] value, int offset, int len)
- throws IOException
- {
- len += offset;
- final char qchar = mEncQuoteChar;
- int highChar = mEncHighChar;
-
- main_loop:
- while (true) { // main_loop
- String ent = null;
-
- inner_loop:
- while (true) {
- if (offset >= len) {
- break main_loop;
- }
- char c = value[offset++];
- if (c <= HIGHEST_ENCODABLE_ATTR_CHAR) { // special char?
- if (c < 0x0020) { // tab, cr/lf need encoding too
- if (c == '\r') {
- if (mEscapeCR) {
- break inner_loop; // quoting
- }
- } else if (c != '\n' && c != '\t'
- && (!mXml11 || c == 0)) {
- c = handleInvalidChar(c);
- } else {
- break inner_loop; // need quoting
- }
- } else if (c == qchar) {
- ent = mEncQuoteEntity;
- break inner_loop;
- } else if (c == '<') {
- ent = "<";
- break inner_loop;
- } else if (c == '&') {
- ent = "&";
- break inner_loop;
- }
- } else if (c >= highChar) { // out of range, have to escape
- break inner_loop;
- }
- if (mOutputPtr >= mOutputBufLen) {
- flushBuffer();
- }
- mOutputBuffer[mOutputPtr++] = c;
- }
- if (ent != null) {
- writeRaw(ent);
- } else {
- writeAsEntity(value[offset-1]);
- }
- }
- }
-
- /*
- ////////////////////////////////////////////////
- // Methods used by Typed Access API
- ////////////////////////////////////////////////
- */
-
- public final void writeTypedElement(AsciiValueEncoder enc)
- throws IOException
- {
- if (mOut == null) {
- return;
- }
-
- int free = mOutputBufLen - mOutputPtr;
- if (enc.bufferNeedsFlush(free)) {
- flush();
- }
- while (true) {
- mOutputPtr = enc.encodeMore(mOutputBuffer, mOutputPtr, mOutputBufLen);
- // If no flushing needed, indicates that all data was encoded
- if (enc.isCompleted()) {
- break;
- }
- flush();
- }
- }
-
- public final void writeTypedElement(AsciiValueEncoder enc,
- XMLValidator validator, char[] copyBuffer)
- throws IOException, XMLStreamException
- {
- if (mOut == null) {
- return;
- }
- int free = mOutputBufLen - mOutputPtr;
- if (enc.bufferNeedsFlush(free)) {
- flush();
- }
- int start = mOutputPtr;
- while (true) {
- mOutputPtr = enc.encodeMore(mOutputBuffer, mOutputPtr, mOutputBufLen);
- // False -> can't be sure it's the whole remaining text
- validator.validateText(mOutputBuffer, start, mOutputPtr, false);
- if (enc.isCompleted()) {
- break;
- }
- flush();
- start = mOutputPtr;
- }
- }
-
- public void writeTypedAttribute(String localName, AsciiValueEncoder enc)
- throws IOException, XMLStreamException
- {
- if (mOut == null) {
- return;
- }
- if (mCheckNames) {
- verifyNameValidity(localName, mNsAware);
- }
- int len = localName.length();
- if ((mOutputPtr + 3 + len) > mOutputBufLen) {
- fastWriteRaw(' ');
- fastWriteRaw(localName);
- fastWriteRaw('=', '"');
- } else {
- int ptr = mOutputPtr;
- char[] buf = mOutputBuffer;
- buf[ptr++] = ' ';
- localName.getChars(0, len, buf, ptr);
- ptr += len;
- buf[ptr++] = '=';
- buf[ptr++] = '"';
- mOutputPtr = ptr;
- }
-
- int free = mOutputBufLen - mOutputPtr;
- if (enc.bufferNeedsFlush(free)) {
- flush();
- }
- while (true) {
- mOutputPtr = enc.encodeMore(mOutputBuffer, mOutputPtr, mOutputBufLen);
- if (enc.isCompleted()) {
- break;
- }
- flush();
- }
- fastWriteRaw('"');
- }
-
- public void writeTypedAttribute(String prefix, String localName,
- AsciiValueEncoder enc)
- throws IOException, XMLStreamException
- {
- if (mOut == null) {
- return;
- }
- if (mCheckNames) {
- verifyNameValidity(prefix, mNsAware);
- verifyNameValidity(localName, mNsAware);
- }
- int plen = prefix.length();
- int llen = localName.length();
-
- if ((mOutputPtr + 4 + plen + llen) > mOutputBufLen) {
- writePrefixedName(prefix, localName);
- fastWriteRaw('=', '"');
- } else {
- int ptr = mOutputPtr;
- char[] buf = mOutputBuffer;
- buf[ptr++] = ' ';
- if (plen > 0) {
- prefix.getChars(0, plen, buf, ptr);
- ptr += plen;
- buf[ptr++] = ':';
-
- }
- localName.getChars(0, llen, buf, ptr);
- ptr += llen;
- buf[ptr++] = '=';
- buf[ptr++] = '"';
- mOutputPtr = ptr;
- }
-
- int free = mOutputBufLen - mOutputPtr;
- if (enc.bufferNeedsFlush(free)) {
- flush();
- }
- while (true) {
- mOutputPtr = enc.encodeMore(mOutputBuffer, mOutputPtr, mOutputBufLen);
- if (enc.isCompleted()) {
- break;
- }
- flush();
- }
-
- fastWriteRaw('"');
- }
-
- public void writeTypedAttribute(String prefix, String localName, String nsURI,
- AsciiValueEncoder enc,
- XMLValidator validator, char[] copyBuffer)
- throws IOException, XMLStreamException
- {
- if (mOut == null) {
- return;
- }
- if (prefix == null) {
- prefix = "";
- }
- if (nsURI == null) {
- nsURI = "";
- }
- int plen = prefix.length();
- if (mCheckNames) {
- if (plen > 0) {
- verifyNameValidity(prefix, mNsAware);
- }
- verifyNameValidity(localName, mNsAware);
- }
- if (((mOutputBufLen - mOutputPtr) - (4 + localName.length() + plen)) < 0) {
- writePrefixedName(prefix, localName);
- fastWriteRaw('=', '"');
- } else {
- int ptr = mOutputPtr;
- char[] buf = mOutputBuffer;
- buf[ptr++] = ' ';
- if (plen > 0) {
- prefix.getChars(0, plen, buf, ptr);
- ptr += plen;
- buf[ptr++] = ':';
-
- }
- int llen = localName.length();
- localName.getChars(0, llen, buf, ptr);
- ptr += llen;
- buf[ptr++] = '=';
- buf[ptr++] = '"';
- mOutputPtr = ptr;
- }
-
- /* Tricky here is this: attributes to validate can not be
- * split (validators expect complete values). So, if value
- * won't fit as is, may need to aggregate using StringBuilder
- */
- int free = mOutputBufLen - mOutputPtr;
- if (enc.bufferNeedsFlush(free)) {
- flush();
- }
- int start = mOutputPtr;
-
- // First, let's see if one call is enough
- mOutputPtr = enc.encodeMore(mOutputBuffer, mOutputPtr, mOutputBufLen);
- if (enc.isCompleted()) { // yup
- validator.validateAttribute(localName, nsURI, prefix, mOutputBuffer, start, mOutputPtr);
- return;
- }
-
- // If not, must combine first
- StringBuffer sb = new StringBuffer(mOutputBuffer.length << 1);
- sb.append(mOutputBuffer, start, mOutputPtr-start);
- while (true) {
- flush();
- start = mOutputPtr;
- mOutputPtr = enc.encodeMore(mOutputBuffer, mOutputPtr, mOutputBufLen);
- sb.append(mOutputBuffer, start, mOutputPtr-start);
- // All done?
- if (enc.isCompleted()) {
- break;
- }
- }
- fastWriteRaw('"');
-
- // Then validate
- String valueStr = sb.toString();
- validator.validateAttribute(localName, nsURI, prefix, valueStr);
- }
-
- protected final void writePrefixedName(String prefix, String localName)
- throws IOException
- {
- fastWriteRaw(' ');
- if (prefix.length() > 0) {
- fastWriteRaw(prefix);
- fastWriteRaw(':');
- }
- fastWriteRaw(localName);
- }
-
- /*
- ////////////////////////////////////////////////////
- // Internal methods, buffering
- ////////////////////////////////////////////////////
- */
-
- private final void flushBuffer()
- throws IOException
- {
- if (mOutputPtr > 0 && mOutputBuffer != null) {
- int ptr = mOutputPtr;
- // Need to update location info, to keep it in sync
- mLocPastChars += ptr;
- mLocRowStartOffset -= ptr;
- mOutputPtr = 0;
- mOut.write(mOutputBuffer, 0, ptr);
- }
- }
-
- private final void fastWriteRaw(char c)
- throws IOException
- {
- if (mOutputPtr >= mOutputBufLen) {
- if (mOut == null) {
- return;
- }
- flushBuffer();
- }
- mOutputBuffer[mOutputPtr++] = c;
- }
-
- private final void fastWriteRaw(char c1, char c2)
- throws IOException
- {
- if ((mOutputPtr + 1) >= mOutputBufLen) {
- if (mOut == null) {
- return;
- }
- flushBuffer();
- }
- mOutputBuffer[mOutputPtr++] = c1;
- mOutputBuffer[mOutputPtr++] = c2;
- }
-
- private final void fastWriteRaw(String str)
- throws IOException
- {
- int len = str.length();
- int ptr = mOutputPtr;
- if ((ptr + len) >= mOutputBufLen) {
- if (mOut == null) {
- return;
- }
- /* It's even possible that String is longer than the buffer (not
- * likely, possible). If so, let's just call the full
- * method:
- */
- if (len > mOutputBufLen) {
- writeRaw(str);
- return;
- }
- flushBuffer();
- ptr = mOutputPtr;
- }
- str.getChars(0, len, mOutputBuffer, ptr);
- mOutputPtr = ptr+len;
- }
-
- /*
- ////////////////////////////////////////////////////
- // Internal methods, content verification/fixing
- ////////////////////////////////////////////////////
- */
-
- /**
- * @return Index at which a problem was found, if any; -1 if there's
- * no problem.
- */
- protected int verifyCDataContent(String content)
- {
- if (content != null && content.length() >= 3) {
- int ix = content.indexOf(']');
- if (ix >= 0) {
- return content.indexOf("]]>", ix);
- }
- }
- return -1;
- }
-
- protected int verifyCDataContent(char[] c, int start, int end)
- {
- if (c != null) {
- start += 2;
- /* Let's do simple optimization for search...
- * (simple bayer-moore - like algorithm)
- */
- while (start < end) {
- char ch = c[start];
- if (ch == ']') {
- ++start; // let's just move by one in this case
- continue;
- }
- if (ch == '>') { // match?
- if (c[start-1] == ']'
- && c[start-2] == ']') {
- return start-2;
- }
- }
- start += 2;
- }
- }
- return -1;
- }
-
- protected int verifyCommentContent(String content)
- {
- int ix = content.indexOf('-');
- if (ix >= 0) {
- /* actually, it's illegal to just end with '-' too, since
- * that would cause invalid end marker '--->'
- */
- if (ix < (content.length() - 1)) {
- ix = content.indexOf("--", ix);
- }
- }
- return ix;
- }
-
- protected void writeSegmentedCData(String content, int index)
- throws IOException
- {
- /* It's actually fairly easy, just split "]]>" into 2 pieces;
- * for each ']]>'; first one containing "]]", second one ">"
- * (as long as necessary)
- */
- int start = 0;
- while (index >= 0) {
- fastWriteRaw("");
- start = index+2;
- index = content.indexOf("]]>", start);
- }
- // Ok, then the last segment
- fastWriteRaw("");
- }
-
- protected void writeSegmentedCData(char[] c, int start, int len, int index)
- throws IOException
- {
- int end = start + len;
- while (index >= 0) {
- fastWriteRaw("");
- start = index+2;
- index = verifyCDataContent(c, start, end);
- }
- // Ok, then the last segment
- fastWriteRaw("");
- }
-
- protected void writeSegmentedComment(String content, int index)
- throws IOException
- {
- int len = content.length();
- // First the special case (last char is hyphen):
- if (index == (len-1)) {
- fastWriteRaw("");
- return;
- }
-
- /* Fixing comments is more difficult than that of CDATA segments';
- * this because CDATA can still contain embedded ']]'s, but
- * comment neither allows '--' nor ending with '-->'; which means
- * that it's impossible to just split segments. Instead we'll do
- * something more intrusive, and embed single spaces between all
- * '--' character pairs... it's intrusive, but comments are not
- * supposed to contain any data, so that should be fine (plus
- * at least result is valid, unlike contents as is)
- */
- fastWriteRaw("");
- }
-
- /**
- * Method used to figure out which part of the Unicode char set the
- * encoding can natively support. Values returned are 7, 8 and 16,
- * to indicate (respectively) "ascii", "ISO-Latin" and "native Unicode".
- * These just best guesses, but should work ok for the most common
- * encodings.
- */
- public static int guessEncodingBitSize(String enc)
- {
- if (enc == null || enc.length() == 0) { // let's assume default is UTF-8...
- return 16;
- }
-
- // Let's see if we can find a normalized name, first:
- enc = CharsetNames.normalize(enc);
-
- // Ok, first, do we have known ones; starting with most common:
- if (enc == CharsetNames.CS_UTF8) {
- return 16; // meaning up to 2^16 can be represented natively
- } else if (enc == CharsetNames.CS_ISO_LATIN1) {
- return 8;
- } else if (enc == CharsetNames.CS_US_ASCII) {
- return 7;
- } else if (enc == CharsetNames.CS_UTF16
- || enc == CharsetNames.CS_UTF16BE
- || enc == CharsetNames.CS_UTF16LE
- || enc == CharsetNames.CS_UTF32BE
- || enc == CharsetNames.CS_UTF32LE) {
- return 16;
- }
-
- /* Above and beyond well-recognized names, it might still be
- * good to have more heuristics for as-of-yet unhandled cases...
- * But, it's probably easier to only assume 8-bit clean (could
- * even make it just 7, let's see how this works out)
- */
- return 8;
- }
-
- protected final void writeAsEntity(int c)
- throws IOException
- {
- char[] buf = mOutputBuffer;
- int ptr = mOutputPtr;
- if ((ptr + 10) >= buf.length) { // [up to 6 hex digits] ;
- flushBuffer();
- ptr = mOutputPtr;
- }
- buf[ptr++] = '&';
-
- // Can use more optimal notation for 8-bit ascii stuff:
- if (c < 256) {
- /* Also; although not really mandatory, let's also
- * use pre-defined entities where possible.
- */
- if (c == '&') {
- buf[ptr++] = 'a';
- buf[ptr++] = 'm';
- buf[ptr++] = 'p';
- } else if (c == '<') {
- buf[ptr++] = 'l';
- buf[ptr++] = 't';
- } else if (c == '>') {
- buf[ptr++] = 'g';
- buf[ptr++] = 't';
- } else if (c == '\'') {
- buf[ptr++] = 'a';
- buf[ptr++] = 'p';
- buf[ptr++] = 'o';
- buf[ptr++] = 's';
- } else if (c == '"') {
- buf[ptr++] = 'q';
- buf[ptr++] = 'u';
- buf[ptr++] = 'o';
- buf[ptr++] = 't';
- } else {
- buf[ptr++] = '#';;
- buf[ptr++] = 'x';;
- // Can use shortest quoting for tab, cr, lf:
- if (c >= 16) {
- int digit = (c >> 4);
- buf[ptr++] = (char) ((digit < 10) ? ('0' + digit) : (('a' - 10) + digit));
- c &= 0xF;
- }
- buf[ptr++] = (char) ((c < 10) ? ('0' + c) : (('a' - 10) + c));
- }
- } else {
- buf[ptr++] = '#';
- buf[ptr++] = 'x';
-
- // Ok, let's write the shortest possible sequence then:
- int shift = 20;
- int origPtr = ptr;
-
- do {
- int digit = (c >> shift) & 0xF;
- if (digit > 0 || (ptr != origPtr)) {
- buf[ptr++] = (char) ((digit < 10) ? ('0' + digit) : (('a' - 10) + digit));
- }
- shift -= 4;
- } while (shift > 0);
- c &= 0xF;
- buf[ptr++] = (char) ((c < 10) ? ('0' + c) : (('a' - 10) + c));
- }
- buf[ptr++] = ';';
- mOutputPtr = ptr;
- }
-}
diff -Nru libwoodstox-java-4.1.3/src/java/com/ctc/wstx/sw/EncodingXmlWriter.java libwoodstox-java-5.1.0/src/java/com/ctc/wstx/sw/EncodingXmlWriter.java
--- libwoodstox-java-4.1.3/src/java/com/ctc/wstx/sw/EncodingXmlWriter.java 2012-04-24 04:38:20.000000000 +0000
+++ libwoodstox-java-5.1.0/src/java/com/ctc/wstx/sw/EncodingXmlWriter.java 1970-01-01 00:00:00.000000000 +0000
@@ -1,934 +0,0 @@
-/* Woodstox XML processor
- *
- * Copyright (c) 2004- 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 com.ctc.wstx.sw;
-
-import java.io.*;
-import javax.xml.stream.XMLStreamException;
-
-import org.codehaus.stax2.ri.typed.AsciiValueEncoder;
-import org.codehaus.stax2.validation.XMLValidator;
-
-import com.ctc.wstx.api.WriterConfig;
-import com.ctc.wstx.cfg.XmlConsts;
-
-/**
- * Intermediate base class used when outputting to streams that use
- * an encoding that is compatible with 7-bit single-byte Ascii encoding.
- * That means it can be used for UTF-8, ISO-Latin1 and pure Ascii.
- *
- * Implementation notes:
- *
- * Parts of surrogate handling are implemented here in the base class:
- * storage for the first part of a split surrogate (only possible when
- * character content is output split in multiple calls) is within
- * base class. Also, simple checks for unmatched surrogate pairs are
- * in writeAscii
method, since it is the most convenient
- * place to catch cases where a text segment ends with an unmatched
- * surrogate pair half.
- */
-public abstract class EncodingXmlWriter
- extends XmlWriter
-{
- /**
- * Let's use a typical default to have a compromise between large
- * enough chunks to output, and minimizing memory overhead.
- * 4k should be close enough to a physical page to work out
- * acceptably, without causing excessive (if temporary) memory usage.
- */
- final static int DEFAULT_BUFFER_SIZE = 4000;
-
- final static byte BYTE_SPACE = (byte) ' ';
- final static byte BYTE_COLON = (byte) ':';
- final static byte BYTE_SEMICOLON = (byte) ';';
- final static byte BYTE_LBRACKET = (byte) '[';
- final static byte BYTE_RBRACKET = (byte) ']';
- final static byte BYTE_QMARK = (byte) '?';
- final static byte BYTE_EQ = (byte) '=';
- final static byte BYTE_SLASH = (byte) '/';
- final static byte BYTE_HASH = (byte) '#';
- final static byte BYTE_HYPHEN = (byte) '-';
-
- final static byte BYTE_LT = (byte) '<';
- final static byte BYTE_GT = (byte) '>';
- final static byte BYTE_AMP = (byte) '&';
- final static byte BYTE_QUOT = (byte) '"';
- final static byte BYTE_APOS = (byte) '\'';
-
- final static byte BYTE_A = (byte) 'a';
- final static byte BYTE_G = (byte) 'g';
- final static byte BYTE_L = (byte) 'l';
- final static byte BYTE_M = (byte) 'm';
- final static byte BYTE_O = (byte) 'o';
- final static byte BYTE_P = (byte) 'p';
- final static byte BYTE_Q = (byte) 'q';
- final static byte BYTE_S = (byte) 's';
- final static byte BYTE_T = (byte) 't';
- final static byte BYTE_U = (byte) 'u';
- final static byte BYTE_X = (byte) 'x';
-
- /*
- ////////////////////////////////////////////////
- // Output state, buffering
- ////////////////////////////////////////////////
- */
-
- /**
- * Actual output stream to use for outputting encoded content as
- * bytes.
- */
- private final OutputStream mOut;
-
- protected byte[] mOutputBuffer;
-
- protected int mOutputPtr;
-
- /**
- * In case a split surrogate pair is output (which can only successfully
- * occur with either writeRaw
or
- * writeCharacters
), the first part is temporarily stored
- * within this member variable.
- */
- protected int mSurrogate = 0;
-
- /*
- ////////////////////////////////////////////////
- //
- ////////////////////////////////////////////////
- */
-
- public EncodingXmlWriter(OutputStream out, WriterConfig cfg, String encoding,
- boolean autoclose)
- throws IOException
- {
- super(cfg, encoding, autoclose);
- mOut = out;
- mOutputBuffer = cfg.allocFullBBuffer(DEFAULT_BUFFER_SIZE);
- mOutputPtr = 0;
- }
-
- /**
- * This method is needed by the super class, to calculate hard
- * byte/char offsets.
- */
- protected int getOutputPtr() {
- return mOutputPtr;
- }
-
- /*
- ////////////////////////////////////////////////
- // Partial API implementation
- ////////////////////////////////////////////////
- */
-
- final protected OutputStream getOutputStream()
- {
- return mOut;
- }
-
- final protected Writer getWriter()
- {
- // No writers are involved with these implementations...
- return null;
- }
-
- public void close(boolean forceRealClose)
- throws IOException
- {
- flush();
-
- // Buffers to free?
- byte[] buf = mOutputBuffer;
- if (buf != null) {
- mOutputBuffer = null;
- mConfig.freeFullBBuffer(buf);
- }
- // Plus may need to close the actual stream
- if (forceRealClose || mAutoCloseOutput) {
- /* 14-Nov-2008, TSa: Wrt [WSTX-163]; no need to
- * check whether mOut implements CompletelyCloseable
- * (unlike with BufferingXmlWriter)
- */
- mOut.close();
- }
- }
-
- public final void flush()
- throws IOException
- {
- flushBuffer();
- mOut.flush();
- }
-
- public abstract void writeRaw(char[] cbuf, int offset, int len)
- throws IOException;
-
- public abstract void writeRaw(String str, int offset, int len)
- throws IOException;
-
- /*
- //////////////////////////////////////////////////
- // "Trusted" low-level output methods (that do not
- // need to verify validity of input)
- //////////////////////////////////////////////////
- */
-
- public final void writeCDataStart()
- throws IOException
- {
- writeAscii("");
- }
-
- public final void writeCommentStart()
- throws IOException
- {
- writeAscii("");
- }
-
- public final void writePIStart(String target, boolean addSpace)
- throws IOException
- {
- writeAscii(BYTE_LT, BYTE_QMARK);
- writeRaw(target);
- if (addSpace) {
- writeAscii(BYTE_SPACE);
- }
- }
-
- public final void writePIEnd()
- throws IOException
- {
- writeAscii(BYTE_QMARK, BYTE_GT);
- }
-
- /*
- ////////////////////////////////////////////////
- // Higher-level output methods, text output
- ////////////////////////////////////////////////
- */
-
- public int writeCData(String data)
- throws IOException
- {
- writeAscii("= 0) {
- return ix;
- }
- writeAscii("]]>");
- return -1;
- }
-
- public int writeCData(char[] cbuf, int offset, int len)
- throws IOException
- {
- writeAscii("= 0) {
- return ix;
- }
- writeAscii("]]>");
- return -1;
- }
-
- public final void writeCharacters(String data)
- throws IOException
- {
- // Note: may get second part of a surrogate
- if (mTextWriter != null) { // custom escaping?
- mTextWriter.write(data);
- } else { // nope, default:
- writeTextContent(data);
- }
- }
-
- public final void writeCharacters(char[] cbuf, int offset, int len)
- throws IOException
- {
- // Note: may get second part of a surrogate
- if (mTextWriter != null) { // custom escaping?
- mTextWriter.write(cbuf, offset, len);
- } else { // nope, default:
- writeTextContent(cbuf, offset, len);
- }
- }
-
- /**
- * Method that will try to output the content as specified. If
- * the content passed in has embedded "--" in it, it will either
- * add an intervening space between consequtive hyphens (if content
- * fixing is enabled), or return the offset of the first hyphen in
- * multi-hyphen sequence.
- */
- public int writeComment(String data)
- throws IOException
- {
- writeAscii("");
- return -1;
- }
-
- public void writeDTD(String data)
- throws IOException
- {
- if (mSurrogate != 0) {
- throwUnpairedSurrogate();
- }
- writeRaw(data, 0, data.length());
- }
-
- public void writeDTD(String rootName, String systemId, String publicId,
- String internalSubset)
- throws IOException, XMLStreamException
- {
- writeAscii(" 0) {
- writeAscii(BYTE_SPACE, BYTE_LBRACKET);
- writeRaw(internalSubset, 0, internalSubset.length());
- writeAscii(BYTE_RBRACKET);
- }
- writeAscii(BYTE_GT);
- }
-
- public void writeEntityReference(String name)
- throws IOException, XMLStreamException
- {
- if (mSurrogate != 0) {
- throwUnpairedSurrogate();
- }
- writeAscii(BYTE_AMP);
- writeName(name);
- writeAscii(BYTE_SEMICOLON);
- }
-
- public void writeXmlDeclaration(String version, String encoding, String standalone)
- throws IOException
- {
- writeAscii(" 0) {
- writeAscii(" encoding='");
- // Should be ascii, but let's play it safe:
- writeRaw(encoding, 0, encoding.length());
- writeAscii(BYTE_APOS);
- }
- if (standalone != null) {
- writeAscii(" standalone='");
- writeAscii(standalone);
- writeAscii(BYTE_APOS);
- }
- writeAscii(BYTE_QMARK, BYTE_GT);
- }
-
- public int writePI(String target, String data)
- throws IOException, XMLStreamException
- {
- writeAscii(BYTE_LT, BYTE_QMARK);
- writeName(target);
- if (data != null && data.length() > 0) {
- writeAscii(BYTE_SPACE);
- int ix = writePIData(data);
- if (ix >= 0) { // embedded "?>"?
- return ix;
- }
- }
- writeAscii(BYTE_QMARK, BYTE_GT);
- return -1;
- }
-
- /*
- ////////////////////////////////////////////////////
- // Write methods, elements
- ////////////////////////////////////////////////////
- */
-
- public void writeStartTagStart(String localName)
- throws IOException, XMLStreamException
- {
- writeAscii(BYTE_LT);
- writeName(localName);
- }
-
- public void writeStartTagStart(String prefix, String localName)
- throws IOException, XMLStreamException
- {
- if (prefix == null || prefix.length() == 0) {
- writeStartTagStart(localName);
- return;
- }
- writeAscii(BYTE_LT);
- writeName(prefix);
- writeAscii(BYTE_COLON);
- writeName(localName);
- }
-
- public void writeStartTagEnd()
- throws IOException
- {
- writeAscii(BYTE_GT);
- }
-
- public void writeStartTagEmptyEnd()
- throws IOException
- {
- if (mAddSpaceAfterEmptyElem) {
- writeAscii(" />");
- } else {
- writeAscii(BYTE_SLASH, BYTE_GT);
- }
- }
-
- public void writeEndTag(String localName)
- throws IOException
- {
- writeAscii(BYTE_LT, BYTE_SLASH);
- /* At this point, it is assumed caller knows that end tag
- * matches with start tag, and that it (by extension) has been
- * validated if and as necessary
- */
- writeNameUnchecked(localName);
- writeAscii(BYTE_GT);
- }
-
- public void writeEndTag(String prefix, String localName)
- throws IOException
- {
- writeAscii(BYTE_LT, BYTE_SLASH);
- /* At this point, it is assumed caller knows that end tag
- * matches with start tag, and that it (by extension) has been
- * validated if and as necessary
- */
- if (prefix != null && prefix.length() > 0) {
- writeNameUnchecked(prefix);
- writeAscii(BYTE_COLON);
- }
- writeNameUnchecked(localName);
- writeAscii(BYTE_GT);
- }
-
- /*
- ////////////////////////////////////////////////////
- // Write methods, attributes/ns
- ////////////////////////////////////////////////////
- */
-
- public void writeAttribute(String localName, String value)
- throws IOException, XMLStreamException
- {
- writeAscii(BYTE_SPACE);
- writeName(localName);
- writeAscii(BYTE_EQ, BYTE_QUOT);
-
- int len = value.length();
- if (len > 0) {
- if (mAttrValueWriter != null) { // custom escaping?
- mAttrValueWriter.write(value, 0, len);
- } else { // nope, default
- writeAttrValue(value);
- }
- }
- writeAscii(BYTE_QUOT);
- }
-
- public void writeAttribute(String localName, char[] value, int offset, int len)
- throws IOException, XMLStreamException
- {
- writeAscii(BYTE_SPACE);
- writeName(localName);
- writeAscii(BYTE_EQ, BYTE_QUOT);
-
- if (len > 0) {
- if (mAttrValueWriter != null) { // custom escaping?
- mAttrValueWriter.write(value, offset, len);
- } else { // nope, default
- writeAttrValue(value, offset, len);
- }
- }
- writeAscii(BYTE_QUOT);
- }
-
- public void writeAttribute(String prefix, String localName, String value)
- throws IOException, XMLStreamException
- {
- writeAscii(BYTE_SPACE);
- writeName(prefix);
- writeAscii(BYTE_COLON);
- writeName(localName);
- writeAscii(BYTE_EQ, BYTE_QUOT);
-
- int len = value.length();
- if (len > 0) {
- if (mAttrValueWriter != null) { // custom escaping?
- mAttrValueWriter.write(value, 0, len);
- } else { // nope, default
- writeAttrValue(value);
- }
- }
- writeAscii(BYTE_QUOT);
- }
-
- public void writeAttribute(String prefix, String localName, char[] value, int offset, int len)
- throws IOException, XMLStreamException
- {
- writeAscii(BYTE_SPACE);
- writeName(prefix);
- writeAscii(BYTE_COLON);
- writeName(localName);
- writeAscii(BYTE_EQ, BYTE_QUOT);
-
- if (len > 0) {
- if (mAttrValueWriter != null) { // custom escaping?
- mAttrValueWriter.write(value, offset, len);
- } else { // nope, default
- writeAttrValue(value, offset, len);
- }
- }
- writeAscii(BYTE_QUOT);
- }
-
- /*
- ////////////////////////////////////////////////
- // Methods used by Typed Access API
- ////////////////////////////////////////////////
- */
-
- /**
- * Non-validating version of typed write method
- */
- public final void writeTypedElement(AsciiValueEncoder enc)
- throws IOException
- {
- if (mSurrogate != 0) {
- throwUnpairedSurrogate();
- }
- if (enc.bufferNeedsFlush(mOutputBuffer.length - mOutputPtr)) {
- flush();
- }
- while (true) {
- mOutputPtr = enc.encodeMore(mOutputBuffer, mOutputPtr, mOutputBuffer.length);
- // If no flushing needed, indicates that all data was encoded
- if (enc.isCompleted()) {
- break;
- }
- flush();
- }
- }
-
- /**
- * Validating version of typed write method
- */
- public final void writeTypedElement(AsciiValueEncoder enc,
- XMLValidator validator, char[] copyBuffer)
- throws IOException, XMLStreamException
- {
- if (mSurrogate != 0) {
- throwUnpairedSurrogate();
- }
-
- /* Ok, this gets trickier: can't use efficient direct-to-bytes
- * encoding since validator won't be able to use it. Instead
- * have to use temporary copy buffer.
- */
- final int copyBufferLen = copyBuffer.length;
-
- // Copy buffer should never be too small, no need to check up front
- do {
- int ptr = enc.encodeMore(copyBuffer, 0, copyBufferLen);
-
- // False -> can't be sure it's the whole remaining text
- validator.validateText(copyBuffer, 0, ptr, false);
- writeRawAscii(copyBuffer, 0, ptr);
- } while (!enc.isCompleted());
- }
-
- public void writeTypedAttribute(String localName, AsciiValueEncoder enc)
- throws IOException, XMLStreamException
- {
- writeAscii(BYTE_SPACE);
- writeName(localName);
- writeAscii(BYTE_EQ, BYTE_QUOT);
-
- if (enc.bufferNeedsFlush(mOutputBuffer.length - mOutputPtr)) {
- flush();
- }
- while (true) {
- mOutputPtr = enc.encodeMore(mOutputBuffer, mOutputPtr, mOutputBuffer.length);
- if (enc.isCompleted()) {
- break;
- }
- flush();
- }
- writeAscii(BYTE_QUOT);
- }
-
- public void writeTypedAttribute(String prefix, String localName,
- AsciiValueEncoder enc)
- throws IOException, XMLStreamException
- {
- writeAscii(BYTE_SPACE);
- writeName(prefix);
- writeAscii(BYTE_COLON);
- writeName(localName);
- writeAscii(BYTE_EQ, BYTE_QUOT);
-
- if (enc.bufferNeedsFlush(mOutputBuffer.length - mOutputPtr)) {
- flush();
- }
- while (true) {
- mOutputPtr = enc.encodeMore(mOutputBuffer, mOutputPtr, mOutputBuffer.length);
- if (enc.isCompleted()) {
- break;
- }
- flush();
- }
- writeAscii(BYTE_QUOT);
- }
-
- public void writeTypedAttribute(String prefix, String localName, String nsURI,
- AsciiValueEncoder enc,
- XMLValidator validator, char[] copyBuffer)
- throws IOException, XMLStreamException
- {
- boolean hasPrefix = (prefix != null && prefix.length() > 0);
- if (nsURI == null) {
- nsURI = "";
- }
- //validator.validateAttribute(localName, nsURI, (hasPrefix ? prefix: ""), buf, offset, len);
-
- writeAscii(BYTE_SPACE);
- if (hasPrefix) {
- writeName(prefix);
- writeAscii(BYTE_COLON);
- }
- writeName(localName);
- writeAscii(BYTE_EQ, BYTE_QUOT);
-
- /* Ok, this gets trickier: can't use efficient direct-to-bytes
- * encoding since validator won't be able to use it. Instead
- * have to use temporary copy buffer.
- * In addition, attributes to validate can not be
- * split (validators expect complete values). So, if value
- * won't fit as is, may need to aggregate using StringBuilder
- */
- final int copyBufferLen = copyBuffer.length;
-
- // First, let's see if one call is enough
- int last = enc.encodeMore(copyBuffer, 0, copyBufferLen);
- writeRawAscii(copyBuffer, 0, last);
- if (enc.isCompleted()) {
- validator.validateAttribute(localName, nsURI, prefix, copyBuffer, 0, last);
- return;
- }
-
- // If not, must combine first
- StringBuffer sb = new StringBuffer(copyBufferLen << 1);
- sb.append(copyBuffer, 0, last);
- do {
- last = enc.encodeMore(copyBuffer, 0, copyBufferLen);
- writeRawAscii(copyBuffer, 0, last);
- sb.append(copyBuffer, 0, last);
- } while (!enc.isCompleted());
-
- writeAscii(BYTE_QUOT);
-
- // Then validate
- String valueStr = sb.toString();
- validator.validateAttribute(localName, nsURI, prefix, valueStr);
-
- return;
- }
-
- /*
- ////////////////////////////////////////////////
- // Methods for sub-classes to use
- ////////////////////////////////////////////////
- */
-
- protected final void flushBuffer()
- throws IOException
- {
- if (mOutputPtr > 0 && mOutputBuffer != null) {
- int ptr = mOutputPtr;
- mOutputPtr = 0;
- mOut.write(mOutputBuffer, 0, ptr);
- }
- }
-
- protected final void writeAscii(byte b)
- throws IOException
- {
- if (mSurrogate != 0) {
- throwUnpairedSurrogate();
- }
- if (mOutputPtr >= mOutputBuffer.length) {
- flushBuffer();
- }
- mOutputBuffer[mOutputPtr++] = b;
- }
-
- protected final void writeAscii(byte b1, byte b2)
- throws IOException
- {
- if (mSurrogate != 0) {
- throwUnpairedSurrogate();
- }
- if ((mOutputPtr + 1) >= mOutputBuffer.length) {
- flushBuffer();
- }
- mOutputBuffer[mOutputPtr++] = b1;
- mOutputBuffer[mOutputPtr++] = b2;
- }
-
- protected final void writeAscii(String str)
- throws IOException
- {
- if (mSurrogate != 0) {
- throwUnpairedSurrogate();
- }
-
- int len = str.length();
- int ptr = mOutputPtr;
- byte[] buf = mOutputBuffer;
- if ((ptr + len) >= buf.length) {
- /* It's even possible that String is longer than the buffer (not
- * likely, possible). If so, let's just call the full
- * method:
- */
- if (len > buf.length) {
- writeRaw(str, 0, len);
- return;
- }
- flushBuffer();
- ptr = mOutputPtr;
- }
- mOutputPtr += len;
- for (int i = 0; i < len; ++i) {
- buf[ptr++] = (byte)str.charAt(i);
- }
- }
-
- public final void writeRawAscii(char[] buf, int offset, int len)
- throws IOException
- {
- if (mSurrogate != 0) {
- throwUnpairedSurrogate();
- }
- int ptr = mOutputPtr;
- byte[] dst = mOutputBuffer;
- if ((ptr + len) >= dst.length) {
- if (len > dst.length) {
- writeRaw(buf, offset, len);
- return;
- }
- flushBuffer();
- ptr = mOutputPtr;
- }
- mOutputPtr += len;
- for (int i = 0; i < len; ++i) {
- dst[ptr+i] = (byte)buf[offset+i];
- }
- }
-
- /**
- * Entity writing can be optimized quite nicely, since it only
- * needs to output ascii characters.
- *
- * @return New value of mOutputPtr
- */
- protected final int writeAsEntity(int c)
- throws IOException
- {
- byte[] buf = mOutputBuffer;
- int ptr = mOutputPtr;
- if ((ptr + 10) >= buf.length) { // [up to 6 hex digits] ;
- flushBuffer();
- ptr = mOutputPtr;
- }
- buf[ptr++] = BYTE_AMP;
-
- // Can use more optimal notation for 8-bit ascii stuff:
- if (c < 256) {
- /* Also; although not really mandatory, let's also
- * use pre-defined entities where possible.
- */
- if (c == '&') {
- buf[ptr++] = BYTE_A;
- buf[ptr++] = BYTE_M;
- buf[ptr++] = BYTE_P;
- } else if (c == '<') {
- buf[ptr++] = BYTE_L;
- buf[ptr++] = BYTE_T;
- } else if (c == '>') {
- buf[ptr++] = BYTE_G;
- buf[ptr++] = BYTE_T;
- } else if (c == '\'') {
- buf[ptr++] = BYTE_A;
- buf[ptr++] = BYTE_P;
- buf[ptr++] = BYTE_O;
- buf[ptr++] = BYTE_S;
- } else if (c == '"') {
- buf[ptr++] = BYTE_Q;
- buf[ptr++] = BYTE_U;
- buf[ptr++] = BYTE_O;
- buf[ptr++] = BYTE_T;
- } else {
- buf[ptr++] = BYTE_HASH;
- buf[ptr++] = BYTE_X;
- // Can use shortest quoting for tab, cr, lf:
- if (c >= 16) {
- int digit = (c >> 4);
- buf[ptr++] = (byte) ((digit < 10) ? ('0' + digit) : (('a' - 10) + digit));
- c &= 0xF;
- }
- buf[ptr++] = (byte) ((c < 10) ? ('0' + c) : (('a' - 10) + c));
- }
- } else {
- buf[ptr++] = BYTE_HASH;
- buf[ptr++] = BYTE_X;
-
- // Ok, let's write the shortest possible sequence then:
- int shift = 20;
- int origPtr = ptr;
-
- do {
- int digit = (c >> shift) & 0xF;
- if (digit > 0 || (ptr != origPtr)) {
- buf[ptr++] = (byte) ((digit < 10) ? ('0' + digit) : (('a' - 10) + digit));
- }
- shift -= 4;
- } while (shift > 0);
- c &= 0xF;
- buf[ptr++] = (byte) ((c < 10) ? ('0' + c) : (('a' - 10) + c));
- }
- buf[ptr++] = BYTE_SEMICOLON;
- mOutputPtr = ptr;
- return ptr;
- }
-
- protected final void writeName(String name)
- throws IOException, XMLStreamException
- {
- if (mCheckNames) {
- verifyNameValidity(name, mNsAware);
- }
- // TODO: maybe we could reuse some previously encoded names?
- writeRaw(name, 0, name.length());
- }
-
- protected final void writeNameUnchecked(String name)
- throws IOException
- {
- writeRaw(name, 0, name.length());
- }
-
- protected final int calcSurrogate(int secondSurr)
- throws IOException
- {
- // First, let's verify first surrogate is valid:
- int firstSurr = mSurrogate;
- mSurrogate = 0;
- if (firstSurr < SURR1_FIRST || firstSurr > SURR1_LAST) {
- throwUnpairedSurrogate(firstSurr);
- }
-
- // Then that the second one is:
- if ((secondSurr < SURR2_FIRST) || (secondSurr > SURR2_LAST)) {
- throwUnpairedSurrogate(secondSurr);
- }
- int ch = 0x10000 + ((firstSurr - SURR1_FIRST) << 10) + (secondSurr - SURR2_FIRST);
- if (ch > XmlConsts.MAX_UNICODE_CHAR) {
- throw new IOException("Illegal surrogate character pair, resulting code 0x"+Integer.toHexString(ch)+" above legal XML character range");
- }
- return ch;
- }
-
- protected final void throwUnpairedSurrogate()
- throws IOException
- {
- int surr = mSurrogate;
- mSurrogate = 0;
- throwUnpairedSurrogate(surr);
- }
-
- protected final void throwUnpairedSurrogate(int code)
- throws IOException
-{
- // Let's flush to make debugging easier
- flush();
- throw new IOException("Unpaired surrogate character (0x"+Integer.toHexString(code)+")");
-}
-
- /*
- ////////////////////////////////////////////////
- // Abstract methods for sub-classes to define
- ////////////////////////////////////////////////
- */
-
- protected abstract void writeAttrValue(String data)
- throws IOException;
-
- protected abstract void writeAttrValue(char[] value, int offset, int len)
- throws IOException;
-
- protected abstract int writeCDataContent(String data)
- throws IOException;
-
- protected abstract int writeCDataContent(char[] cbuf, int start, int len)
- throws IOException;
-
- protected abstract int writeCommentContent(String data)
- throws IOException;
-
- protected abstract int writePIData(String data)
- throws IOException, XMLStreamException;
-
- protected abstract void writeTextContent(String data)
- throws IOException;
-
- protected abstract void writeTextContent(char[] cbuf, int start, int len)
- throws IOException;
-}
diff -Nru libwoodstox-java-4.1.3/src/java/com/ctc/wstx/sw/ISOLatin1XmlWriter.java libwoodstox-java-5.1.0/src/java/com/ctc/wstx/sw/ISOLatin1XmlWriter.java
--- libwoodstox-java-4.1.3/src/java/com/ctc/wstx/sw/ISOLatin1XmlWriter.java 2012-04-24 04:38:20.000000000 +0000
+++ libwoodstox-java-5.1.0/src/java/com/ctc/wstx/sw/ISOLatin1XmlWriter.java 1970-01-01 00:00:00.000000000 +0000
@@ -1,791 +0,0 @@
-/* Woodstox XML processor
- *
- * Copyright (c) 2004- 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 com.ctc.wstx.sw;
-
-import java.io.*;
-
-import javax.xml.stream.XMLStreamException;
-
-import com.ctc.wstx.api.WriterConfig;
-import com.ctc.wstx.io.CharsetNames;
-
-/**
- * Concrete implementation of {@link EncodingXmlWriter} used when output
- * is to be encoded using ISO-8859-1, aka ISO-Latin1 encoding.
- *
- * Regarding surrogate pair handling: most of the checks are in the base
- * class, and here we only need to worry about writeRaw
- * methods.
- */
-public final class ISOLatin1XmlWriter
- extends EncodingXmlWriter
-{
- public ISOLatin1XmlWriter(OutputStream out, WriterConfig cfg, boolean autoclose)
- throws IOException
- {
- super(out, cfg, CharsetNames.CS_ISO_LATIN1, autoclose);
- }
-
- public void writeRaw(char[] cbuf, int offset, int len)
- throws IOException
- {
- if (mSurrogate != 0) {
- throwUnpairedSurrogate();
- }
-
- int ptr = mOutputPtr;
- while (len > 0) {
- int max = mOutputBuffer.length - ptr;
- if (max < 1) { // output buffer full?
- mOutputPtr = ptr;
- flushBuffer();
- ptr = 0;
- max = mOutputBuffer.length;
- }
- // How much can we output?
- if (max > len) {
- max = len;
- }
- if (mCheckContent) {
- for (int inEnd = offset + max; offset < inEnd; ++offset) {
- int c = cbuf[offset];
- if (c < 32) {
- if (c == '\n') {
- // !!! TBI: line nr
- } else if (c == '\r') {
- // !!! TBI: line nr (and skipping \n that may follow)
- } else if (c != '\t') {
- mOutputPtr = ptr;
- c = handleInvalidChar(c);
- }
- } else if (c > 0x7E) {
- if (c > 0xFF) {
- mOutputPtr = ptr;
- handleInvalidLatinChar(c);
- } else if (mXml11) {
- if (c < 0x9F && c != 0x85) {
- mOutputPtr = ptr;
- c = handleInvalidChar(c);
- }
- }
- }
- mOutputBuffer[ptr++] = (byte) c;
- }
- } else {
- for (int inEnd = offset + max; offset < inEnd; ++offset) {
- mOutputBuffer[ptr++] = (byte) cbuf[offset];
- }
- }
- len -= max;
- }
- mOutputPtr = ptr;
- }
-
- public void writeRaw(String str, int offset, int len)
- throws IOException
- {
- if (mSurrogate != 0) {
- throwUnpairedSurrogate();
- }
- int ptr = mOutputPtr;
- while (len > 0) {
- int max = mOutputBuffer.length - ptr;
- if (max < 1) { // output buffer full?
- mOutputPtr = ptr;
- flushBuffer();
- ptr = 0;
- max = mOutputBuffer.length;
- }
- // How much can we output?
- if (max > len) {
- max = len;
- }
- if (mCheckContent) {
- for (int inEnd = offset + max; offset < inEnd; ++offset) {
- int c = str.charAt(offset);
- if (c < 32) {
- if (c == '\n') {
- // !!! TBI: line nr
- } else if (c == '\r') {
- // !!! TBI: line nr (and skipping \n that may follow)
- } else if (c != '\t') {
- mOutputPtr = ptr;
- c = handleInvalidChar(c);
- }
- } else if (c > 0x7E) {
- if (c > 0xFF) {
- mOutputPtr = ptr;
- handleInvalidLatinChar(c);
- } else if (mXml11) {
- if (c < 0x9F && c != 0x85) {
- mOutputPtr = ptr;
- c = handleInvalidChar(c);
- }
- }
- }
- mOutputBuffer[ptr++] = (byte) c;
- }
- } else {
- for (int inEnd = offset + max; offset < inEnd; ++offset) {
- mOutputBuffer[ptr++] = (byte) str.charAt(offset);
- }
- }
- len -= max;
- }
- mOutputPtr = ptr;
- }
-
- protected void writeAttrValue(String data)
- throws IOException
- {
- int offset = 0;
- int len = data.length();
- int ptr = mOutputPtr;
-
- main_loop:
- while (len > 0) {
- int max = mOutputBuffer.length - ptr;
- if (max < 1) { // output buffer full?
- mOutputPtr = ptr;
- flushBuffer();
- ptr = 0;
- max = mOutputBuffer.length;
- }
- // Do we start with a surrogate?
- if (mSurrogate != 0) {
- int sec = data.charAt(offset++);
- sec = calcSurrogate(sec);
- mOutputPtr = ptr;
- ptr = writeAsEntity(sec);
- --len;
- continue main_loop;
- }
- // How much can we output?
- if (max > len) {
- max = len;
- }
- inner_loop:
- for (int inEnd = offset + max; offset < inEnd; ) {
- int c = data.charAt(offset++);
- if (c < 32) {
- /* Need to quote all white space except for regular
- * space chars, to preserve them (round-tripping)
- */
- if (c == '\r') {
- if (!mEscapeCR) {
- mOutputBuffer[ptr++] = (byte) c;
- continue;
- }
- } else if (c != '\n' && c != '\t') {
- if (mCheckContent) {
- if (!mXml11 || c == 0) {
- c = handleInvalidChar(c);
- mOutputBuffer[ptr++] = (byte) c;
- continue;
- }
- }
- }
- // fall-through to char entity output
- } else if (c < 0x7F) {
- if (c != '<' && c != '&' && c != '"') {
- mOutputBuffer[ptr++] = (byte) c;
- continue;
- }
- // otherwise fall back on quoting
- } else if (c > 0x9F && c <= 0xFF) {
- mOutputBuffer[ptr++] = (byte) c;
- continue; // [WSTX-88]
- } else {
- // Surrogate?
- if (c >= SURR1_FIRST && c <= SURR2_LAST) {
- mSurrogate = c;
- // Last char needs special handling:
- if (offset == inEnd) {
- break inner_loop;
- }
- c = calcSurrogate(data.charAt(offset++));
- // Let's fall down to entity output
- }
- }
- /* Has to be escaped as char entity; as such, also need
- * to re-calc max. continguous data we can output
- */
- mOutputPtr = ptr;
- ptr = writeAsEntity(c);
- len = data.length() - offset;
- continue main_loop;
- }
- len -= max;
- }
- mOutputPtr = ptr;
- }
-
- protected void writeAttrValue(char[] data, int offset, int len)
- throws IOException
- {
- int ptr = mOutputPtr;
-
- main_loop:
- while (len > 0) {
- int max = mOutputBuffer.length - ptr;
- if (max < 1) { // output buffer full?
- mOutputPtr = ptr;
- flushBuffer();
- ptr = 0;
- max = mOutputBuffer.length;
- }
- // Do we start with a surrogate?
- if (mSurrogate != 0) {
- int sec = data[offset++];
- sec = calcSurrogate(sec);
- mOutputPtr = ptr;
- ptr = writeAsEntity(sec);
- --len;
- continue main_loop;
- }
- // How much can we output?
- if (max > len) {
- max = len;
- }
- inner_loop:
- for (int inEnd = offset + max; offset < inEnd; ) {
- int c = data[offset++];
- if (c < 32) {
- /* Need to quote all white space except for regular
- * space chars, to preserve them (round-tripping)
- */
- if (c == '\r') {
- if (!mEscapeCR) {
- mOutputBuffer[ptr++] = (byte) c;
- continue;
- }
- } else if (c != '\n' && c != '\t') {
- if (mCheckContent) {
- if (!mXml11 || c == 0) {
- c = handleInvalidChar(c);
- mOutputBuffer[ptr++] = (byte) c;
- continue;
- }
- }
- }
- // fall-through to char entity output
- } else if (c < 0x7F) {
- if (c != '<' && c != '&' && c != '"') {
- mOutputBuffer[ptr++] = (byte) c;
- continue;
- }
- // otherwise fall back on quoting
- } else if (c > 0x9F && c <= 0xFF) {
- mOutputBuffer[ptr++] = (byte) c;
- continue; // [WSTX-88]
- } else {
- // Surrogate?
- if (c >= SURR1_FIRST && c <= SURR2_LAST) {
- mSurrogate = c;
- // Last char needs special handling:
- if (offset == inEnd) {
- break inner_loop;
- }
- c = calcSurrogate(data[offset++]);
- // Let's fall down to entity output
- }
- }
- /* Has to be escaped as char entity; as such, also need
- * to re-calc max. contiguous data we can output
- */
- mOutputPtr = ptr;
- ptr = writeAsEntity(c);
- max -= (inEnd - offset); // since we didn't loop completely
- break inner_loop;
- }
- len -= max;
- }
- mOutputPtr = ptr;
- }
-
- protected int writeCDataContent(String data)
- throws IOException
- {
- // Note: mSurrogate can not be non-zero at this point, no need to check
-
- int offset = 0;
- int len = data.length();
- if (!mCheckContent) {
- writeRaw(data, offset, len);
- return -1;
- }
- int ptr = mOutputPtr;
-
- main_loop:
- while (len > 0) {
- int max = mOutputBuffer.length - ptr;
- if (max < 1) { // output buffer full?
- mOutputPtr = ptr;
- flushBuffer();
- ptr = 0;
- max = mOutputBuffer.length;
- }
- // How much can we output?
- if (max > len) {
- max = len;
- }
- for (int inEnd = offset + max; offset < inEnd; ) {
- int c = data.charAt(offset++);
- if (c < 32) {
- if (c == '\n') {
- // !!! TBI: line nr
- } else if (c == '\r') {
- // !!! TBI: line nr (and skipping \n that may follow)
- } else if (c != '\t') {
- mOutputPtr = ptr;
- c = handleInvalidChar(c);
- }
- } else if (c > 0x7E) {
- if (c > 0xFF) {
- mOutputPtr = ptr;
- handleInvalidLatinChar(c);
- } else if (mXml11) {
- if (c < 0x9F && c != 0x85) {
- mOutputPtr = ptr;
- c = handleInvalidChar(c);
- }
- }
- } else if (c == '>') { // embedded "]]>"?
- if (offset > 2 && data.charAt(offset-2) == ']'
- && data.charAt(offset-3) == ']') {
- if (!mFixContent) {
- return offset-3;
- }
- /* Relatively easy fix; just need to close this
- * section, and open a new one...
- */
- mOutputPtr = ptr;
- writeCDataEnd();
- writeCDataStart();
- writeAscii(BYTE_GT);
- ptr = mOutputPtr;
- /* No guarantees there's as much free room in the
- * output buffer, thus, need to restart loop:
- */
- len = data.length() - offset;
- continue main_loop;
- }
- }
- mOutputBuffer[ptr++] = (byte) c;
- }
- len -= max;
- }
- mOutputPtr = ptr;
- return -1;
- }
-
- protected int writeCDataContent(char[] cbuf, int start, int len)
- throws IOException
- {
- // Note: mSurrogate can not be non-zero at this point, no need to check
-
- if (!mCheckContent) {
- writeRaw(cbuf, start, len);
- return -1;
- }
-
- int ptr = mOutputPtr;
- int offset = start;
-
- while (len > 0) {
- int max = mOutputBuffer.length - ptr;
- if (max < 1) { // output buffer full?
- mOutputPtr = ptr;
- flushBuffer();
- ptr = 0;
- max = mOutputBuffer.length;
- }
- // How much can we output?
- if (max > len) {
- max = len;
- }
- inner_loop:
- for (int inEnd = offset + max; offset < inEnd; ) {
- int c = cbuf[offset++];
- if (c < 32) {
- if (c == '\n') {
- // !!! TBI: line nr
- } else if (c == '\r') {
- // !!! TBI: line nr (and skipping \n that may follow)
- } else if (c != '\t') {
- mOutputPtr = ptr;
- c = handleInvalidChar(c);
- }
- } else if (c > 0x7E) {
- if (c > 0xFF) {
- mOutputPtr = ptr;
- handleInvalidLatinChar(c);
- } else if (mXml11) {
- if (c < 0x9F && c != 0x85) {
- mOutputPtr = ptr;
- c = handleInvalidChar(c);
- }
- }
- } else if (c == '>') { // embedded "]]>"?
- if (offset >= (start+3) && cbuf[offset-2] == ']'
- && cbuf[offset-3] == ']') {
- if (!mFixContent) {
- return offset-3;
- }
- /* Relatively easy fix; just need to close this
- * section, and open a new one...
- */
- mOutputPtr = ptr;
- writeCDataEnd();
- writeCDataStart();
- writeAscii(BYTE_GT);
- ptr = mOutputPtr;
- /* No guarantees there's as much free room in the
- * output buffer, thus, need to restart loop:
- */
- max -= (inEnd - offset);
- break inner_loop;
- }
- }
- mOutputBuffer[ptr++] = (byte) c;
- }
- len -= max;
- }
- mOutputPtr = ptr;
- return -1;
- }
-
- protected int writeCommentContent(String data)
- throws IOException
- {
- // Note: mSurrogate can not be non-zero at this point, no need to check
-
- int offset = 0;
- int len = data.length();
- if (!mCheckContent) {
- writeRaw(data, offset, len);
- return -1;
- }
-
- int ptr = mOutputPtr;
-
- while (len > 0) {
- int max = mOutputBuffer.length - ptr;
- if (max < 1) { // output buffer full?
- mOutputPtr = ptr;
- flushBuffer();
- ptr = 0;
- max = mOutputBuffer.length;
- }
- // How much can we output?
- if (max > len) {
- max = len;
- }
- inner_loop:
- for (int inEnd = offset + max; offset < inEnd; ) {
- int c = data.charAt(offset++);
- if (c < 32) {
- if (c == '\n') {
- // !!! TBI: line nr
- } else if (c == '\r') {
- // !!! TBI: line nr (and skipping \n that may follow)
- } else if (c != '\t') {
- mOutputPtr = ptr;
- c = handleInvalidChar(c);
- }
- } else if (c > 0x7E) {
- if (c > 0xFF) {
- mOutputPtr = ptr;
- handleInvalidLatinChar(c);
- } else if (mXml11) {
- if (c < 0x9F && c != 0x85) {
- mOutputPtr = ptr;
- c = handleInvalidChar(c);
- }
- }
- } else if (c == '-') { // embedded "--"?
- if (offset > 1 && data.charAt(offset-2) == '-') {
- if (!mFixContent) {
- return offset-2;
- }
- /* Quite easy to fix: just add an extra space
- * in front. There will be room for that char;
- * but may need to take that the following '-'
- * also fits.
- */
- mOutputBuffer[ptr++] = ' ';
- if (ptr >= mOutputBuffer.length) { // whops. need to flush
- mOutputPtr = ptr;
- flushBuffer();
- ptr = 0;
- }
- mOutputBuffer[ptr++] = BYTE_HYPHEN;
- /* Also, since we did output an extra char, better
- * restart the loop (since max calculation is now
- * off)
- */
- max -= (inEnd - offset);
- break inner_loop;
- }
- }
- mOutputBuffer[ptr++] = (byte) c;
- }
- len -= max;
- }
- mOutputPtr = ptr;
- return -1;
- }
-
- protected int writePIData(String data)
- throws IOException, XMLStreamException
- {
- // Note: mSurrogate can not be non-zero at this point, no need to check
-
- int offset = 0;
- int len = data.length();
- if (!mCheckContent) {
- writeRaw(data, offset, len);
- return -1;
- }
-
- int ptr = mOutputPtr;
- while (len > 0) {
- int max = mOutputBuffer.length - ptr;
- if (max < 1) { // output buffer full?
- mOutputPtr = ptr;
- flushBuffer();
- ptr = 0;
- max = mOutputBuffer.length;
- }
- // How much can we output?
- if (max > len) {
- max = len;
- }
- for (int inEnd = offset + max; offset < inEnd; ++offset) {
- int c = data.charAt(offset);
- if (c < 32) {
- if (c == '\n') {
- // !!! TBI: line nr
- } else if (c == '\r') {
- // !!! TBI: line nr (and skipping \n that may follow)
- } else if (c != '\t') {
- mOutputPtr = ptr;
- c = handleInvalidChar(c);
- }
- } else if (c > 0x7E) {
- if (c > 0xFF) {
- mOutputPtr = ptr;
- handleInvalidLatinChar(c);
- } else if (mXml11) {
- if (c < 0x9F && c != 0x85) {
- mOutputPtr = ptr;
- c = handleInvalidChar(c);
- }
- }
- } else if (c == '>') { // enclosed end marker ("?>")?
- if (offset > 0 && data.charAt(offset-1) == '?') {
- return offset-2;
- }
- }
- mOutputBuffer[ptr++] = (byte) c;
- }
- len -= max;
- }
- mOutputPtr = ptr;
- return -1;
- }
-
- protected void writeTextContent(String data)
- throws IOException
- {
- int offset = 0;
- int len = data.length();
-
- main_loop:
- while (len > 0) {
- int max = mOutputBuffer.length - mOutputPtr;
- if (max < 1) { // output buffer full?
- flushBuffer();
- max = mOutputBuffer.length;
- }
- // Do we start with a surrogate?
- if (mSurrogate != 0) {
- int sec = data.charAt(offset++);
- sec = calcSurrogate(sec);
- writeAsEntity(sec);
- --len;
- continue main_loop;
- }
- // How much can we output?
- if (max > len) {
- max = len;
- }
- inner_loop:
- for (int inEnd = offset + max; offset < inEnd; ) {
- int c = data.charAt(offset++);
- if (c < 32) {
- if (c == '\n' || c == '\t') { // TODO: line count
- mOutputBuffer[mOutputPtr++] = (byte) c;
- continue;
- } else if (c == '\r') {
- if (!mEscapeCR) {
- mOutputBuffer[mOutputPtr++] = (byte) c;
- continue;
- }
- } else if (!mXml11 || c == 0) { // ok in xml1.1, as entity
- if (mCheckContent) {
- c = handleInvalidChar(c);
- mOutputBuffer[mOutputPtr++] = (byte) c;
- continue;
- }
- // otherwise... well, I guess we can just escape it
- }
- // \r, or xml1.1 + other whitespace, need to escape
- } else if (c < 0x7F) {
- if (c != '<' && c != '&') {
- if (c != '>' || (offset > 1 && data.charAt(offset-2) != ']')) {
- mOutputBuffer[mOutputPtr++] = (byte) c;
- continue;
- }
- }
- // otherwise fall back on quoting
- } else if (c > 0x9F && c <= 0xFF) {
- mOutputBuffer[mOutputPtr++] = (byte) c;
- continue; // [WSTX-88]
- } else {
- // Surrogate?
- if (c >= SURR1_FIRST && c <= SURR2_LAST) {
- mSurrogate = c;
- // Last char needs special handling:
- if (offset == inEnd) {
- break inner_loop;
- }
- c = calcSurrogate(data.charAt(offset++));
- // Let's fall down to entity output
- }
- }
- /* Has to be escaped as char entity; as such, also need
- * to re-calc max. continguous data we can output
- */
- writeAsEntity(c);
- len = data.length() - offset;
- continue main_loop;
- }
- len -= max;
- }
- }
-
- protected void writeTextContent(char[] cbuf, int offset, int len)
- throws IOException
- {
- main_loop:
- while (len > 0) {
- int max = mOutputBuffer.length - mOutputPtr;
- if (max < 1) { // output buffer full?
- flushBuffer();
- max = mOutputBuffer.length;
- }
- // Do we start with a surrogate?
- if (mSurrogate != 0) {
- int sec = cbuf[offset++];
- sec = calcSurrogate(sec);
- writeAsEntity(sec);
- --len;
- continue main_loop;
- }
- // How much can we output?
- if (max > len) {
- max = len;
- }
- inner_loop:
- for (int inEnd = offset + max; offset < inEnd; ) {
- int c = cbuf[offset++];
- if (c < 32) {
- if (c == '\n' || c == '\t') { // TODO: line count
- mOutputBuffer[mOutputPtr++] = (byte) c;
- continue;
- } else if (c == '\r') {
- if (!mEscapeCR) {
- mOutputBuffer[mOutputPtr++] = (byte) c;
- continue;
- }
- } else if (!mXml11 || c == 0) { // ok in xml1.1, as entity
- if (mCheckContent) {
- c = handleInvalidChar(c);
- mOutputBuffer[mOutputPtr++] = (byte) c;
- continue;
- }
- // otherwise... well, I guess we can just escape it
- }
- // \r, or xml1.1 + other whitespace, need to escape
- } else if (c < 0x7F) {
- if (c !='<' && c != '&') {
- /* Since we can be conservative, it doesn't matter
- * if second check is not exact
- */
- if (c != '>' || (offset > 1 && cbuf[offset-2] != ']')) {
- mOutputBuffer[mOutputPtr++] = (byte) c;
- continue;
- }
- }
- // otherwise fall back on quoting
- } else if (c > 0x9F && c <= 0xFF) {
- mOutputBuffer[mOutputPtr++] = (byte) c;
- continue; // [WSTX-88]
- } else {
- // Surrogate?
- if (c >= SURR1_FIRST && c <= SURR2_LAST) {
- mSurrogate = c;
- // Last char needs special handling:
- if (offset == inEnd) {
- break inner_loop;
- }
- c = calcSurrogate(cbuf[offset++]);
- // Let's fall down to entity output
- }
- }
- /* Has to be escaped as char entity; as such, also need
- * to re-calc max. continguous data we can output
- */
- writeAsEntity(c);
- max -= (inEnd - offset);
- break inner_loop;
- }
- len -= max;
- }
- }
-
- /*
- ////////////////////////////////////////////////////
- // Internal methods
- ////////////////////////////////////////////////////
- */
-
- protected void handleInvalidLatinChar(int c)
- throws IOException
- {
- // First, let's flush any output we may have, to make debugging easier
- flush();
-
- /* 17-May-2006, TSa: Would really be useful if we could throw
- * XMLStreamExceptions; esp. to indicate actual output location.
- * However, this causes problem with methods that call us and
- * can only throw IOExceptions (when invoked via Writer proxy).
- * Need to figure out how to resolve this.
- */
- throw new IOException("Invalid XML character (0x"+Integer.toHexString(c)+"); can only be output using character entity when using ISO-8859-1 encoding");
- }
-}
diff -Nru libwoodstox-java-4.1.3/src/java/com/ctc/wstx/sw/NonNsStreamWriter.java libwoodstox-java-5.1.0/src/java/com/ctc/wstx/sw/NonNsStreamWriter.java
--- libwoodstox-java-4.1.3/src/java/com/ctc/wstx/sw/NonNsStreamWriter.java 2012-04-24 04:38:20.000000000 +0000
+++ libwoodstox-java-5.1.0/src/java/com/ctc/wstx/sw/NonNsStreamWriter.java 1970-01-01 00:00:00.000000000 +0000
@@ -1,553 +0,0 @@
-/* Woodstox XML processor
- *
- * Copyright (c) 2004- Tatu Saloranta, tatu.saloranta@iki.fi
- *
- * Licensed under the License specified in the file LICENSE which is
- * included with the source code.
- * You may not use this file except in compliance with the License.
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.ctc.wstx.sw;
-
-import java.io.IOException;
-import java.util.*;
-
-import javax.xml.XMLConstants;
-import javax.xml.namespace.NamespaceContext;
-import javax.xml.namespace.QName;
-import javax.xml.stream.XMLStreamWriter;
-import javax.xml.stream.XMLStreamException;
-import javax.xml.stream.events.Attribute;
-import javax.xml.stream.events.StartElement;
-
-import org.codehaus.stax2.ri.typed.AsciiValueEncoder;
-
-import com.ctc.wstx.api.WriterConfig;
-import com.ctc.wstx.cfg.ErrorConsts;
-import com.ctc.wstx.cfg.XmlConsts;
-import com.ctc.wstx.sr.AttributeCollector;
-import com.ctc.wstx.sr.InputElementStack;
-import com.ctc.wstx.util.EmptyNamespaceContext;
-import com.ctc.wstx.util.StringVector;
-
-/**
- * Implementation of {@link XMLStreamWriter} used when namespace support
- * is not enabled. This means that only local names are used for elements
- * and attributes; and if rudimentary namespace declarations need to be
- * output, they are output using attribute writing methods.
- */
-public class NonNsStreamWriter
- extends TypedStreamWriter
-{
- /*
- ////////////////////////////////////////////////////
- // State information
- ////////////////////////////////////////////////////
- */
-
- /**
- * Stack of currently open start elements; only local names
- * are included.
- */
- final StringVector mElements;
-
- /**
- * Container for attribute names for current element; used only
- * if uniqueness of attribute names is to be enforced.
- *
- * TreeSet is used mostly because clearing it up is faster than
- * clearing up HashSet, and the only access is done by
- * adding entries and see if an value was already set.
- */
- TreeSet mAttrNames;
-
- /*
- ////////////////////////////////////////////////////
- // Life-cycle (ctors)
- ////////////////////////////////////////////////////
- */
-
- public NonNsStreamWriter(XmlWriter xw, String enc, WriterConfig cfg)
- {
- super(xw, enc, cfg);
- mElements = new StringVector(32);
- }
-
- /*
- ////////////////////////////////////////////////////
- // XMLStreamWriter API
- ////////////////////////////////////////////////////
- */
-
- public NamespaceContext getNamespaceContext() {
- return EmptyNamespaceContext.getInstance();
- }
-
- public String getPrefix(String uri) {
- return null;
- }
-
- public void setDefaultNamespace(String uri)
- throws XMLStreamException
- {
- reportIllegalArg("Can not set default namespace for non-namespace writer.");
- }
-
- public void setNamespaceContext(NamespaceContext context)
- {
- reportIllegalArg("Can not set NamespaceContext for non-namespace writer.");
- }
-
- public void setPrefix(String prefix, String uri)
- throws XMLStreamException
- {
- reportIllegalArg("Can not set namespace prefix for non-namespace writer.");
- }
-
- public void writeAttribute(String localName, String value)
- throws XMLStreamException
- {
- // No need to set mAnyOutput, nor close the element
- if (!mStartElementOpen && mCheckStructure) {
- reportNwfStructure(ErrorConsts.WERR_ATTR_NO_ELEM);
- }
- if (mCheckAttrs) {
- /* 11-Dec-2005, TSa: Should use a more efficient Set/Map value
- * for this in future.
- */
- if (mAttrNames == null) {
- mAttrNames = new TreeSet();
- }
- if (!mAttrNames.add(localName)) {
- reportNwfAttr("Trying to write attribute '"+localName+"' twice");
- }
- }
- if (mValidator != null) {
- /* No need to get it normalized... even if validator does normalize
- * it, we don't use that for anything
- */
- mValidator.validateAttribute(localName, XmlConsts.ATTR_NO_NS_URI, XmlConsts.ATTR_NO_PREFIX, value);
- }
-
- try {
- mWriter.writeAttribute(localName, value);
- } catch (IOException ioe) {
- throwFromIOE(ioe);
- }
- }
-
- public void writeAttribute(String nsURI, String localName, String value)
- throws XMLStreamException
- {
- writeAttribute(localName, value);
- }
-
- public void writeAttribute(String prefix, String nsURI,
- String localName, String value)
- throws XMLStreamException
- {
- writeAttribute(localName, value);
- }
-
- public void writeDefaultNamespace(String nsURI)
- throws XMLStreamException
- {
- reportIllegalMethod("Can not call writeDefaultNamespace namespaces with non-namespace writer.");
- }
-
- public void writeEmptyElement(String localName)
- throws XMLStreamException
- {
- doWriteStartElement(localName);
- mEmptyElement = true;
- }
-
- public void writeEmptyElement(String nsURI, String localName)
- throws XMLStreamException
- {
- writeEmptyElement(localName);
- }
-
- public void writeEmptyElement(String prefix, String localName, String nsURI)
- throws XMLStreamException
- {
- writeEmptyElement(localName);
- }
-
- public void writeEndElement()
- throws XMLStreamException
- {
- doWriteEndTag(null, mCfgAutomaticEmptyElems);
- }
-
- public void writeNamespace(String prefix, String nsURI)
- throws XMLStreamException
- {
- reportIllegalMethod("Can not set write namespaces with non-namespace writer.");
- }
-
- public void writeStartElement(String localName)
- throws XMLStreamException
- {
- doWriteStartElement(localName);
- mEmptyElement = false;
- }
-
- public void writeStartElement(String nsURI, String localName)
- throws XMLStreamException
- {
- writeStartElement(localName);
- }
-
- public void writeStartElement(String prefix, String localName, String nsURI)
- throws XMLStreamException
- {
- writeStartElement(localName);
- }
-
- /*
- ////////////////////////////////////////////////////
- // Remaining XMLStreamWriter2 methods (StAX2)
- ////////////////////////////////////////////////////
- */
-
- /**
- * Similar to {@link #writeEndElement}, but never allows implicit
- * creation of empty elements.
- */
- public void writeFullEndElement()
- throws XMLStreamException
- {
- doWriteEndTag(null, false);
- }
-
- /*
- ////////////////////////////////////////////////////
- // Remaining ValidationContext methods (StAX2)
- ////////////////////////////////////////////////////
- */
-
- public QName getCurrentElementName() {
- if (mElements.isEmpty()) {
- return null;
- }
- return new QName(mElements.getLastString());
- }
-
- public String getNamespaceURI(String prefix) {
- return null;
- }
-
- /*
- ////////////////////////////////////////////////////
- // Package methods:
- ////////////////////////////////////////////////////
- */
-
- public void writeStartElement(StartElement elem)
- throws XMLStreamException
- {
- QName name = elem.getName();
- writeStartElement(name.getLocalPart());
- Iterator it = elem.getAttributes();
- while (it.hasNext()) {
- Attribute attr = (Attribute) it.next();
- name = attr.getName();
- writeAttribute(name.getLocalPart(), attr.getValue());
- }
- }
-
- /**
- * Method called by {@link javax.xml.stream.XMLEventWriter} implementation
- * (instead of the version
- * that takes no argument), so that we can verify it does match the
- * start element, if necessary
- */
- public void writeEndElement(QName name)
- throws XMLStreamException
- {
- doWriteEndTag(mCheckStructure ? name.getLocalPart() : null,
- mCfgAutomaticEmptyElems);
- }
-
- protected void writeTypedAttribute(String prefix, String nsURI, String localName,
- AsciiValueEncoder enc)
- throws XMLStreamException
- {
- // note: mostly copied from the other writeAttribute() method..
- if (!mStartElementOpen && mCheckStructure) {
- reportNwfStructure(ErrorConsts.WERR_ATTR_NO_ELEM);
- }
- if (mCheckAttrs) { // doh. Not good, need to construct non-transient value...
- if (mAttrNames == null) {
- mAttrNames = new TreeSet();
- }
- if (!mAttrNames.add(localName)) {
- reportNwfAttr("Trying to write attribute '"+localName+"' twice");
- }
- }
-
- try {
- if (mValidator == null) {
- mWriter.writeTypedAttribute(localName, enc);
- } else {
- mWriter.writeTypedAttribute(null, localName, null, enc, mValidator, getCopyBuffer());
- }
- } catch (IOException ioe) {
- throwFromIOE(ioe);
- }
- }
-
- /**
- * Method called to close an open start element, when another
- * main-level element (not namespace declaration or
- * attribute) is being output; except for end element which is
- * handled differently.
- */
- protected void closeStartElement(boolean emptyElem)
- throws XMLStreamException
- {
- mStartElementOpen = false;
- if (mAttrNames != null) {
- mAttrNames.clear();
- }
-
- try {
- if (emptyElem) {
- mWriter.writeStartTagEmptyEnd();
- } else {
- mWriter.writeStartTagEnd();
- }
- } catch (IOException ioe) {
- throwFromIOE(ioe);
- }
-
- if (mValidator != null) {
- mVldContent = mValidator.validateElementAndAttributes();
- }
-
- // Need bit more special handling for empty elements...
- if (emptyElem) {
- String localName = mElements.removeLast();
- if (mElements.isEmpty()) {
- mState = STATE_EPILOG;
- }
- if (mValidator != null) {
- mVldContent = mValidator.validateElementEnd(localName, XmlConsts.ELEM_NO_NS_URI, XmlConsts.ELEM_NO_PREFIX);
- }
- }
- }
-
- /**
- * Element copier method implementation suitable to be used with
- * non-namespace-aware writers. The only special thing here is that
- * the copier can convert namespace declarations to equivalent
- * attribute writes.
- */
- public void copyStartElement(InputElementStack elemStack,
- AttributeCollector attrCollector)
- throws IOException, XMLStreamException
- {
- String ln = elemStack.getLocalName();
- boolean nsAware = elemStack.isNamespaceAware();
-
- /* First, since we are not to output namespace stuff as is,
- * we just need to copy the element:
- */
- if (nsAware) { // but reader is ns-aware? Need to add prefix?
- String prefix = elemStack.getPrefix();
- if (prefix != null && prefix.length() > 0) { // yup
- ln = prefix + ":" + ln;
- }
- }
- writeStartElement(ln);
-
- /* However, if there are any namespace declarations, we probably
- * better output them just as 'normal' attributes:
- */
- if (nsAware) {
- int nsCount = elemStack.getCurrentNsCount();
- if (nsCount > 0) {
- for (int i = 0; i < nsCount; ++i) {
- String prefix = elemStack.getLocalNsPrefix(i);
- if (prefix == null || prefix.length() == 0) { // default NS decl
- prefix = XMLConstants.XML_NS_PREFIX;
- } else {
- prefix = "xmlns:"+prefix;
- }
- writeAttribute(prefix, elemStack.getLocalNsURI(i));
- }
- }
- }
-
- /* And then let's just output attributes, if any (whether to copy
- * implicit, aka "default" attributes, is configurable)
- */
- int attrCount = mCfgCopyDefaultAttrs ?
- attrCollector.getCount() :
- attrCollector.getSpecifiedCount();
-
- if (attrCount > 0) {
- for (int i = 0; i < attrCount; ++i) {
- attrCollector.writeAttribute(i, mWriter);
- }
- }
- }
-
- protected String getTopElementDesc()
- {
- return mElements.isEmpty() ? "#root" : mElements.getLastString();
- }
-
- public String validateQNamePrefix(QName name)
- {
- // Can either strip prefix out, or return as is
- return name.getPrefix();
- }
-
- /*
- ////////////////////////////////////////////////////
- // Internal methods
- ////////////////////////////////////////////////////
- */
-
- private void doWriteStartElement(String localName)
- throws XMLStreamException
- {
- mAnyOutput = true;
- // Need to finish an open start element?
- if (mStartElementOpen) {
- closeStartElement(mEmptyElement);
- } else if (mState == STATE_PROLOG) {
- // 20-Dec-2005, TSa: Does this match DOCTYPE declaration?
- verifyRootElement(localName, null);
- } else if (mState == STATE_EPILOG) {
- if (mCheckStructure) {
- reportNwfStructure(ErrorConsts.WERR_PROLOG_SECOND_ROOT, localName);
- }
- // Outputting fragment? Better reset to tree, then...
- mState = STATE_TREE;
- }
-
- /* Note: need not check for CONTENT_ALLOW_NONE here, since the
- * validator should handle this particular case...
- */
- /*if (mVldContent == XMLValidator.CONTENT_ALLOW_NONE) { // EMPTY content
- reportInvalidContent(START_ELEMENT);
- }*/
- if (mValidator != null) {
- mValidator.validateElementStart(localName, XmlConsts.ELEM_NO_NS_URI, XmlConsts.ELEM_NO_PREFIX);
- }
-
- mStartElementOpen = true;
- mElements.addString(localName);
- try {
- mWriter.writeStartTagStart(localName);
- } catch (IOException ioe) {
- throwFromIOE(ioe);
- }
- }
-
- /**
- *
- * Note: Caller has to do actual removal of the element from element
- * stack, before calling this method.
- *
- * @param expName Name that the closing element should have; null
- * if whatever is in stack should be used
- * @param allowEmpty If true, is allowed to create the empty element
- * if the closing element was truly empty; if false, has to write
- * the full empty element no matter what
- */
- private void doWriteEndTag(String expName, boolean allowEmpty)
- throws XMLStreamException
- {
- /* First of all, do we need to close up an earlier empty element?
- * (open start element that was not created via call to
- * writeEmptyElement gets handled later on)
- */
- if (mStartElementOpen && mEmptyElement) {
- mEmptyElement = false;
- // note: this method guarantees proper updates to validation
- closeStartElement(true);
- }
-
- // Better have something to close... (to figure out what to close)
- if (mState != STATE_TREE) {
- // Have to throw an exception always, don't know elem name
- reportNwfStructure("No open start element, when trying to write end element");
- }
-
- /* Now, do we have an unfinished start element (created via
- * writeStartElement() earlier)?
- */
- String localName = mElements.removeLast();
- if (mCheckStructure) {
- if (expName != null && !localName.equals(expName)) {
- /* Only gets called when trying to output an XMLEvent... in
- * which case names can actually be compared
- */
- reportNwfStructure("Mismatching close element name, '"+localName+"'; expected '"+expName+"'.");
- }
- }
-
- /* Can't yet validate, since we have two paths; one for empty
- * elements, another for non-empty...
- */
-
- // Got a half output start element to close?
- if (mStartElementOpen) {
- /* Can't/shouldn't call closeStartElement, but need to do same
- * processing. Thus, this is almost identical to closeStartElement:
- */
- if (mValidator != null) {
- /* Note: return value is not of much use, since the
- * element will be closed right away...
- */
- mVldContent = mValidator.validateElementAndAttributes();
- }
- mStartElementOpen = false;
- if (mAttrNames != null) {
- mAttrNames.clear();
- }
- try {
- // We could write an empty element, implicitly?
- if (allowEmpty) {
- mWriter.writeStartTagEmptyEnd();
- if (mElements.isEmpty()) {
- mState = STATE_EPILOG;
- }
- if (mValidator != null) {
- mVldContent = mValidator.validateElementEnd(localName, XmlConsts.ELEM_NO_NS_URI, XmlConsts.ELEM_NO_PREFIX);
- }
- return;
- }
- // Nah, need to close open elem, and then output close elem
- mWriter.writeStartTagEnd();
- } catch (IOException ioe) {
- throwFromIOE(ioe);
- }
- }
-
- try {
- mWriter.writeEndTag(localName);
- } catch (IOException ioe) {
- throwFromIOE(ioe);
- }
-
- if (mElements.isEmpty()) {
- mState = STATE_EPILOG;
- }
-
- // Ok, time to validate...
- if (mValidator != null) {
- mVldContent = mValidator.validateElementEnd(localName, XmlConsts.ELEM_NO_NS_URI, XmlConsts.ELEM_NO_PREFIX);
- }
- }
-}
diff -Nru libwoodstox-java-4.1.3/src/java/com/ctc/wstx/sw/OutputElementBase.java libwoodstox-java-5.1.0/src/java/com/ctc/wstx/sw/OutputElementBase.java
--- libwoodstox-java-4.1.3/src/java/com/ctc/wstx/sw/OutputElementBase.java 2012-04-24 04:38:20.000000000 +0000
+++ libwoodstox-java-5.1.0/src/java/com/ctc/wstx/sw/OutputElementBase.java 1970-01-01 00:00:00.000000000 +0000
@@ -1,373 +0,0 @@
-/* Woodstox XML processor
- *
- * 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 com.ctc.wstx.sw;
-
-import java.util.*;
-
-import javax.xml.XMLConstants;
-import javax.xml.namespace.NamespaceContext;
-import javax.xml.stream.XMLStreamException;
-
-import org.codehaus.stax2.ri.EmptyIterator;
-
-import com.ctc.wstx.util.BijectiveNsMap;
-
-/**
- * Class that encapsulates information about a specific element in virtual
- * output stack for namespace-aware writers.
- * It provides support for URI-to-prefix mappings as well as namespace
- * mapping generation.
- *
- * One noteworthy feature of the class is that it is designed to allow
- * "short-term recycling", ie. instances can be reused within context
- * of a simple document output. While reuse/recycling of such lightweight
- * object is often useless or even counter productive, here it may
- * be worth using, due to simplicity of the scheme (basically using
- * a very simple free-elements linked list).
- */
-public abstract class OutputElementBase
- implements NamespaceContext
-{
- public final static int PREFIX_UNBOUND = 0;
- public final static int PREFIX_OK = 1;
- public final static int PREFIX_MISBOUND = 2;
-
- final static String sXmlNsPrefix = XMLConstants.XML_NS_PREFIX;
- final static String sXmlNsURI = XMLConstants.XML_NS_URI;
-
- /*
- ////////////////////////////////////////////
- // Namespace binding/mapping information
- ////////////////////////////////////////////
- */
-
- /**
- * Namespace context end application may have supplied, and that
- * (if given) should be used to augment explicitly defined bindings.
- */
- protected NamespaceContext mRootNsContext;
-
- protected String mDefaultNsURI;
-
- /**
- * Mapping of namespace prefixes to URIs and back.
- */
- protected BijectiveNsMap mNsMapping;
-
- /**
- * True, if {@link #mNsMapping} is a shared copy from the parent;
- * false if a local copy was created (which happens when namespaces
- * get bound etc).
- */
- protected boolean mNsMapShared;
-
- /*
- ////////////////////////////////////////////
- // Life-cycle
- ////////////////////////////////////////////
- */
-
- /**
- * Constructor for the virtual root element
- */
- protected OutputElementBase()
- {
- mNsMapping = null;
- mNsMapShared = false;
- mDefaultNsURI = "";
- mRootNsContext = null;
- }
-
- protected OutputElementBase(OutputElementBase parent, BijectiveNsMap ns)
- {
- mNsMapping = ns;
- mNsMapShared = (ns != null);
- mDefaultNsURI = parent.mDefaultNsURI;
- mRootNsContext = parent.mRootNsContext;
- }
-
- /**
- * Method called to reuse a pooled instance.
- */
- protected void relink(OutputElementBase parent)
- {
- mNsMapping = parent.mNsMapping;
- mNsMapShared = (mNsMapping != null);
- mDefaultNsURI = parent.mDefaultNsURI;
- mRootNsContext = parent.mRootNsContext;
- }
-
- protected abstract void setRootNsContext(NamespaceContext ctxt);
-
- /*
- ////////////////////////////////////////////
- // Public API, accessors
- ////////////////////////////////////////////
- */
-
- public abstract boolean isRoot();
-
- /**
- * @return String presentation of the fully-qualified name, in
- * "prefix:localName" format (no URI). Useful for error and
- * debugging messages.
- */
- public abstract String getNameDesc();
-
- public final String getDefaultNsUri() {
- return mDefaultNsURI;
- }
-
- /*
- ////////////////////////////////////////////
- // Public API, ns binding, checking
- ////////////////////////////////////////////
- */
-
- /**
- * Method similar to {@link #getPrefix}, but one that will not accept
- * the default namespace, only an explicit one. Usually used when
- * trying to find a prefix for attributes.
- */
- public final String getExplicitPrefix(String uri)
- {
- if (mNsMapping != null) {
- String prefix = mNsMapping.findPrefixByUri(uri);
- if (prefix != null) {
- return prefix;
- }
- }
- if (mRootNsContext != null) {
- String prefix = mRootNsContext.getPrefix(uri);
- if (prefix != null) {
- // Hmmh... still can't use the default NS:
- if (prefix.length() > 0) {
- return prefix;
- }
- // ... should we try to find an explicit one?
- }
- }
- return null;
- }
-
- /**
- * Method that verifies that passed-in prefix indeed maps to the specified
- * namespace URI; and depending on how it goes returns a status for
- * caller.
- *
- * @param isElement If true, rules for the default NS are those of elements
- * (ie. empty prefix can map to non-default namespace); if false,
- * rules are those of attributes (only non-default prefix can map to
- * a non-default namespace).
- *
- * @return PREFIX_OK, if passed-in prefix matches matched-in namespace URI
- * in current scope; PREFIX_UNBOUND if it's not bound to anything,
- * and PREFIX_MISBOUND if it's bound to another URI.
- *
- * @throws XMLStreamException True if default (no) prefix is allowed to
- * match a non-default URI (elements); false if not (attributes)
- */
- public final int isPrefixValid(String prefix, String nsURI,
- boolean isElement)
- throws XMLStreamException
- {
- // Hmmm.... caller shouldn't really pass null.
- if (nsURI == null) {
- nsURI = "";
- }
-
- /* First thing is to see if specified prefix is bound to a namespace;
- * and if so, verify it matches with data passed in:
- */
-
- // Checking default namespace?
- if (prefix == null || prefix.length() == 0) {
- if (isElement) {
- // It's fine for elements only if the URI actually matches:
- if (nsURI == mDefaultNsURI || nsURI.equals(mDefaultNsURI)) {
- return PREFIX_OK;
- }
- } else {
- /* Attributes never use the default namespace: "no prefix"
- * can only mean "no namespace"
- */
- if (nsURI.length() == 0) {
- return PREFIX_OK;
- }
- }
- return PREFIX_MISBOUND;
- }
-
- /* Need to handle 'xml' prefix and its associated
- * URI; they are always declared by default
- */
- if (prefix.equals(sXmlNsPrefix)) {
- // Should we thoroughly verify its namespace matches...?
- // 01-Apr-2005, TSa: Yes, let's always check this
- if (!nsURI.equals(sXmlNsURI)) {
- throwOutputError("Namespace prefix '"+sXmlNsPrefix
- +"' can not be bound to non-default namespace ('"+nsURI+"'); has to be the default '"
- +sXmlNsURI+"'");
- }
- return PREFIX_OK;
- }
-
- // Nope checking some other namespace
- String act;
-
- if (mNsMapping != null) {
- act = mNsMapping.findUriByPrefix(prefix);
- } else {
- act = null;
- }
-
- if (act == null && mRootNsContext != null) {
- act = mRootNsContext.getNamespaceURI(prefix);
- }
-
- // Not (yet) bound...
- if (act == null) {
- return PREFIX_UNBOUND;
- }
-
- return (act == nsURI || act.equals(nsURI)) ?
- PREFIX_OK : PREFIX_MISBOUND;
- }
-
- /*
- ////////////////////////////////////////////
- // Public API, mutators
- ////////////////////////////////////////////
- */
-
- public abstract void setDefaultNsUri(String uri);
-
- public final String generateMapping(String prefixBase, String uri, int[] seqArr)
- {
- // This is mostly cut'n pasted from addPrefix()...
- if (mNsMapping == null) {
- // Didn't have a mapping yet? Need to create one...
- mNsMapping = BijectiveNsMap.createEmpty();
- } else if (mNsMapShared) {
- /* Was shared with parent(s)? Need to create a derivative, to
- * allow for nesting/scoping of new prefix
- */
- mNsMapping = mNsMapping.createChild();
- mNsMapShared = false;
- }
- return mNsMapping.addGeneratedMapping(prefixBase, mRootNsContext,
- uri, seqArr);
- }
-
- public final void addPrefix(String prefix, String uri)
- {
- if (mNsMapping == null) {
- // Didn't have a mapping yet? Need to create one...
- mNsMapping = BijectiveNsMap.createEmpty();
- } else if (mNsMapShared) {
- /* Was shared with parent(s)? Need to create a derivative, to
- * allow for nesting/scoping of new prefix
- */
- mNsMapping = mNsMapping.createChild();
- mNsMapShared = false;
- }
- mNsMapping.addMapping(prefix, uri);
- }
-
- /*
- //////////////////////////////////////////////////
- // NamespaceContext implementation
- //////////////////////////////////////////////////
- */
-
- public final String getNamespaceURI(String prefix)
- {
- if (prefix.length() == 0) { //default NS
- return mDefaultNsURI;
- }
- if (mNsMapping != null) {
- String uri = mNsMapping.findUriByPrefix(prefix);
- if (uri != null) {
- return uri;
- }
- }
- return (mRootNsContext != null) ?
- mRootNsContext.getNamespaceURI(prefix) : null;
- }
-
- public final String getPrefix(String uri)
- {
- if (mDefaultNsURI.equals(uri)) {
- return "";
- }
- if (mNsMapping != null) {
- String prefix = mNsMapping.findPrefixByUri(uri);
- if (prefix != null) {
- return prefix;
- }
- }
- return (mRootNsContext != null) ?
- mRootNsContext.getPrefix(uri) : null;
- }
-
- public final Iterator getPrefixes(String uri)
- {
- List l = null;
-
- if (mDefaultNsURI.equals(uri)) {
- l = new ArrayList();
- l.add("");
- }
- if (mNsMapping != null) {
- l = mNsMapping.getPrefixesBoundToUri(uri, l);
- }
- // How about the root namespace context? (if any)
- /* Note: it's quite difficult to properly resolve masking, when
- * combining these things (not impossible, just tricky); for now
- * let's do best effort without worrying about masking:
- */
- if (mRootNsContext != null) {
- Iterator it = mRootNsContext.getPrefixes(uri);
- while (it.hasNext()) {
- String prefix = (String) it.next();
- if (prefix.length() == 0) { // default NS already checked
- continue;
- }
- // slow check... but what the heck
- if (l == null) {
- l = new ArrayList();
- } else if (l.contains(prefix)) { // double-defined...
- continue;
- }
- l.add(prefix);
- }
- }
- return (l == null) ? EmptyIterator.getInstance() :
- l.iterator();
- }
-
- /*
- ////////////////////////////////////////////
- // Internal methods
- ////////////////////////////////////////////
- */
-
- protected final void throwOutputError(String msg)
- throws XMLStreamException
- {
- throw new XMLStreamException(msg);
- }
-}
diff -Nru libwoodstox-java-4.1.3/src/java/com/ctc/wstx/sw/RepairingNsStreamWriter.java libwoodstox-java-5.1.0/src/java/com/ctc/wstx/sw/RepairingNsStreamWriter.java
--- libwoodstox-java-4.1.3/src/java/com/ctc/wstx/sw/RepairingNsStreamWriter.java 2012-04-24 04:38:20.000000000 +0000
+++ libwoodstox-java-5.1.0/src/java/com/ctc/wstx/sw/RepairingNsStreamWriter.java 1970-01-01 00:00:00.000000000 +0000
@@ -1,646 +0,0 @@
-/* Woodstox XML processor
- *
- * Copyright (c) 2004- Tatu Saloranta, tatu.saloranta@iki.fi
- *
- * Licensed under the License specified in the 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, softwar
- * 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 com.ctc.wstx.sw;
-
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-
-import javax.xml.namespace.QName;
-import javax.xml.stream.XMLStreamWriter;
-import javax.xml.stream.XMLStreamException;
-import javax.xml.stream.events.Attribute;
-import javax.xml.stream.events.StartElement;
-
-import org.codehaus.stax2.ri.typed.AsciiValueEncoder;
-
-import com.ctc.wstx.api.WriterConfig;
-import com.ctc.wstx.cfg.ErrorConsts;
-import com.ctc.wstx.sr.AttributeCollector;
-import com.ctc.wstx.sr.InputElementStack;
-
-/**
- * Namespace-aware implementation of {@link XMLStreamWriter}, that does
- * namespace repairing, ie resolves possible conflicts between prefixes
- * (add new bindings as necessary), as well as automatically creates
- * namespace declarations as necessary.
- */
-public final class RepairingNsStreamWriter
- extends BaseNsStreamWriter
-{
- /*
- ///////////////////////////////////////////////////////////
- // Configuration (options, features)
- ///////////////////////////////////////////////////////////
- */
-
- // // // Additional specific config flags base class doesn't have
-
- protected final String mAutomaticNsPrefix;
-
- /*
- ///////////////////////////////////////////////////////////
- // Additional state
- ///////////////////////////////////////////////////////////
- */
-
- /**
- * Sequence number used for generating dynamic namespace prefixes.
- * Array used as a wrapper to allow for easy sharing of the sequence
- * number.
- */
- protected int[] mAutoNsSeq = null;
-
- protected String mSuggestedDefNs = null;
-
- /**
- * Map that contains URI-to-prefix entries that point out suggested
- * prefixes for URIs. These are populated by calls to
- * {@link #setPrefix}, and they are only used as hints for binding;
- * if there are conflicts, repairing writer can just use some other
- * prefix.
- */
- protected HashMap mSuggestedPrefixes = null;
-
- /*
- ///////////////////////////////////////////////////////////
- // Life-cycle (ctors)
- ///////////////////////////////////////////////////////////
- */
-
- public RepairingNsStreamWriter(XmlWriter xw, String enc, WriterConfig cfg)
- {
- super(xw, enc, cfg, true);
- mAutomaticNsPrefix = cfg.getAutomaticNsPrefix();
- }
-
- /*
- ///////////////////////////////////////////////////////////
- // XMLStreamWriter API
- ///////////////////////////////////////////////////////////
- */
-
- //public NamespaceContext getNamespaceContext()
- //public void setNamespaceContext(NamespaceContext context)
- //public String getPrefix(String uri)
- //public void setPrefix(String prefix, String uri)
- //public void setDefaultNamespace(String uri)
-
- //public void writeAttribute(String localName, String value)
-
- public void writeAttribute(String nsURI, String localName, String value)
- throws XMLStreamException
- {
- // No need to set mAnyOutput, nor close the element
- if (!mStartElementOpen) {
- throwOutputError(ErrorConsts.WERR_ATTR_NO_ELEM);
- }
- doWriteAttr(localName, nsURI,
- findOrCreateAttrPrefix(null, nsURI, mCurrElem),
- value);
- }
-
- public void writeAttribute(String prefix, String nsURI,
- String localName, String value)
- throws XMLStreamException
- {
- if (!mStartElementOpen) {
- throwOutputError(ErrorConsts.WERR_ATTR_NO_ELEM);
- }
-
- doWriteAttr(localName, nsURI, findOrCreateAttrPrefix(prefix, nsURI, mCurrElem),
- value);
- }
-
- public void writeDefaultNamespace(String nsURI)
- throws XMLStreamException
- {
- /* 01-Sep-2006, TSa: The use case for calling this method is that
- * of caller may wanting to 'suggest' that
- * such a namespace should indeed be bound at this level. This
- * may be necessary for canonicalization, or for minimizing number
- * of binding declarations (all children need the ns, but root
- * itself not).
- */
- if (!mStartElementOpen) {
- throwOutputError(ERR_NSDECL_WRONG_STATE);
- }
- /* ... We have one complication though: if the current element
- * uses default namespace, can not change it (attributes don't
- * matter -- they never use the default namespace, but either don't
- * belong to a namespace, or belong to one using explicit prefix)
- */
- String prefix = mCurrElem.getPrefix();
- if (prefix != null && prefix.length() > 0) { // ok, can change it
- mCurrElem.setDefaultNsUri(nsURI);
- doWriteDefaultNs(nsURI);
- }
- }
-
- //public void writeEmptyElement(String localName) throws XMLStreamException
-
- public void writeNamespace(String prefix, String nsURI)
- throws XMLStreamException
- {
- /* (see discussion in 'writeDefaultNamespace()' for details on
- * if and how this method may get called in repairing mode)
- */
- if (prefix == null || prefix.length() == 0) {
- writeDefaultNamespace(nsURI);
- return;
- }
- if (!mStartElementOpen) {
- throwOutputError(ERR_NSDECL_WRONG_STATE);
- }
- /* 01-Sep-2006, TSa: Let's only add the declaration if the prefix
- * is as of yet unbound. If we have to re-bind things in future,
- * so be it -- for now, this should suffice (and if we have to
- * add re-binding, must verify that no attribute, nor element
- * itself, is using overridden prefix)
- */
- int value = mCurrElem.isPrefixValid(prefix, nsURI, true);
- if (value == SimpleOutputElement.PREFIX_UNBOUND) {
- mCurrElem.addPrefix(prefix, nsURI);
- doWriteNamespace(prefix, nsURI);
- }
- }
-
- /*
- ///////////////////////////////////////////////////////////
- // Package methods:
- ///////////////////////////////////////////////////////////
- */
-
- /**
- * With repairing writer, this is only taken as a suggestion as to how
- * the caller would prefer prefixes to be mapped.
- */
- public void setDefaultNamespace(String uri)
- throws XMLStreamException
- {
- mSuggestedDefNs = (uri == null || uri.length() == 0) ? null : uri;
- }
-
- public void doSetPrefix(String prefix, String uri)
- throws XMLStreamException
- {
- /* Ok; let's assume that passing in a null or empty String as
- * the URI means that we don't want passed prefix to be preferred
- * for any URI.
- */
- if (uri == null || uri.length() == 0) {
- if (mSuggestedPrefixes != null) {
- for (Iterator it = mSuggestedPrefixes.entrySet().iterator();
- it.hasNext(); ) {
- Map.Entry en = (Map.Entry) it.next();
- String thisP = (String) en.getValue();
- if (thisP.equals(prefix)) {
- it.remove();
- }
- }
- }
- } else {
- if (mSuggestedPrefixes == null) {
- mSuggestedPrefixes = new HashMap(16);
- }
- mSuggestedPrefixes.put(uri, prefix);
- }
- }
-
- public void writeStartElement(StartElement elem)
- throws XMLStreamException
- {
- /* In repairing mode this is simple: let's just pass info
- * we have, and things should work... a-may-zing!
- */
- QName name = elem.getName();
- writeStartElement(name.getPrefix(), name.getLocalPart(),
- name.getNamespaceURI());
- Iterator it = elem.getAttributes();
- while (it.hasNext()) {
- Attribute attr = (Attribute) it.next();
- name = attr.getName();
- writeAttribute(name.getPrefix(), name.getNamespaceURI(),
- name.getLocalPart(), attr.getValue());
- }
- }
-
- //public void writeEndElement(QName name) throws XMLStreamException
-
- protected void writeTypedAttribute(String prefix, String nsURI, String localName,
- AsciiValueEncoder enc)
- throws XMLStreamException
- {
- super.writeTypedAttribute(findOrCreateAttrPrefix(prefix, nsURI, mCurrElem),
- nsURI, localName, enc);
- }
-
- protected void writeStartOrEmpty(String localName, String nsURI)
- throws XMLStreamException
- {
- checkStartElement(localName, "");
-
- // First, need to find prefix matching URI, if any:
- String prefix = findElemPrefix(nsURI, mCurrElem);
- /* Then need to create the element, since it'll have to
- * contain the new namespace binding, if one needed
- * (changed to resolve [WSTX-135] as reported by Y-J Choi,
- * who also proposed the solution)
- */
- if (mOutputElemPool != null) {
- SimpleOutputElement newCurr = mOutputElemPool;
- mOutputElemPool = newCurr.reuseAsChild(mCurrElem, prefix, localName, nsURI);
- --mPoolSize;
- mCurrElem = newCurr;
- } else {
- mCurrElem = mCurrElem.createChild(prefix, localName, nsURI);
- }
-
- if (prefix != null) { // prefix ok, easy, no need to overwrite
- if (mValidator != null) {
- mValidator.validateElementStart(localName, nsURI, prefix);
- }
- doWriteStartTag(prefix, localName);
- } else { // no prefix, more work
- prefix = generateElemPrefix(null, nsURI, mCurrElem);
- if (mValidator != null) {
- mValidator.validateElementStart(localName, nsURI, prefix);
- }
- mCurrElem.setPrefix(prefix);
- doWriteStartTag(prefix, localName);
- if (prefix == null || prefix.length() == 0) { // def NS
- mCurrElem.setDefaultNsUri(nsURI);
- doWriteDefaultNs(nsURI);
- } else { // explicit NS
- mCurrElem.addPrefix(prefix, nsURI);
- doWriteNamespace(prefix, nsURI);
- }
- }
- }
-
- protected void writeStartOrEmpty(String suggPrefix, String localName, String nsURI)
- throws XMLStreamException
- {
- checkStartElement(localName, suggPrefix);
-
- // In repairing mode, better ensure validity:
- String actPrefix = validateElemPrefix(suggPrefix, nsURI, mCurrElem);
- if (actPrefix != null) { // fine, an existing binding we can use:
- if (mValidator != null) {
- mValidator.validateElementStart(localName, nsURI, actPrefix);
- }
- if (mOutputElemPool != null) {
- SimpleOutputElement newCurr = mOutputElemPool;
- mOutputElemPool = newCurr.reuseAsChild(mCurrElem, actPrefix, localName, nsURI);
- --mPoolSize;
- mCurrElem = newCurr;
- } else {
- mCurrElem = mCurrElem.createChild(actPrefix, localName, nsURI);
- }
- doWriteStartTag(actPrefix, localName);
- } else { // nah, need to create a new binding...
- /* Need to ensure that we'll pass "" as prefix, not null, so
- * that it is understood as "I want to use the default NS", not
- * as "whatever prefix, I don't care"
- */
- if (suggPrefix == null) {
- suggPrefix = "";
- }
- actPrefix = generateElemPrefix(suggPrefix, nsURI, mCurrElem);
- if (mValidator != null) {
- mValidator.validateElementStart(localName, nsURI, actPrefix);
- }
- if (mOutputElemPool != null) {
- SimpleOutputElement newCurr = mOutputElemPool;
- mOutputElemPool = newCurr.reuseAsChild(mCurrElem, actPrefix, localName, nsURI);
- --mPoolSize;
- mCurrElem = newCurr;
- } else {
- mCurrElem = mCurrElem.createChild(actPrefix, localName, nsURI);
- }
- mCurrElem.setPrefix(actPrefix);
- doWriteStartTag(actPrefix, localName);
- if (actPrefix == null || actPrefix.length() == 0) { // def NS
- mCurrElem.setDefaultNsUri(nsURI);
- doWriteDefaultNs(nsURI);
- } else { // explicit NS
- mCurrElem.addPrefix(actPrefix, nsURI);
- doWriteNamespace(actPrefix, nsURI);
- }
- }
- }
-
- /**
- * Element copier method implementation suitable for use with
- * namespace-aware writers in repairing mode.
- * The trickiest thing is having to properly
- * order calls to setPrefix
, writeNamespace
- * and writeStartElement
; the order writers expect is
- * bit different from the order in which element information is
- * passed in.
- */
- public final void copyStartElement(InputElementStack elemStack, AttributeCollector ac)
- throws IOException, XMLStreamException
- {
- /* In case of repairing stream writer, we can actually just
- * go ahead and first output the element: stream writer should
- * be able to resolve namespace mapping for the element
- * automatically, as necessary.
- */
- String prefix = elemStack.getPrefix();
- String uri = elemStack.getNsURI();
- writeStartElement(prefix, elemStack.getLocalName(), uri);
-
- /* 04-Sep-2006, TSa: Although we could really just ignore all
- * namespace declarations, some apps prefer (or even expect...)
- * that ns bindings are preserved as much as possible. So, let's
- * just try to output them as they are (could optimize and skip
- * ones related to the start element [same prefix or URI], but
- * for now let's not bother)
- */
- int nsCount = elemStack.getCurrentNsCount();
- if (nsCount > 0) { // yup, got some...
- for (int i = 0; i < nsCount; ++i) {
- writeNamespace(elemStack.getLocalNsPrefix(i), elemStack.getLocalNsURI(i));
- }
- }
-
- /* And then let's just output attributes, if any (whether to copy
- * implicit, aka "default" attributes, is configurable)
- */
- int attrCount = mCfgCopyDefaultAttrs ? ac.getCount() : ac.getSpecifiedCount();
-
- /* Unlike in non-ns and simple-ns modes, we can not simply literally
- * copy the attributes here. It is possible that some namespace
- * prefixes have been remapped... so need to be bit more careful.
- */
- if (attrCount > 0) {
- for (int i = 0; i < attrCount; ++i) {
- // First; need to make sure that the prefix-to-ns mapping
- // attribute has is valid... and can not output anything
- // before that's done (since remapping will output a namespace
- // declaration!)
- uri = ac.getURI(i);
- prefix = ac.getPrefix(i);
-
- // With attributes, missing/empty prefix always means 'no
- // namespace', can take a shortcut:
- if (prefix == null || prefix.length() == 0) {
- ;
- } else {
- // and otherwise we'll always have a prefix as attributes
- // can not make use of the def. namespace...
- prefix = findOrCreateAttrPrefix(prefix, uri, mCurrElem);
- }
- /* Hmmh. Since the prefix we use may be different from what
- * collector has, we can not use pass-through method of
- * the collector, but need to call XmlWriter directly:
- */
- if (prefix == null || prefix.length() == 0) {
- mWriter.writeAttribute(ac.getLocalName(i), ac.getValue(i));
- } else {
- mWriter.writeAttribute(prefix, ac.getLocalName(i), ac.getValue(i));
- }
- }
- }
- }
-
- public String validateQNamePrefix(QName name)
- throws XMLStreamException
- {
- /* Gets bit more complicated: we need to ensure that given URI
- * is properly bound...
- */
- String uri = name.getNamespaceURI();
- String suggPrefix = name.getPrefix();
- String actPrefix = validateElemPrefix(suggPrefix, uri, mCurrElem);
- if (actPrefix == null) { // no suitable prefix, must bind
- /* Need to ensure that we'll pass "" as prefix, not null, so
- * that it is understood as "I want to use the default NS", not
- * as "whatever prefix, I don't care"
- */
- if (suggPrefix == null) {
- suggPrefix = "";
- }
- actPrefix = generateElemPrefix(suggPrefix, uri, mCurrElem);
- if (actPrefix == null || actPrefix.length() == 0) { // def NS
- writeDefaultNamespace(uri);
- } else {
- writeNamespace(actPrefix, uri);
- }
- }
- return actPrefix;
- }
-
- /*
- ///////////////////////////////////////////////////////////
- // Internal methods
- ///////////////////////////////////////////////////////////
- */
-
- /**
- * Method called to find an existing prefix for the given namespace,
- * if any exists in the scope. If one is found, it's returned (including
- * "" for the current default namespace); if not, null is returned.
- *
- * @param nsURI URI of namespace for which we need a prefix
- */
- protected final String findElemPrefix(String nsURI, SimpleOutputElement elem)
- throws XMLStreamException
- {
- /* Special case: empty NS URI can only be bound to the empty
- * prefix...
- */
- if (nsURI == null || nsURI.length() == 0) {
- String currDefNsURI = elem.getDefaultNsUri();
- if (currDefNsURI != null && currDefNsURI.length() > 0) {
- // Nope; won't do... has to be re-bound, but not here:
- return null;
- }
- return "";
- }
- return mCurrElem.getPrefix(nsURI);
- }
-
- /**
- * Method called after {@link #findElemPrefix} has returned null,
- * to create and bind a namespace mapping for specified namespace.
- */
- protected final String generateElemPrefix(String suggPrefix, String nsURI,
- SimpleOutputElement elem)
- throws XMLStreamException
- {
- /* Ok... now, since we do not have an existing mapping, let's
- * see if we have a preferred prefix to use.
- */
- /* Except if we need the empty namespace... that can only be
- * bound to the empty prefix:
- */
- if (nsURI == null || nsURI.length() == 0) {
- return "";
- }
-
- /* Ok; with elements this is easy: the preferred prefix can
- * ALWAYS be used, since it can mask preceding bindings:
- */
- if (suggPrefix == null) {
- // caller wants this URI to map as the default namespace?
- if (mSuggestedDefNs != null && mSuggestedDefNs.equals(nsURI)) {
- suggPrefix = "";
- } else {
- suggPrefix = (mSuggestedPrefixes == null) ? null:
- (String) mSuggestedPrefixes.get(nsURI);
- if (suggPrefix == null) {
- /* 16-Oct-2005, TSa: We have 2 choices here, essentially;
- * could make elements always try to override the def
- * ns... or can just generate new one. Let's do latter
- * for now.
- */
- if (mAutoNsSeq == null) {
- mAutoNsSeq = new int[1];
- mAutoNsSeq[0] = 1;
- }
- suggPrefix = elem.generateMapping(mAutomaticNsPrefix, nsURI,
- mAutoNsSeq);
- }
- }
- }
-
- // Ok; let's let the caller deal with bindings
- return suggPrefix;
- }
-
- /**
- * Method called to somehow find a prefix for given namespace, to be
- * used for a new start element; either use an existing one, or
- * generate a new one. If a new mapping needs to be generated,
- * it will also be automatically bound, and necessary namespace
- * declaration output.
- *
- * @param suggPrefix Suggested prefix to bind, if any; may be null
- * to indicate "no preference"
- * @param nsURI URI of namespace for which we need a prefix
- * @param elem Currently open start element, on which the attribute
- * will be added.
- */
- protected final String findOrCreateAttrPrefix(String suggPrefix, String nsURI,
- SimpleOutputElement elem)
- throws XMLStreamException
- {
- if (nsURI == null || nsURI.length() == 0) {
- /* Attributes never use the default namespace; missing
- * prefix always leads to the empty ns... so nothing
- * special is needed here.
- */
- return null;
- }
- // Maybe the suggested prefix is properly bound?
- if (suggPrefix != null) {
- int status = elem.isPrefixValid(suggPrefix, nsURI, false);
- if (status == SimpleOutputElement.PREFIX_OK) {
- return suggPrefix;
- }
- /* Otherwise, if the prefix is unbound, let's just bind
- * it -- if caller specified a prefix, it probably prefers
- * binding that prefix even if another prefix already existed?
- * The remaining case (already bound to another URI) we don't
- * want to touch, at least not yet: it may or not be safe
- * to change binding, so let's just not try it.
- */
- if (status == SimpleOutputElement.PREFIX_UNBOUND) {
- elem.addPrefix(suggPrefix, nsURI);
- doWriteNamespace(suggPrefix, nsURI);
- return suggPrefix;
- }
- }
-
- // If not, perhaps there's another existing binding available?
- String prefix = elem.getExplicitPrefix(nsURI);
- if (prefix != null) { // already had a mapping for the URI... cool.
- return prefix;
- }
-
- /* Nope, need to create one. First, let's see if there's a
- * preference...
- */
- if (suggPrefix != null) {
- prefix = suggPrefix;
- } else if (mSuggestedPrefixes != null) {
- prefix = (String) mSuggestedPrefixes.get(nsURI);
- // note: def ns is never added to suggested prefix map
- }
-
- if (prefix != null) {
- /* Can not use default namespace for attributes.
- * Also, re-binding is tricky for attributes; can't
- * re-bind anything that's bound on this scope... or
- * used in this scope. So, to simplify life, let's not
- * re-bind anything for attributes.
- */
- if (prefix.length() == 0
- || (elem.getNamespaceURI(prefix) != null)) {
- prefix = null;
- }
- }
-
- if (prefix == null) {
- if (mAutoNsSeq == null) {
- mAutoNsSeq = new int[1];
- mAutoNsSeq[0] = 1;
- }
- prefix = mCurrElem.generateMapping(mAutomaticNsPrefix, nsURI,
- mAutoNsSeq);
- }
-
- // Ok; so far so good: let's now bind and output the namespace:
- elem.addPrefix(prefix, nsURI);
- doWriteNamespace(prefix, nsURI);
- return prefix;
- }
-
- private final String validateElemPrefix(String prefix, String nsURI,
- SimpleOutputElement elem)
- throws XMLStreamException
- {
- /* 06-Feb-2005, TSa: Special care needs to be taken for the
- * "empty" (or missing) namespace:
- * (see comments from findOrCreatePrefix())
- */
- if (nsURI == null || nsURI.length() == 0) {
- String currURL = elem.getDefaultNsUri();
- if (currURL == null || currURL.length() == 0) {
- // Ok, good:
- return "";
- }
- // Nope, needs to be re-bound:
- return null;
- }
-
- int status = elem.isPrefixValid(prefix, nsURI, true);
- if (status == SimpleOutputElement.PREFIX_OK) {
- return prefix;
- }
-
- /* Hmmh... now here's bit of dilemma: that particular prefix is
- * either not bound, or is masked... but it is possible some other
- * prefix would be bound. Should we search for another one, or
- * try to re-define suggested one? Let's do latter, for now;
- * caller can then (try to) bind the preferred prefix:
- */
- return null;
- }
-}
diff -Nru libwoodstox-java-4.1.3/src/java/com/ctc/wstx/sw/SimpleNsStreamWriter.java libwoodstox-java-5.1.0/src/java/com/ctc/wstx/sw/SimpleNsStreamWriter.java
--- libwoodstox-java-4.1.3/src/java/com/ctc/wstx/sw/SimpleNsStreamWriter.java 2012-04-24 04:38:20.000000000 +0000
+++ libwoodstox-java-5.1.0/src/java/com/ctc/wstx/sw/SimpleNsStreamWriter.java 1970-01-01 00:00:00.000000000 +0000
@@ -1,336 +0,0 @@
-/* Woodstox XML processor
- *
- * Copyright (c) 2004- Tatu Saloranta, tatu.saloranta@iki.fi
- *
- * Licensed under the License specified in the 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 com.ctc.wstx.sw;
-
-import java.io.IOException;
-import java.util.Iterator;
-
-import javax.xml.XMLConstants;
-import javax.xml.namespace.QName;
-import javax.xml.stream.XMLStreamWriter;
-import javax.xml.stream.XMLStreamException;
-import javax.xml.stream.events.Attribute;
-import javax.xml.stream.events.Namespace;
-import javax.xml.stream.events.StartElement;
-
-import com.ctc.wstx.api.WriterConfig;
-import com.ctc.wstx.cfg.ErrorConsts;
-import com.ctc.wstx.sr.AttributeCollector;
-import com.ctc.wstx.sr.InputElementStack;
-
-/**
- * Namespace-aware implementation of {@link XMLStreamWriter}, that does
- * not do namespace repairing, ie doesn't try to resolve possible
- * conflicts between prefixes and namespace URIs, or automatically
- * create namespace bindings.
- */
-public class SimpleNsStreamWriter
- extends BaseNsStreamWriter
-{
- /*
- ////////////////////////////////////////////////////
- // Life-cycle (ctors)
- ////////////////////////////////////////////////////
- */
-
- public SimpleNsStreamWriter(XmlWriter xw, String enc, WriterConfig cfg)
- {
- super(xw, enc, cfg, false);
- }
-
- /*
- ////////////////////////////////////////////////////
- // XMLStreamWriter API
- ////////////////////////////////////////////////////
- */
-
- //public NamespaceContext getNamespaceContext()
- //public void setNamespaceContext(NamespaceContext context)
- //public String getPrefix(String uri)
- //public void setPrefix(String prefix, String uri)
-
- //public void writeAttribute(String localName, String value)
-
- public void writeAttribute(String nsURI, String localName, String value)
- throws XMLStreamException
- {
- // No need to set mAnyOutput, nor close the element
- if (!mStartElementOpen) {
- throwOutputError(ErrorConsts.WERR_ATTR_NO_ELEM);
- }
- String prefix = mCurrElem.getExplicitPrefix(nsURI);
- if (!mReturnNullForDefaultNamespace && prefix == null) {
- throwOutputError("Unbound namespace URI '" + nsURI + "'");
- }
- doWriteAttr(localName, nsURI, prefix, value);
- }
-
- public void writeAttribute(String prefix, String nsURI,
- String localName, String value)
- throws XMLStreamException
- {
- if (!mStartElementOpen) {
- throwOutputError(ErrorConsts.WERR_ATTR_NO_ELEM);
- }
- doWriteAttr(localName, nsURI, prefix, value);
- }
-
- //public void writeEmptyElement(String localName) throws XMLStreamException
- //public void writeEmptyElement(String nsURI, String localName) throws XMLStreamException
- //public void writeEmptyElement(String prefix, String localName, String nsURI) throws XMLStreamException
-
- //public void writeEndElement() throws XMLStreamException
-
- public void writeDefaultNamespace(String nsURI)
- throws XMLStreamException
- {
- if (!mStartElementOpen) {
- throwOutputError(ERR_NSDECL_WRONG_STATE);
- }
- // 27-Mar-2007, TSa: Apparently TCK expects a binding to be added
- setDefaultNamespace(nsURI);
- doWriteDefaultNs(nsURI);
- }
-
- public void writeNamespace(String prefix, String nsURI)
- throws XMLStreamException
- {
- if (prefix == null || prefix.length() == 0
- || prefix.equals(XMLConstants.XMLNS_ATTRIBUTE)) {
- writeDefaultNamespace(nsURI);
- return;
- }
-
- // No need to set mAnyOutput, and shouldn't close the element.
- // But element needs to be open, obviously.
- if (!mStartElementOpen) {
- throwOutputError(ERR_NSDECL_WRONG_STATE);
- }
- /* 05-Feb-2005, TSa: Also, as per namespace specs; the 'empty'
- * namespace URI can not be bound as a non-default namespace
- * (ie. for any actual prefix)
- */
- /* 04-Feb-2005, TSa: Namespaces 1.1 does allow this, though,
- * so for xml 1.1 documents we need to allow it
- */
- if (!mXml11) {
- if (nsURI.length() == 0) {
- throwOutputError(ErrorConsts.ERR_NS_EMPTY);
- }
- // 01-Apr-2005, TSa: Can we (and do we want to) verify NS consistency?
- }
- // 27-Mar-2007, TSa: Apparently TCK expects a binding to be added
- setPrefix(prefix, nsURI);
- doWriteNamespace(prefix, nsURI);
- }
-
- /*
- ////////////////////////////////////////////////////
- // Package methods:
- ////////////////////////////////////////////////////
- */
-
- public void setDefaultNamespace(String uri)
- throws XMLStreamException
- {
- mCurrElem.setDefaultNsUri(uri);
- }
-
- public void doSetPrefix(String prefix, String uri)
- throws XMLStreamException
- {
- mCurrElem.addPrefix(prefix, uri);
- }
-
- public void writeStartElement(StartElement elem)
- throws XMLStreamException
- {
- QName name = elem.getName();
- Iterator it = elem.getNamespaces();
-
- while (it.hasNext()) {
- Namespace ns = (Namespace) it.next();
- // First need to 'declare' namespace:
- String prefix = ns.getPrefix();
- if (prefix == null || prefix.length() == 0) {
- setDefaultNamespace(ns.getNamespaceURI());
- } else {
- setPrefix(prefix, ns.getNamespaceURI());
- }
- }
-
- /* Outputting element itself is fairly easy. The main question
- * is whether namespaces match. Let's use simple heuristics:
- * if writer is to do automatic prefix matching, let's only
- * pass explicit prefix (not default one); otherwise we'll
- * pass all parameters as is.
- */
- /* Quick check first though: if URI part of QName is null, it's
- * assumed element will just use whatever is current default
- * namespace....
- */
- String nsURI = name.getNamespaceURI();
- if (nsURI == null) {
- writeStartElement(name.getLocalPart());
- } else {
- String prefix = name.getPrefix();
- writeStartElement(prefix, name.getLocalPart(), nsURI);
- }
-
- // And now we need to output namespaces (including default), if any:
- it = elem.getNamespaces();
- while (it.hasNext()) {
- Namespace ns = (Namespace) it.next();
- String prefix = ns.getPrefix();
- if (prefix == null || prefix.length() == 0) {
- writeDefaultNamespace(ns.getNamespaceURI());
- } else {
- writeNamespace(prefix, ns.getNamespaceURI());
- }
- }
-
-
- // And finally, need to output attributes as well:
-
- it = elem.getAttributes();
- while (it.hasNext()) {
- Attribute attr = (Attribute) it.next();
- name = attr.getName();
- nsURI = name.getNamespaceURI();
- // In non-default/empty namespace?
- if (nsURI != null && nsURI.length() > 0) {
- writeAttribute(name.getPrefix(), nsURI,
- name.getLocalPart(), attr.getValue());
- } else {
- writeAttribute(name.getLocalPart(), attr.getValue());
- }
- }
- }
-
- //public void writeEndElement(QName name) throws XMLStreamException
-
- protected void writeStartOrEmpty(String localName, String nsURI)
- throws XMLStreamException
- {
- // Need a prefix...
- String prefix = mCurrElem.getPrefix(nsURI);
- if (prefix == null) {
- throw new XMLStreamException("Unbound namespace URI '"+nsURI+"'");
- }
- checkStartElement(localName, prefix);
- if (mValidator != null) {
- mValidator.validateElementStart(localName, nsURI, prefix);
- }
-
- if (mOutputElemPool != null) {
- SimpleOutputElement newCurr = mOutputElemPool;
- mOutputElemPool = newCurr.reuseAsChild(mCurrElem, prefix, localName, nsURI);
- --mPoolSize;
- mCurrElem = newCurr;
- } else {
- mCurrElem = mCurrElem.createChild(prefix, localName, nsURI);
- }
- doWriteStartTag(prefix, localName);
- }
-
- protected void writeStartOrEmpty(String prefix, String localName, String nsURI)
- throws XMLStreamException
- {
- checkStartElement(localName, prefix);
- if (mValidator != null) {
- mValidator.validateElementStart(localName, nsURI, prefix);
- }
-
- if (mOutputElemPool != null) {
- SimpleOutputElement newCurr = mOutputElemPool;
- mOutputElemPool = newCurr.reuseAsChild(mCurrElem, prefix, localName, nsURI);
- --mPoolSize;
- mCurrElem = newCurr;
- } else {
- mCurrElem = mCurrElem.createChild(prefix, localName, nsURI);
- }
- doWriteStartTag(prefix, localName);
- }
-
- /**
- * Element copier method implementation suitable to be used with
- * namespace-aware writers in non-repairing (explicit namespaces) mode.
- * The trickiest thing is having to properly
- * order calls to setPrefix
, writeNamespace
- * and writeStartElement
; the order writers expect is
- * bit different from the order in which element information is
- * passed in.
- */
- public final void copyStartElement(InputElementStack elemStack,
- AttributeCollector attrCollector)
- throws IOException, XMLStreamException
- {
- // Any namespace declarations/bindings?
- int nsCount = elemStack.getCurrentNsCount();
- 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 = elemStack.getLocalNsPrefix(i);
- String uri = elemStack.getLocalNsURI(i);
- if (prefix == null || prefix.length() == 0) { // default NS
- setDefaultNamespace(uri);
- } else {
- setPrefix(prefix, uri);
- }
- }
- }
-
- writeStartElement(elemStack.getPrefix(),
- elemStack.getLocalName(),
- elemStack.getNsURI());
-
- if (nsCount > 0) {
- // And then output actual namespace declarations:
- for (int i = 0; i < nsCount; ++i) {
- String prefix = elemStack.getLocalNsPrefix(i);
- String uri = elemStack.getLocalNsURI(i);
-
- if (prefix == null || prefix.length() == 0) { // default NS
- writeDefaultNamespace(uri);
- } else {
- writeNamespace(prefix, uri);
- }
- }
- }
-
- /* And then let's just output attributes, if any (whether to copy
- * implicit, aka "default" attributes, is configurable)
- */
- int attrCount = mCfgCopyDefaultAttrs ?
- attrCollector.getCount() :
- attrCollector.getSpecifiedCount();
-
- if (attrCount > 0) {
- for (int i = 0; i < attrCount; ++i) {
- attrCollector.writeAttribute(i, mWriter);
- }
- }
- }
-
- public String validateQNamePrefix(QName name)
- {
- // Good as is, let's not complicate things
- return name.getPrefix();
- }
-}
diff -Nru libwoodstox-java-4.1.3/src/java/com/ctc/wstx/sw/SimpleOutputElement.java libwoodstox-java-5.1.0/src/java/com/ctc/wstx/sw/SimpleOutputElement.java
--- libwoodstox-java-4.1.3/src/java/com/ctc/wstx/sw/SimpleOutputElement.java 2012-04-24 04:38:20.000000000 +0000
+++ libwoodstox-java-5.1.0/src/java/com/ctc/wstx/sw/SimpleOutputElement.java 1970-01-01 00:00:00.000000000 +0000
@@ -1,367 +0,0 @@
-/* Woodstox XML processor
- *
- * 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 com.ctc.wstx.sw;
-
-import java.util.*;
-
-import javax.xml.namespace.NamespaceContext;
-import javax.xml.namespace.QName;
-import javax.xml.stream.XMLStreamException;
-
-import com.ctc.wstx.compat.QNameCreator;
-import com.ctc.wstx.util.BijectiveNsMap;
-
-/**
- * Class that encapsulates information about a specific element in virtual
- * output stack for namespace-aware writers.
- * It provides support for URI-to-prefix mappings as well as namespace
- * mapping generation.
- *
- * One noteworthy feature of the class is that it is designed to allow
- * "short-term recycling", ie. instances can be reused within context
- * of a simple document output. While reuse/recycling of such lightweight
- * object is often useless or even counter productive, here it may
- * be worth using, due to simplicity of the scheme (basically using
- * a very simple free-elements linked list).
- */
-public final class SimpleOutputElement
- extends OutputElementBase
-{
- /*
- ////////////////////////////////////////////
- // Information about element itself:
- ////////////////////////////////////////////
- */
-
- /**
- * Reference to the parent element, element enclosing this element.
- * Null for root element.
- * Non-final only to allow temporary pooling
- * (on per-writer basis, to keep these short-lived).
- */
- SimpleOutputElement mParent;
-
- /**
- * Prefix that is used for the element. Can not be final, since sometimes
- * it needs to be dynamically generated and bound after creating the
- * element instance.
- */
- String mPrefix;
-
- /**
- * Local name of the element.
- * Non-final only to allow reuse.
- */
- String mLocalName;
-
- /**
- * Namespace of the element, whatever {@link #mPrefix} maps to.
- * Non-final only to allow reuse.
- */
- String mURI;
-
- /*
- ////////////////////////////////////////////
- // Attribute information
- ////////////////////////////////////////////
- */
-
- /**
- * Map used to check for duplicate attribute declarations, if
- * feature is enabled.
- */
- protected HashSet mAttrSet = null;
-
- /*
- ////////////////////////////////////////////
- // Life-cycle
- ////////////////////////////////////////////
- */
-
- /**
- * Constructor for the virtual root element
- */
- private SimpleOutputElement()
- {
- super();
- mParent = null;
- mPrefix = null;
- mLocalName = "";
- mURI = null;
- }
-
- private SimpleOutputElement(SimpleOutputElement parent,
- String prefix, String localName, String uri,
- BijectiveNsMap ns)
- {
- super(parent, ns);
- mParent = parent;
- mPrefix = prefix;
- mLocalName = localName;
- mURI = uri;
- }
-
- /**
- * Method called to reuse a pooled instance.
- *
- * @return Chained pooled instance that should now be head of the
- * reuse chain
- */
- private void relink(SimpleOutputElement parent,
- String prefix, String localName, String uri)
- {
- super.relink(parent);
- mParent = parent;
- mPrefix = prefix;
- mLocalName = localName;
- mURI = uri;
- mNsMapping = parent.mNsMapping;
- mNsMapShared = (mNsMapping != null);
- mDefaultNsURI = parent.mDefaultNsURI;
- mRootNsContext = parent.mRootNsContext;
- }
-
- public static SimpleOutputElement createRoot()
- {
- return new SimpleOutputElement();
- }
-
- /**
- * Simplest factory method, which gets called when a 1-argument
- * element output method is called. It is, then, assumed to
- * use the default namespce.
- */
- protected SimpleOutputElement createChild(String localName)
- {
- /* At this point we can also discard attribute Map; it is assumed
- * that when a child element has been opened, no more attributes
- * can be output.
- */
- mAttrSet = null;
- return new SimpleOutputElement(this, null, localName,
- mDefaultNsURI, mNsMapping);
- }
-
- /**
- * @return New head of the recycle pool
- */
- protected SimpleOutputElement reuseAsChild(SimpleOutputElement parent,
- String localName)
- {
- mAttrSet = null;
- SimpleOutputElement poolHead = mParent;
- relink(parent, null, localName, mDefaultNsURI);
- return poolHead;
- }
-
- protected SimpleOutputElement reuseAsChild(SimpleOutputElement parent,
- String prefix, String localName,
- String uri)
- {
- mAttrSet = null;
- SimpleOutputElement poolHead = mParent;
- relink(parent, prefix, localName, uri);
- return poolHead;
- }
-
- /**
- * Full factory method, used for 'normal' namespace qualified output
- * methods.
- */
- protected SimpleOutputElement createChild(String prefix, String localName,
- String uri)
- {
- /* At this point we can also discard attribute Map; it is assumed
- * that when a child element has been opened, no more attributes
- * can be output.
- */
- mAttrSet = null;
- return new SimpleOutputElement(this, prefix, localName, uri, mNsMapping);
- }
-
- /**
- * Method called to temporarily link this instance to a pool, to
- * allow reusing of instances with the same reader.
- */
- protected void addToPool(SimpleOutputElement poolHead)
- {
- mParent = poolHead;
- }
-
- /*
- ////////////////////////////////////////////
- // Public API, accessors
- ////////////////////////////////////////////
- */
-
- public SimpleOutputElement getParent() {
- return mParent;
- }
-
- public boolean isRoot() {
- // (Virtual) Root element has no parent...
- return (mParent == null);
- }
-
- /**
- * @return String presentation of the fully-qualified name, in
- * "prefix:localName" format (no URI). Useful for error and
- * debugging messages.
- */
- public String getNameDesc() {
- if (mPrefix != null && mPrefix.length() > 0) {
- return mPrefix + ":" +mLocalName;
- }
- if (mLocalName != null && mLocalName.length() > 0) {
- return mLocalName;
- }
- return "#error"; // unexpected case
- }
-
- public String getPrefix() {
- return mPrefix;
- }
-
- public String getLocalName() {
- return mLocalName;
- }
-
- public String getNamespaceURI() {
- return mURI;
- }
-
- public QName getName() {
- return QNameCreator.create(mURI, mLocalName, mPrefix);
- }
-
- /*
- ////////////////////////////////////////////
- // Public API, ns binding, checking
- ////////////////////////////////////////////
- */
-
- public void checkAttrWrite(String nsURI, String localName)
- throws XMLStreamException
- {
- AttrName an = new AttrName(nsURI, localName);
- if (mAttrSet == null) {
- /* 13-Dec-2005, TSa: Should use a more efficient Set/Map value
- * for this in future -- specifically one that could use
- * ns/local-name pairs without intermediate objects
- */
- mAttrSet = new HashSet();
- }
- if (!mAttrSet.add(an)) {
- throw new XMLStreamException("Duplicate attribute write for attribute '"+an+"'");
- }
- }
-
- /*
- ////////////////////////////////////////////
- // Public API, mutators
- ////////////////////////////////////////////
- */
-
- public void setPrefix(String prefix) {
- mPrefix = prefix;
- }
-
- public void setDefaultNsUri(String uri) {
- mDefaultNsURI = uri;
- }
-
- /**
- * Note: this method can and will only be called before outputting
- * the root element.
- */
- protected final void setRootNsContext(NamespaceContext ctxt)
- {
- mRootNsContext = ctxt;
- // Let's also figure out the default ns binding, if any:
- String defURI = ctxt.getNamespaceURI("");
- if (defURI != null && defURI.length() > 0) {
- mDefaultNsURI = defURI;
- }
- }
-
- /*
- //////////////////////////////////////////////////
- // Helper classes:
- //////////////////////////////////////////////////
- */
-
- /**
- * Simple key class used to represent two-piece (attribute) names;
- * first part being optional (URI), and second non-optional (local name).
- */
- final static class AttrName
- implements Comparable
- {
- final String mNsURI;
- final String mLocalName;
-
- /**
- * Let's cache the hash code, since although hash calculation is
- * fast, hash code is needed a lot as this is always used as a
- * HashSet/TreeMap key.
- */
- final int mHashCode;
-
- public AttrName(String nsURI, String localName) {
- mNsURI = (nsURI == null) ? "" : nsURI;
- mLocalName = localName;
- mHashCode = mNsURI.hashCode() * 31 ^ mLocalName.hashCode();
- }
-
- public boolean equals(Object o) {
- if (o == this) {
- return true;
- }
- if (!(o instanceof AttrName)) {
- return false;
- }
- AttrName other = (AttrName) o;
- String otherLN = other.mLocalName;
- // Local names are shorter, more varying:
- if (otherLN != mLocalName && !otherLN.equals(mLocalName)) {
- return false;
- }
- String otherURI = other.mNsURI;
- return (otherURI == mNsURI || otherURI.equals(mNsURI));
- }
-
- public String toString() {
- if (mNsURI.length() > 0) {
- return "{"+mNsURI + "} " +mLocalName;
- }
- return mLocalName;
- }
-
- public int hashCode() {
- return mHashCode;
- }
-
- public int compareTo(Object o) {
- AttrName other = (AttrName) o;
- // Let's first order by namespace:
- int result = mNsURI.compareTo(other.mNsURI);
- if (result == 0) {
- result = mLocalName.compareTo(other.mLocalName);
- }
- return result;
- }
- }
-}
diff -Nru libwoodstox-java-4.1.3/src/java/com/ctc/wstx/sw/TypedStreamWriter.java libwoodstox-java-5.1.0/src/java/com/ctc/wstx/sw/TypedStreamWriter.java
--- libwoodstox-java-4.1.3/src/java/com/ctc/wstx/sw/TypedStreamWriter.java 2012-04-24 04:38:20.000000000 +0000
+++ libwoodstox-java-5.1.0/src/java/com/ctc/wstx/sw/TypedStreamWriter.java 1970-01-01 00:00:00.000000000 +0000
@@ -1,330 +0,0 @@
-/* Woodstox XML processor
- *
- * Copyright (c) 2004- 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 com.ctc.wstx.sw;
-
-import java.io.IOException;
-import java.math.BigDecimal;
-import java.math.BigInteger;
-
-import javax.xml.namespace.QName;
-import javax.xml.stream.XMLStreamException;
-
-import org.codehaus.stax2.typed.Base64Variant;
-import org.codehaus.stax2.typed.Base64Variants;
-import org.codehaus.stax2.ri.typed.AsciiValueEncoder;
-import org.codehaus.stax2.ri.typed.ValueEncoderFactory;
-import org.codehaus.stax2.validation.XMLValidator;
-
-import com.ctc.wstx.api.WriterConfig;
-import com.ctc.wstx.cfg.ErrorConsts;
-import com.ctc.wstx.exc.WstxIOException;
-
-/**
- * Intermediate base class that implements Typed Access API (Stax2 v3)
- * for all (repairing, non-repairing, non-namespace) native stream
- * writer implementations.
- */
-public abstract class TypedStreamWriter
- extends BaseStreamWriter
-{
- /**
- * When outputting using Typed Access API, we will need
- * encoders. If so, they will created by lazily-constructed
- * factory
- */
- protected ValueEncoderFactory mValueEncoderFactory;
-
- /*
- ////////////////////////////////////////////////////
- // Life-cycle
- ////////////////////////////////////////////////////
- */
-
- protected TypedStreamWriter(XmlWriter xw, String enc, WriterConfig cfg)
- {
- super(xw, enc, cfg);
- }
-
- protected final ValueEncoderFactory valueEncoderFactory()
- {
- if (mValueEncoderFactory == null) {
- mValueEncoderFactory = new ValueEncoderFactory();
- }
- return mValueEncoderFactory;
- }
-
- /*
- /////////////////////////////////////////////////
- // TypedXMLStreamWriter2 implementation
- // (Typed Access API, Stax v3.0)
- /////////////////////////////////////////////////
- */
-
- // // // Typed element content write methods
-
- public void writeBoolean(boolean value)
- throws XMLStreamException
- {
- writeTypedElement(valueEncoderFactory().getEncoder(value));
- }
-
- public void writeInt(int value)
- throws XMLStreamException
- {
- writeTypedElement(valueEncoderFactory().getEncoder(value));
- }
-
- public void writeLong(long value)
- throws XMLStreamException
- {
- writeTypedElement(valueEncoderFactory().getEncoder(value));
- }
-
- public void writeFloat(float value)
- throws XMLStreamException
- {
- writeTypedElement(valueEncoderFactory().getEncoder(value));
- }
-
- public void writeDouble(double value)
- throws XMLStreamException
- {
- writeTypedElement(valueEncoderFactory().getEncoder(value));
-
- }
-
- public void writeInteger(BigInteger value)
- throws XMLStreamException
- {
- /* No really efficient method exposed by JDK, keep it simple
- * (esp. considering that length is actually not bound)
- */
- writeTypedElement(valueEncoderFactory().getScalarEncoder(value.toString()));
- }
-
- public void writeDecimal(BigDecimal value)
- throws XMLStreamException
- {
- /* No really efficient method exposed by JDK, keep it simple
- * (esp. considering that length is actually not bound)
- */
- writeTypedElement(valueEncoderFactory().getScalarEncoder(value.toString()));
- }
-
- public void writeQName(QName name)
- throws XMLStreamException
- {
- /* Can't use AsciiValueEncoder, since QNames can contain
- * non-ascii characters
- */
- writeCharacters(serializeQName(name));
- }
-
- public final void writeIntArray(int[] value, int from, int length)
- throws XMLStreamException
- {
- writeTypedElement(valueEncoderFactory().getEncoder(value, from, length));
- }
-
- public void writeLongArray(long[] value, int from, int length)
- throws XMLStreamException
- {
- writeTypedElement(valueEncoderFactory().getEncoder(value, from, length));
- }
-
- public void writeFloatArray(float[] value, int from, int length)
- throws XMLStreamException
- {
- writeTypedElement(valueEncoderFactory().getEncoder(value, from, length));
- }
-
- public void writeDoubleArray(double[] value, int from, int length)
- throws XMLStreamException
- {
- writeTypedElement(valueEncoderFactory().getEncoder(value, from, length));
- }
-
- public void writeBinary(byte[] value, int from, int length)
- throws XMLStreamException
- {
- Base64Variant v = Base64Variants.getDefaultVariant();
- writeTypedElement(valueEncoderFactory().getEncoder(v, value, from, length));
- }
-
- public void writeBinary(Base64Variant v, byte[] value, int from, int length)
- throws XMLStreamException
- {
- writeTypedElement(valueEncoderFactory().getEncoder(v, value, from, length));
- }
-
- protected final void writeTypedElement(AsciiValueEncoder enc)
- throws XMLStreamException
- {
- if (mStartElementOpen) {
- closeStartElement(mEmptyElement);
- }
- // How about well-formedness?
- if (mCheckStructure) {
- if (inPrologOrEpilog()) {
- reportNwfStructure(ErrorConsts.WERR_PROLOG_NONWS_TEXT);
- }
- }
- // Or validity?
- if (mVldContent <= XMLValidator.CONTENT_ALLOW_WS) {
- reportInvalidContent(CHARACTERS);
- }
-
- // So far so good: let's serialize
- try {
- XMLValidator vld = (mVldContent == XMLValidator.CONTENT_ALLOW_VALIDATABLE_TEXT) ?
- mValidator : null;
- if (vld == null) {
- mWriter.writeTypedElement(enc);
- } else {
- mWriter.writeTypedElement(enc, vld, getCopyBuffer());
- }
- } catch (IOException ioe) {
- throw new WstxIOException(ioe);
- }
- }
-
- // // // Typed attribute value write methods
-
- public void writeBooleanAttribute(String prefix, String nsURI, String localName, boolean value)
- throws XMLStreamException
- {
- writeTypedAttribute(prefix, nsURI, localName,
- valueEncoderFactory().getEncoder(value));
- }
-
- public void writeIntAttribute(String prefix, String nsURI, String localName, int value)
- throws XMLStreamException
- {
- writeTypedAttribute(prefix, nsURI, localName,
- valueEncoderFactory().getEncoder(value));
- }
-
- public void writeLongAttribute(String prefix, String nsURI, String localName, long value)
- throws XMLStreamException
- {
- writeTypedAttribute(prefix, nsURI, localName,
- valueEncoderFactory().getEncoder(value));
- }
-
- public void writeFloatAttribute(String prefix, String nsURI, String localName, float value)
- throws XMLStreamException
- {
- writeTypedAttribute(prefix, nsURI, localName,
- valueEncoderFactory().getEncoder(value));
- }
-
- public void writeDoubleAttribute(String prefix, String nsURI, String localName, double value)
- throws XMLStreamException
- {
- writeTypedAttribute(prefix, nsURI, localName,
- valueEncoderFactory().getEncoder(value));
- }
-
- public void writeIntegerAttribute(String prefix, String nsURI, String localName, BigInteger value)
- throws XMLStreamException
- {
- // not optimal, but has to do:
- writeTypedAttribute(prefix, nsURI, localName,
- valueEncoderFactory().getScalarEncoder(value.toString()));
- }
-
- public void writeDecimalAttribute(String prefix, String nsURI, String localName, BigDecimal value)
- throws XMLStreamException
- {
- // not optimal, but has to do:
- writeTypedAttribute(prefix, nsURI, localName,
- valueEncoderFactory().getScalarEncoder(value.toString()));
- }
-
- public void writeQNameAttribute(String prefix, String nsURI, String localName, QName name)
- throws XMLStreamException
- {
- /* Can't use AsciiValueEncoder, since QNames can contain
- * non-ascii characters
- */
- writeAttribute(prefix, nsURI, localName, serializeQName(name));
- }
-
- public void writeIntArrayAttribute(String prefix, String nsURI, String localName, int[] value)
- throws XMLStreamException
- {
- writeTypedAttribute(prefix, nsURI, localName,
- valueEncoderFactory().getEncoder(value, 0, value.length));
- }
-
- public void writeLongArrayAttribute(String prefix, String nsURI, String localName, long[] value)
- throws XMLStreamException
- {
- writeTypedAttribute(prefix, nsURI, localName,
- valueEncoderFactory().getEncoder(value, 0, value.length));
- }
-
- public void writeFloatArrayAttribute(String prefix, String nsURI, String localName, float[] value)
- throws XMLStreamException
- {
- writeTypedAttribute(prefix, nsURI, localName,
- valueEncoderFactory().getEncoder(value, 0, value.length));
- }
-
- public void writeDoubleArrayAttribute(String prefix, String nsURI, String localName, double[] value)
- throws XMLStreamException
- {
- writeTypedAttribute(prefix, nsURI, localName,
- valueEncoderFactory().getEncoder(value, 0, value.length));
- }
-
- public void writeBinaryAttribute(String prefix, String nsURI, String localName, byte[] value)
- throws XMLStreamException
- {
- Base64Variant v = Base64Variants.getDefaultVariant();
- writeTypedAttribute(prefix, nsURI, localName,
- valueEncoderFactory().getEncoder(v, value, 0, value.length));
- }
-
- public void writeBinaryAttribute(Base64Variant v, String prefix, String nsURI, String localName, byte[] value)
- throws XMLStreamException
- {
- writeTypedAttribute(prefix, nsURI, localName,
- valueEncoderFactory().getEncoder(v, value, 0, value.length));
- }
-
- /**
- * Method that will write attribute with value that is known not to
- * require additional escaping.
- */
- protected abstract void writeTypedAttribute(String prefix, String nsURI,
- String localName,
- AsciiValueEncoder enc)
- throws XMLStreamException;
-
- private String serializeQName(QName name)
- throws XMLStreamException
- {
- String vp = validateQNamePrefix(name);
- String local = name.getLocalPart();
- if (vp == null || vp.length() == 0) {
- return local;
- }
-
- // Not efficient... but should be ok
- return vp + ":" + local;
- }
-}
diff -Nru libwoodstox-java-4.1.3/src/java/com/ctc/wstx/sw/XmlWriter.java libwoodstox-java-5.1.0/src/java/com/ctc/wstx/sw/XmlWriter.java
--- libwoodstox-java-4.1.3/src/java/com/ctc/wstx/sw/XmlWriter.java 2012-04-24 04:38:20.000000000 +0000
+++ libwoodstox-java-5.1.0/src/java/com/ctc/wstx/sw/XmlWriter.java 1970-01-01 00:00:00.000000000 +0000
@@ -1,625 +0,0 @@
-/* Woodstox XML processor
- *
- * Copyright (c) 2004- 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 com.ctc.wstx.sw;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.Writer;
-import java.text.MessageFormat;
-
-import javax.xml.stream.XMLStreamException;
-
-import org.codehaus.stax2.io.EscapingWriterFactory;
-import org.codehaus.stax2.ri.typed.AsciiValueEncoder;
-import org.codehaus.stax2.validation.XMLValidator;
-
-import com.ctc.wstx.api.InvalidCharHandler;
-import com.ctc.wstx.api.WriterConfig;
-import com.ctc.wstx.api.WstxOutputProperties;
-import com.ctc.wstx.cfg.ErrorConsts;
-import com.ctc.wstx.cfg.OutputConfigFlags;
-import com.ctc.wstx.exc.WstxIOException;
-import com.ctc.wstx.io.WstxInputData;
-
-/**
- * This is the base class for actual physical xml outputters. These
- * instances will only handle actual writing (possibly including
- * encoding) of the serialized textual xml, and will in general
- * not verify content being output. The exception are the
- * character-by-character checks that are most efficiently done
- * at encoding level (such as character escaping, and checks for
- * illegal character combinations), which are handled at this
- * level.
- *
- * Note that implementations can have different operating modes:
- * specifically, when dealing with illegal content (such as "--"
- * in a comment, "?>" in processing instruction, or "]]>" within
- * CDATA section), implementations can do one of 3 things:
- *
- * - Fix the problem, by splitting the section (which can be done
- * for CDATA sections, and to some degree, comments)
- *
- * - Stop outputting, and return an index to the illegal piece
- * of data (if there is no easy way to fix the problem: for
- * example, for processing instruction)
- *
- * - Just output content even though it will not result in
- * well-formed output. This should only be done if the calling
- * application has specifically requested verifications to be
- * disabled.
- *
- *
- */
-public abstract class XmlWriter
-{
- protected final static int SURR1_FIRST = 0xD800;
- protected final static int SURR1_LAST = 0xDBFF;
- protected final static int SURR2_FIRST = 0xDC00;
- protected final static int SURR2_LAST = 0xDFFF;
-
- protected final static char DEFAULT_QUOTE_CHAR = '"';
-
- protected final WriterConfig mConfig;
- protected final String mEncoding;
-
- // // // Operating mode: base class needs to know whether
- // // // namespaces are support (for entity/PI target validation)
-
- protected final boolean mNsAware;
-
- protected final boolean mCheckStructure;
- protected final boolean mCheckContent;
- protected final boolean mCheckNames;
- protected final boolean mFixContent;
-
- /**
- * Whether to escape CR (\r) character.
- */
- final boolean mEscapeCR;
-
- /**
- * Whether to add a space after empty element (before closing "/>")
- * or not.
- */
- final boolean mAddSpaceAfterEmptyElem;
-
- /**
- * Flag that defines whether close() on this writer should call
- * close on the underlying output object (stream, writer)
- */
- protected final boolean mAutoCloseOutput;
-
- /**
- * Optional escaping writer used for escaping characters like '<'
- * '&' and '>' in textual content.
- * Constructed if calling code has
- * installed a special escaping writer factory for text content.
- * Null if the default escaper is to be used.
- */
- protected Writer mTextWriter;
-
- /**
- * Optional escaping writer used for escaping characters like '"'
- * '&' and '<' in attribute values.
- * Constructed if calling code has
- * installed a special escaping writer factory for text content.
- * Null if the default escaper is to be used.
- */
- protected Writer mAttrValueWriter;
-
- /**
- * Indicates whether output is to be compliant; if false, is to be
- * xml 1.0 compliant, if true, xml 1.1 compliant.
- */
- protected boolean mXml11 = false;
-
- /**
- * Lazy-constructed wrapper object, which will route all calls to
- * Writer API, to matching writeRaw
methods of this
- * XmlWriter instance.
- */
- protected XmlWriterWrapper mRawWrapper = null;
-
- /**
- * Lazy-constructed wrapper object, which will route all calls to
- * Writer API, to matching writeCharacters
methods of this
- * XmlWriter instance.
- */
- protected XmlWriterWrapper mTextWrapper = null;
-
- /*
- ///////////////////////////////////////////////////////
- // Output location info
- ///////////////////////////////////////////////////////
- */
-
- /**
- * Number of characters output prior to currently buffered output
- */
- protected int mLocPastChars = 0;
-
- protected int mLocRowNr = 1;
-
- /**
- * Offset of the first character on this line. May be negative, if
- * the offset was in a buffer that has been flushed out.
- */
- protected int mLocRowStartOffset = 0;
-
- /*
- ///////////////////////////////////////////////////////
- // Life-cycle
- ///////////////////////////////////////////////////////
- */
-
- protected XmlWriter(WriterConfig cfg, String encoding, boolean autoclose)
- throws IOException
- {
- mConfig = cfg;
- mEncoding = encoding;
- mAutoCloseOutput = autoclose;
- int flags = cfg.getConfigFlags();
- mNsAware = (flags & OutputConfigFlags.CFG_ENABLE_NS) != 0;
- mCheckStructure = (flags & OutputConfigFlags.CFG_VALIDATE_STRUCTURE) != 0;
- mCheckContent = (flags & OutputConfigFlags.CFG_VALIDATE_CONTENT) != 0;
- mCheckNames = (flags & OutputConfigFlags.CFG_VALIDATE_NAMES) != 0;
- mFixContent = (flags & OutputConfigFlags.CFG_FIX_CONTENT) != 0;
- mEscapeCR = (flags & OutputConfigFlags.CFG_ESCAPE_CR) != 0;
- mAddSpaceAfterEmptyElem = (flags & OutputConfigFlags.CFG_ADD_SPACE_AFTER_EMPTY_ELEM) != 0;
-
- // Has caller requested any custom text or attr value escaping?
-
- EscapingWriterFactory f = mConfig.getTextEscaperFactory();
- if (f == null) {
- mTextWriter = null;
- } else {
- String enc = (mEncoding == null || mEncoding.length() == 0) ?
- WstxOutputProperties.DEFAULT_OUTPUT_ENCODING : mEncoding;
- mTextWriter = f.createEscapingWriterFor(wrapAsRawWriter(), enc);
- }
-
- f = mConfig.getAttrValueEscaperFactory();
- if (f == null) {
- mAttrValueWriter = null;
- } else {
- String enc = (mEncoding == null || mEncoding.length() == 0) ?
- WstxOutputProperties.DEFAULT_OUTPUT_ENCODING : mEncoding;
- mAttrValueWriter = f.createEscapingWriterFor(wrapAsRawWriter(), enc);
- }
- }
-
- /*
- ////////////////////////////////////////////////////
- // Extra configuration
- ////////////////////////////////////////////////////
- */
-
- public void enableXml11() {
- mXml11 = true;
- }
-
- /*
- ////////////////////////////////////////////////////
- // Access to underlying physical output destinations
- ////////////////////////////////////////////////////
- */
-
- /**
- * @return Underlying OutputStream used for physical output,
- * if the writer was constructed using one
- */
- protected abstract OutputStream getOutputStream();
-
- /**
- * @return Underlying Writer used for physical output,
- * if the writer was constructed with one, or one was
- * created to be used with an OutputStream.
- */
- protected abstract Writer getWriter();
-
- /*
- ////////////////////////////////////////////////////
- // Basic methods for communicating with underlying
- // stream or writer
- ////////////////////////////////////////////////////
- */
-
- /**
- * Method called to flush the buffer(s), and close the output
- * sink (stream or writer) if enabled (auto-closing) or
- * forced.
- */
- public abstract void close(boolean forceRealClose) throws IOException;
-
- public abstract void flush()
- throws IOException;
-
- public abstract void writeRaw(String str, int offset, int len)
- throws IOException;
-
- public void writeRaw(String str)
- throws IOException
- {
- writeRaw(str, 0, str.length());
- }
-
- public abstract void writeRaw(char[] cbuf, int offset, int len)
- throws IOException;
-
- /**
- * Like {@link #writeRaw}, but caller guarantees that the contents
- * additionally are known to be in 7-bit ascii range.
- */
- public abstract void writeRawAscii(char[] cbuf, int offset, int len)
- throws IOException;
-
- /*
- ////////////////////////////////////////////////////
- // Raw, non-verifying write methods; used when
- // directly copying trusted content
- ////////////////////////////////////////////////////
- */
-
- public abstract void writeCDataStart()
- throws IOException;
-
- public abstract void writeCDataEnd()
- throws IOException;
-
- public abstract void writeCommentStart()
- throws IOException;
-
- public abstract void writeCommentEnd()
- throws IOException;
-
- public abstract void writePIStart(String target, boolean addSpace)
- throws IOException;
-
- public abstract void writePIEnd()
- throws IOException;
-
- /*
- ////////////////////////////////////////////////////
- // Write methods, textual:
- ////////////////////////////////////////////////////
- */
-
- /**
- * @param data Contents of the CDATA section to write out
-
- * @return offset of the (first) illegal content segment ("]]>") in
- * passed content and not in repairing mode; or -1 if none or is
- * repairing
- */
- public abstract int writeCData(String data)
- throws IOException, XMLStreamException;
-
- public abstract int writeCData(char[] cbuf, int offset, int len)
- throws IOException, XMLStreamException;
-
- public abstract void writeCharacters(String data)
- throws IOException;
-
- public abstract void writeCharacters(char[] cbuf, int offset, int len)
- throws IOException;
-
- /*
- ////////////////////////////////////////////////////
- // Write methods, non-textual, non-elem/attr:
- ////////////////////////////////////////////////////
- */
-
- /**
- * Method that will try to output the content as specified. If
- * the content passed in has embedded "--" in it, it will either
- * add an intervening space between consequtive hyphens (if content
- * fixing is enabled), or return the offset of the first hyphen in
- * multi-hyphen sequence.
- */
- public abstract int writeComment(String data)
- throws IOException, XMLStreamException;
-
- /**
- * Older "legacy" output method for outputting DOCTYPE declaration.
- * Assumes that the passed-in String contains a complete DOCTYPE
- * declaration properly quoted.
- */
- public abstract void writeDTD(String data)
- throws IOException, XMLStreamException;
-
- public abstract void writeDTD(String rootName,
- String systemId, String publicId,
- String internalSubset)
- throws IOException, XMLStreamException;
-
- public abstract void writeEntityReference(String name)
- throws IOException, XMLStreamException;
-
- public abstract int writePI(String target, String data)
- throws IOException, XMLStreamException;
-
- public abstract void writeXmlDeclaration(String version, String enc, String standalone)
- throws IOException;
-
- /*
- ////////////////////////////////////////////////////
- // Write methods, elements
- ////////////////////////////////////////////////////
- */
-
- /**
- *
- * Note: can throw XMLStreamException, if name checking is enabled,
- * and name is invalid (name check has to be in this writer, not
- * caller, since it depends not only on xml limitations, but also
- * on encoding limitations)
- */
- public abstract void writeStartTagStart(String localName)
- throws IOException, XMLStreamException;
-
- /**
- *
- * Note: can throw XMLStreamException, if name checking is enabled,
- * and name is invalid (name check has to be in this writer, not
- * caller, since it depends not only on xml limitations, but also
- * on encoding limitations)
- */
- public abstract void writeStartTagStart(String prefix, String localName)
- throws IOException, XMLStreamException;
-
- public abstract void writeStartTagEnd()
- throws IOException;
-
- public abstract void writeStartTagEmptyEnd()
- throws IOException;
-
- public abstract void writeEndTag(String localName)
- throws IOException;
-
- public abstract void writeEndTag(String prefix, String localName)
- throws IOException;
-
- /*
- ////////////////////////////////////////////////////
- // Write methods, attributes/ns
- ////////////////////////////////////////////////////
- */
-
- /**
- *
- * Note: can throw XMLStreamException, if name checking is enabled,
- * and name is invalid (name check has to be in this writer, not
- * caller, since it depends not only on xml limitations, but also
- * on encoding limitations)
- */
- public abstract void writeAttribute(String localName, String value)
- throws IOException, XMLStreamException;
-
- public abstract void writeAttribute(String localName, char[] value, int offset, int len)
- throws IOException, XMLStreamException;
-
- /**
- *
- * Note: can throw XMLStreamException, if name checking is enabled,
- * and name is invalid (name check has to be in this writer, not
- * caller, since it depends not only on xml limitations, but also
- * on encoding limitations)
- */
- public abstract void writeAttribute(String prefix, String localName, String value)
- throws IOException, XMLStreamException;
-
- public abstract void writeAttribute(String prefix, String localName, char[] value, int offset, int len)
- throws IOException, XMLStreamException;
-
- /*
- ////////////////////////////////////////////////////
- // Write methods, Typed Access API support
- ////////////////////////////////////////////////////
- */
-
- /**
- * Like {@link #writeRaw}, but caller guarantees that the contents
- * additionally are known to be in 7-bit ascii range, and also
- * passes an encoder object that will encode values only when
- * being handed a buffer to append to.
- *
- * @param enc Encoder that will produce content
- */
- public abstract void writeTypedElement(AsciiValueEncoder enc)
- throws IOException;
-
- /**
- * Like {@link #writeRaw}, but caller guarantees that the contents
- * additionally are known to be in 7-bit ascii range, and also
- * passes an encoder object that will encode values only when
- * being handed a buffer to append to.
- *
- * @param enc Encoder that will produce content
- * @param validator Validator to use for validating serialized textual
- * content (can not be null)
- * @param copyBuffer Temporary buffer that writer can use for temporary
- * copies as necessary
- */
- public abstract void writeTypedElement(AsciiValueEncoder enc,
- XMLValidator validator, char[] copyBuffer)
- throws IOException, XMLStreamException;
-
- /**
- * Method similar to {@link #writeAttribute(String,String,char[],int,int)}
- * but where is known not to require escaping.
- * No validation needs to be performed.
- */
- public abstract void writeTypedAttribute(String localName, AsciiValueEncoder enc)
- throws IOException, XMLStreamException;
-
- /**
- * Method similar to {@link #writeAttribute(String,String,char[],int,int)}
- * but where is known not to require escaping.
- * No validation needs to be performed.
- */
- public abstract void writeTypedAttribute(String prefix, String localName, AsciiValueEncoder enc)
- throws IOException, XMLStreamException;
-
- /**
- * Method similar to {@link #writeAttribute(String,String,char[],int,int)}
- * but where is known not to require escaping.
- * Validation of the attribute value must be done by calling given
- * validator appropriately.
- */
- public abstract void writeTypedAttribute(String prefix, String localName, String nsURI,
- AsciiValueEncoder enc,
- XMLValidator validator, char[] copyBuffer)
- throws IOException, XMLStreamException;
-
- /*
- ////////////////////////////////////////////////////
- // Location information
- ////////////////////////////////////////////////////
- */
-
- protected abstract int getOutputPtr();
-
- public int getRow() {
- return mLocRowNr;
- }
-
- public int getColumn() {
- return (getOutputPtr() - mLocRowStartOffset) + 1;
- }
-
- public int getAbsOffset() {
- return mLocPastChars +getOutputPtr();
- }
-
- /*
- ////////////////////////////////////////////////////
- // Wrapper methods, semi-public
- ////////////////////////////////////////////////////
- */
-
- /**
- * Method that can be called to get a wrapper instance that
- * can be used to essentially call the writeRaw
- * method.
- */
- public final Writer wrapAsRawWriter()
- {
- if (mRawWrapper == null) {
- mRawWrapper = XmlWriterWrapper.wrapWriteRaw(this);
- }
- return mRawWrapper;
- }
-
- public final Writer wrapAsTextWriter()
- {
- if (mTextWrapper == null) {
- mTextWrapper = XmlWriterWrapper.wrapWriteCharacters(this);
- }
- return mTextWrapper;
- }
-
- /*
- ////////////////////////////////////////////////////
- // Helper methods for sub-classes
- ////////////////////////////////////////////////////
- */
-
- /**
- * Method called to verify that the name is a legal XML name.
- */
- public final void verifyNameValidity(String name, boolean checkNs)
- throws XMLStreamException
- {
- /* No empty names... caller must have dealt with optional arguments
- * prior to calling this method
- */
- if (name == null || name.length() == 0) {
- reportNwfName(ErrorConsts.WERR_NAME_EMPTY);
- }
- int illegalIx = WstxInputData.findIllegalNameChar(name, checkNs, mXml11);
- if (illegalIx >= 0) {
- if (illegalIx == 0) {
- reportNwfName(ErrorConsts.WERR_NAME_ILLEGAL_FIRST_CHAR,
- WstxInputData.getCharDesc(name.charAt(0)));
- }
- reportNwfName(ErrorConsts.WERR_NAME_ILLEGAL_CHAR,
- WstxInputData.getCharDesc(name.charAt(illegalIx)));
- }
- }
-
- /**
- * This is the method called when an output method call violates
- * name well-formedness checks
- * and {@link WstxOutputProperties#P_OUTPUT_VALIDATE_NAMES} is
- * is enabled.
- */
- protected void reportNwfName(String msg)
- throws XMLStreamException
- {
- throwOutputError(msg);
- }
-
- protected void reportNwfName(String msg, Object arg)
- throws XMLStreamException
- {
- throwOutputError(msg, arg);
- }
-
- protected void reportNwfContent(String msg)
- throws XMLStreamException
- {
- throwOutputError(msg);
- }
-
- protected void throwOutputError(String msg)
- throws XMLStreamException
- {
- // First, let's flush any output we may have, to make debugging easier
- try {
- flush();
- } catch (IOException ioe) {
- throw new WstxIOException(ioe);
- }
-
- throw new XMLStreamException(msg);
- }
-
- protected void throwOutputError(String format, Object arg)
- throws XMLStreamException
- {
- String msg = MessageFormat.format(format, new Object[] { arg });
- throwOutputError(msg);
- }
-
- /**
- * Method called to handle invalid character in textual content requested
- * to be output. Content may be part of textual events (CHARACTER, CDATA),
- * attribute value, COMMENT content or PROCESSING_INSTRUCTION data.
- * The default behavior is to just throw an exception, but this can
- * be configured via property {@link WstxOutputProperties#P_OUTPUT_INVALID_CHAR_HANDLER}.
- */
- protected char handleInvalidChar(int c)
- throws IOException
- {
- // First, let's flush any output we may have, to make debugging easier
- flush();
- InvalidCharHandler h = mConfig.getInvalidCharHandler();
- if (h == null) {
- h = InvalidCharHandler.FailingHandler.getInstance();
- }
- return h.convertInvalidChar(c);
- }
-}
diff -Nru libwoodstox-java-4.1.3/src/java/com/ctc/wstx/sw/XmlWriterWrapper.java libwoodstox-java-5.1.0/src/java/com/ctc/wstx/sw/XmlWriterWrapper.java
--- libwoodstox-java-4.1.3/src/java/com/ctc/wstx/sw/XmlWriterWrapper.java 2012-04-24 04:38:20.000000000 +0000
+++ libwoodstox-java-5.1.0/src/java/com/ctc/wstx/sw/XmlWriterWrapper.java 1970-01-01 00:00:00.000000000 +0000
@@ -1,172 +0,0 @@
-/* Woodstox XML processor
- *
- * Copyright (c) 2004- 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 com.ctc.wstx.sw;
-
-import java.io.*;
-
-/**
- * This is a simple wrapper class, which decorates an {@link XmlWriter}
- * to look like a Writer. This is necessary to implement a (legacy)
- * character quoting system introduced for Woodstox 2.0, which relies
- * on having a Writer to use for outputting.
- */
-public abstract class XmlWriterWrapper
- extends Writer
-{
- protected final XmlWriter mWriter;
-
- private char[] mBuffer = null;
-
- public static XmlWriterWrapper wrapWriteRaw(XmlWriter xw)
- {
- return new RawWrapper(xw);
- }
-
- public static XmlWriterWrapper wrapWriteCharacters(XmlWriter xw)
- {
- return new TextWrapper(xw);
- }
-
- protected XmlWriterWrapper(XmlWriter writer)
- {
- mWriter = writer;
- }
-
- public final void close()
- throws IOException
- {
- mWriter.close(false);
- }
-
- public final void flush()
- throws IOException
- {
- mWriter.flush();
- }
-
- /* !!! 30-Nov-2006, TSa: Due to co-variance between Appendable and
- * Writer, this would not compile with javac 1.5, in 1.4 mode
- * (source and target set to "1.4". Not a huge deal, but since
- * the base impl is just fine, no point in overriding it.
- */
- /*
- public final Writer append(char c)
- throws IOException
- {
- if (mBuffer == null) {
- mBuffer = new char[1];
- }
- mBuffer[0] = (char) c;
- write(mBuffer, 0, 1);
- return this;
- }
- */
-
- public final void write(char[] cbuf)
- throws IOException
- {
- write(cbuf, 0, cbuf.length);
- }
-
- public abstract void write(char[] cbuf, int off, int len)
- throws IOException;
-
- public final void write(int c)
- throws IOException
- {
- if (mBuffer == null) {
- mBuffer = new char[1];
- }
- mBuffer[0] = (char) c;
- write(mBuffer, 0, 1);
- }
-
- public abstract void write(String str)
- throws IOException;
-
- public abstract void write(String str, int off, int len)
- throws IOException;
-
- /*
- //////////////////////////////////////////////////
- // Implementation classes
- //////////////////////////////////////////////////
- */
-
- /**
- * This wrapper directs calls to writeRaw
methods. Thus,
- * it is a "vanilla" writer, and no escaping is done.
- */
- private final static class RawWrapper
- extends XmlWriterWrapper
- {
- protected RawWrapper(XmlWriter writer)
- {
- super(writer);
- }
-
- public void write(char[] cbuf, int off, int len)
- throws IOException
- {
- mWriter.writeRaw(cbuf, off, len);
- }
-
- public void write(String str, int off, int len)
- throws IOException
- {
- mWriter.writeRaw(str, off, len);
- }
-
- public final void write(String str)
- throws IOException
- {
- mWriter.writeRaw(str, 0, str.length());
- }
- }
-
- /**
- * This wrapper directs calls to writeCharacters
methods.
- * This means that text content escaping (and, possibly, validation)
- * is done, using default or custom escaping code.
- */
- private static class TextWrapper
- extends XmlWriterWrapper
- {
- protected TextWrapper(XmlWriter writer)
- {
- super(writer);
- }
-
- public void write(char[] cbuf, int off, int len)
- throws IOException
- {
- mWriter.writeCharacters(cbuf, off, len);
- }
-
- public void write(String str)
- throws IOException
- {
- mWriter.writeCharacters(str);
- }
-
- public void write(String str, int off, int len)
- throws IOException
- {
- mWriter.writeCharacters(str.substring(off, off+len));
- }
- }
-}
-
diff -Nru libwoodstox-java-4.1.3/src/java/com/ctc/wstx/util/ArgUtil.java libwoodstox-java-5.1.0/src/java/com/ctc/wstx/util/ArgUtil.java
--- libwoodstox-java-4.1.3/src/java/com/ctc/wstx/util/ArgUtil.java 2012-04-24 04:38:20.000000000 +0000
+++ libwoodstox-java-5.1.0/src/java/com/ctc/wstx/util/ArgUtil.java 1970-01-01 00:00:00.000000000 +0000
@@ -1,58 +0,0 @@
-package com.ctc.wstx.util;
-
-/**
- * Simple static utility class that contains (static) utility methods useful
- * when parsing non-typesafe arguments (String-only configuration, command
- * line args).
- */
-public final class ArgUtil
-{
- private ArgUtil() { }
-
- public static boolean convertToBoolean(String prop, Object value)
- {
- if (value == null) {
- return false;
- }
- if (value instanceof Boolean) {
- return ((Boolean) value).booleanValue();
- }
- if (value instanceof String) {
- String str = (String) value;
- if (str.equalsIgnoreCase("false")) {
- return false;
- }
- if (str.equalsIgnoreCase("true")) {
- return true;
- }
- throw new IllegalArgumentException("Invalid String value for property '"+prop+"': expected Boolean value.");
- }
- throw new IllegalArgumentException("Invalid value type ("+value.getClass()+") for property '"+prop+"': expected Boolean value.");
- }
-
- public static int convertToInt(String prop, Object value, int minValue)
- {
- int i;
-
- if (value == null) {
- i = 0;
- } else if (value instanceof Number) {
- i = ((Number) value).intValue();
- } else if (value instanceof String) {
- try {
- i = Integer.parseInt((String) value);
- } catch (NumberFormatException nex) {
- throw new IllegalArgumentException("Invalid String value for property '"+prop+"': expected a number (Integer).");
- }
- } else {
- throw new IllegalArgumentException("Invalid value type ("+value.getClass()+") for property '"+prop+"': expected Integer value.");
- }
-
- if (i < minValue) {
- throw new IllegalArgumentException("Invalid numeric value ("+i
- +") for property '"+prop
- +"': minimum is "+minValue+".");
- }
- return i;
- }
-}
diff -Nru libwoodstox-java-4.1.3/src/java/com/ctc/wstx/util/BaseNsContext.java libwoodstox-java-5.1.0/src/java/com/ctc/wstx/util/BaseNsContext.java
--- libwoodstox-java-4.1.3/src/java/com/ctc/wstx/util/BaseNsContext.java 2012-04-24 04:38:20.000000000 +0000
+++ libwoodstox-java-5.1.0/src/java/com/ctc/wstx/util/BaseNsContext.java 1970-01-01 00:00:00.000000000 +0000
@@ -1,132 +0,0 @@
-/* Woodstox XML processor
- *
- * Copyright (c) 2004 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 com.ctc.wstx.util;
-
-import java.io.IOException;
-import java.io.Writer;
-import java.util.Iterator;
-
-import javax.xml.XMLConstants;
-import javax.xml.namespace.NamespaceContext;
-import javax.xml.stream.XMLStreamException;
-import javax.xml.stream.XMLStreamWriter;
-
-import org.codehaus.stax2.ri.SingletonIterator;
-
-import com.ctc.wstx.cfg.ErrorConsts;
-
-/**
- * Abstract base class that defines extra features defined by most
- * NamespaceContext implementations Wodstox uses.
- */
-public abstract class BaseNsContext
- implements NamespaceContext
-{
- /**
- * This is the URI returned for default namespace, when it hasn't
- * been explicitly declared; could be either "" or null.
- */
- protected final static String UNDECLARED_NS_URI = "";
-
- /*
- /////////////////////////////////////////////
- // 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(ErrorConsts.ERR_NULL_ARG);
- }
- 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 doGetNamespaceURI(prefix);
- }
-
- public final String getPrefix(String nsURI)
- {
- /* First the known offenders; invalid args, 2 predefined xml namespace
- * prefixes
- */
- if (nsURI == null || nsURI.length() == 0) {
- throw new IllegalArgumentException("Illegal to pass null/empty prefix 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 doGetPrefix(nsURI);
- }
-
- public final Iterator getPrefixes(String nsURI)
- {
- /* First the known offenders; invalid args, 2 predefined xml namespace
- * prefixes
- */
- if (nsURI == null || nsURI.length() == 0) {
- throw new IllegalArgumentException("Illegal to pass null/empty prefix as argument.");
- }
- if (nsURI.equals(XMLConstants.XML_NS_URI)) {
- return new SingletonIterator(XMLConstants.XML_NS_PREFIX);
- }
- if (nsURI.equals(XMLConstants.XMLNS_ATTRIBUTE_NS_URI)) {
- return new SingletonIterator(XMLConstants.XMLNS_ATTRIBUTE);
- }
-
- return doGetPrefixes(nsURI);
- }
-
- /*
- /////////////////////////////////////////////
- // Extended API
- /////////////////////////////////////////////
- */
-
- public abstract Iterator getNamespaces();
-
- /**
- * Method called by the matching start element class to
- * output all namespace declarations active in current namespace
- * scope, if any.
- */
- public abstract void outputNamespaceDeclarations(Writer w) throws IOException;
-
- public abstract void outputNamespaceDeclarations(XMLStreamWriter w) throws XMLStreamException;
-
- /*
- /////////////////////////////////////////////////
- // Template methods sub-classes need to implement
- /////////////////////////////////////////////////
- */
-
- public abstract String doGetNamespaceURI(String prefix);
-
- public abstract String doGetPrefix(String nsURI);
-
- public abstract Iterator doGetPrefixes(String nsURI);
-}
diff -Nru libwoodstox-java-4.1.3/src/java/com/ctc/wstx/util/BijectiveNsMap.java libwoodstox-java-5.1.0/src/java/com/ctc/wstx/util/BijectiveNsMap.java
--- libwoodstox-java-4.1.3/src/java/com/ctc/wstx/util/BijectiveNsMap.java 2012-04-24 04:38:20.000000000 +0000
+++ libwoodstox-java-5.1.0/src/java/com/ctc/wstx/util/BijectiveNsMap.java 1970-01-01 00:00:00.000000000 +0000
@@ -1,326 +0,0 @@
-/* Woodstox XML processor
- *
- * 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 com.ctc.wstx.util;
-
-import java.util.*;
-
-import javax.xml.XMLConstants;
-import javax.xml.namespace.NamespaceContext;
-
-import com.ctc.wstx.util.DataUtil;
-
-/**
- * Helper class that implements "bijective map" (Map that allows use of values
- * as keys and vice versa, bidirectional access), and is specifically
- * used for storing namespace binding information.
- * One thing worth noting is that Strings stored are NOT assumed to have
- * been unified (interned) -- if they were, different implementation would
- * be more optimal.
- *
- * Currently only used by stream writers, but could be more generally useful
- * too.
- */
-
-public final class BijectiveNsMap
-{
- /*
- ///////////////////////////////////////////////
- // Constants
- ///////////////////////////////////////////////
- */
-
- /**
- * Let's plan for having up to 14 explicit namespace declarations (2
- * defaults, for 'xml' and 'xmlns', are pre-populated)
- */
- final static int DEFAULT_ARRAY_SIZE = 2 * 16;
-
- /*
- ///////////////////////////////////////////////
- // Member vars
- ///////////////////////////////////////////////
- */
-
- final int mScopeStart;
-
- /**
- * Array that contains { prefix, ns-uri } pairs, up to (but not including)
- * index {@link #mScopeEnd}.
- */
- String[] mNsStrings;
-
- int mScopeEnd;
-
- /*
- ///////////////////////////////////////////////
- // Life-cycle
- ///////////////////////////////////////////////
- */
-
- private BijectiveNsMap(int scopeStart, String[] strs)
- {
- mScopeStart = mScopeEnd = scopeStart;
- mNsStrings = strs;
- }
-
- public static BijectiveNsMap createEmpty()
- {
- String[] strs = new String[DEFAULT_ARRAY_SIZE];
-
- strs[0] = XMLConstants.XML_NS_PREFIX;
- strs[1] = XMLConstants.XML_NS_URI;
- strs[2] = XMLConstants.XMLNS_ATTRIBUTE;
- strs[3] = XMLConstants.XMLNS_ATTRIBUTE_NS_URI;
-
- /* Let's consider pre-defined ones to be 'out of scope', i.e.
- * conceptually be part of (missing) parent's mappings.
- */
- return new BijectiveNsMap(4, strs);
- }
-
- public BijectiveNsMap createChild() {
- return new BijectiveNsMap(mScopeEnd, mNsStrings);
- }
-
- /*
- ///////////////////////////////////////////////
- // Public API, accessors
- ///////////////////////////////////////////////
- */
-
- public String findUriByPrefix(String prefix)
- {
- /* This is quite simple: just need to locate the last mapping
- * for the prefix, if any:
- */
- String[] strs = mNsStrings;
- int phash = prefix.hashCode();
-
- for (int ix = mScopeEnd - 2; ix >= 0; ix -= 2) {
- String thisP = strs[ix];
- if (thisP == prefix ||
- (thisP.hashCode() == phash && thisP.equals(prefix))) {
- return strs[ix+1];
- }
- }
- return null;
- }
-
- public String findPrefixByUri(String uri)
- {
-
- /* Finding a valid binding for the given URI is trickier, since
- * mappings can be masked by others... so, we need to first find
- * most recent binding, from the freshest one, and then verify
- * it's still unmasked; if not, continue with the first loop,
- * and so on.
- */
-
- String[] strs = mNsStrings;
- int uhash = uri.hashCode();
-
- main_loop:
- for (int ix = mScopeEnd - 1; ix > 0; ix -= 2) {
- String thisU = strs[ix];
- if (thisU == uri ||
- (thisU.hashCode() == uhash && thisU.equals(uri))) {
- // match, but has it been masked?
- String prefix = strs[ix-1];
- /* only need to check, if it wasn't within current scope
- * (no masking allowed within scopes)
- */
- if (ix < mScopeStart) {
- int phash = prefix.hashCode();
- for (int j = ix+1, end = mScopeEnd; j < end; j += 2) {
- String thisP = strs[j];
- if (thisP == prefix ||
- (thisP.hashCode() == phash && thisP.equals(prefix))) {
- // Masking... got to continue the main loop:
- continue main_loop;
- }
- }
- }
- // Ok, unmasked one, can return
- return prefix;
- }
- }
- return null;
- }
-
- public List getPrefixesBoundToUri(String uri, List l)
- {
- /* Same problems (masking) apply here, as well as with
- * findPrefixByUri...
- */
- String[] strs = mNsStrings;
- int uhash = uri.hashCode();
-
- main_loop:
- for (int ix = mScopeEnd - 1; ix > 0; ix -= 2) {
- String thisU = strs[ix];
- if (thisU == uri ||
- (thisU.hashCode() == uhash && thisU.equals(uri))) {
- // match, but has it been masked?
- String prefix = strs[ix-1];
- /* only need to check, if it wasn't within current scope
- * (no masking allowed within scopes)
- */
- if (ix < mScopeStart) {
- int phash = prefix.hashCode();
- for (int j = ix+1, end = mScopeEnd; j < end; j += 2) {
- String thisP = strs[j];
- if (thisP == prefix ||
- (thisP.hashCode() == phash && thisP.equals(prefix))) {
- // Masking... got to continue the main loop:
- continue main_loop;
- }
- }
- }
- // Ok, unmasked one, can add
- if (l == null) {
- l = new ArrayList();
- }
- l.add(prefix);
- }
- }
- return l;
- }
-
- public int size() {
- return (mScopeEnd >> 1);
- }
-
- public int localSize() {
- return ((mScopeEnd - mScopeStart) >> 1);
- }
-
- /*
- ///////////////////////////////////////////////
- // Public API, mutators
- ///////////////////////////////////////////////
- */
-
- /**
- * Method to add a new prefix-to-URI mapping for the current scope.
- * Note that it should NOT be used for the default namespace
- * declaration
- *
- * @param prefix Prefix to bind
- * @param uri URI to bind to the prefix
- *
- * @return If the prefix was already bound, the URI it was bound to:
- * null if it's a new binding for the current scope.
- */
- public String addMapping(String prefix, String uri)
- {
- String[] strs = mNsStrings;
- int phash = prefix.hashCode();
-
- for (int ix = mScopeStart, end = mScopeEnd; ix < end; ix += 2) {
- String thisP = strs[ix];
- if (thisP == prefix ||
- (thisP.hashCode() == phash && thisP.equals(prefix))) {
- // Overriding an existing mapping
- String old = strs[ix+1];
- strs[ix+1] = uri;
- return old;
- }
- }
- // no previous binding, let's just add it at the end
- if (mScopeEnd >= strs.length) {
- // let's just double the array sizes...
- strs = DataUtil.growArrayBy(strs, strs.length);
- mNsStrings = strs;
- }
- strs[mScopeEnd++] = prefix;
- strs[mScopeEnd++] = uri;
-
- return null;
- }
-
- /**
- * Method used to add a dynamic binding, and return the prefix
- * used to bind the specified namespace URI.
- */
- public String addGeneratedMapping(String prefixBase, NamespaceContext ctxt,
- String uri, int[] seqArr)
- {
- String[] strs = mNsStrings;
- int seqNr = seqArr[0];
- String prefix;
-
- main_loop:
- while (true) {
- /* We better intern the resulting prefix? Or not?
- * TODO: maybe soft cache these for other docs?
- */
- prefix = (prefixBase + seqNr).intern();
- ++seqNr;
-
- /* Ok, let's see if we have a mapping (masked or not) for
- * the prefix. If we do, let's just not use it: we could
- * of course mask it (unless it's in current scope), but
- * it's easier to just get a "virgin" prefix...
- */
- int phash = prefix.hashCode();
-
- for (int ix = mScopeEnd - 2; ix >= 0; ix -= 2) {
- String thisP = strs[ix];
- if (thisP == prefix ||
- (thisP.hashCode() == phash && thisP.equals(prefix))) {
- continue main_loop;
- }
- }
- /* So far so good... but do we have a root context that might
- * have something too?
- */
-
- if (ctxt != null && ctxt.getNamespaceURI(prefix) != null) {
- continue;
- }
- break;
- }
- seqArr[0] = seqNr;
-
- // Ok, good; then let's just add it in...
- if (mScopeEnd >= strs.length) {
- // let's just double the array sizes...
- strs = DataUtil.growArrayBy(strs, strs.length);
- mNsStrings = strs;
- }
- strs[mScopeEnd++] = prefix;
- strs[mScopeEnd++] = uri;
-
- return prefix;
- }
-
- /*
- ///////////////////////////////////////////////
- // Standard overridden methods
- ///////////////////////////////////////////////
- */
-
- public String toString() {
- return "["+getClass().toString()+"; "+size()+" entries; of which "
- +localSize()+" local]";
- }
-
- /*
- ///////////////////////////////////////////////
- // Internal methods
- ///////////////////////////////////////////////
- */
-}
diff -Nru libwoodstox-java-4.1.3/src/java/com/ctc/wstx/util/DataUtil.java libwoodstox-java-5.1.0/src/java/com/ctc/wstx/util/DataUtil.java
--- libwoodstox-java-4.1.3/src/java/com/ctc/wstx/util/DataUtil.java 2012-04-24 04:38:20.000000000 +0000
+++ libwoodstox-java-5.1.0/src/java/com/ctc/wstx/util/DataUtil.java 1970-01-01 00:00:00.000000000 +0000
@@ -1,135 +0,0 @@
-package com.ctc.wstx.util;
-
-import java.lang.reflect.Array;
-import java.util.*;
-
-public final class DataUtil
-{
- final static char[] EMPTY_CHAR_ARRAY = new char[0];
-
- /**
- * If baseline requirement was JDK 1.5, we wouldn't need to
- * cache Integer instances like this (since it has
- * Integer.valueOf() which does it); but until then, we
- * alas need our known canonicalization.
- */
- final static Integer[] INTS = new Integer[100];
- static {
- for (int i = 0; i < INTS.length; ++i) {
- INTS[i] = new Integer(i);
- }
- }
-
- private DataUtil() { }
-
- /*
- ////////////////////////////////////////////////////////////
- // Pooling for immutable objects
- ////////////////////////////////////////////////////////////
- */
-
- public static char[] getEmptyCharArray() {
- return EMPTY_CHAR_ARRAY;
- }
-
- public static Integer Integer(int i)
- {
- /* !!! 13-Sep-2008, TSa: JDK 1.5 can use Integer.valueOf(int)
- * which does the same. When upgrading baseline, can get rid
- * of this method.
- */
- if (i < 0 || i >= INTS.length) {
- return new Integer(i);
- }
- return INTS[i];
- }
-
- /*
- ////////////////////////////////////////////////////////////
- // Methods for common operations on std data structs
- ////////////////////////////////////////////////////////////
- */
-
- /**
- * Method that can be used to efficiently check if 2 collections
- * share at least one common element.
- *
- * @return True if there is at least one element that's common
- * to both Collections, ie. that is contained in both of them.
- */
- public static boolean anyValuesInCommon(Collection c1, Collection c2)
- {
- // Let's always iterate over smaller collection:
- if (c1.size() > c2.size()) {
- Collection tmp = c1;
- c1 = c2;
- c2 = tmp;
- }
- Iterator it = c1.iterator();
- while (it.hasNext()) {
- if (c2.contains(it.next())) {
- return true;
- }
- }
- return false;
- }
-
- final static String NO_TYPE = "Illegal to pass null; can not determine component type";
-
- public static Object growArrayBy50Pct(Object arr)
- {
- if (arr == null) {
- throw new IllegalArgumentException(NO_TYPE);
- }
- Object old = arr;
- int len = Array.getLength(arr);
- arr = Array.newInstance(arr.getClass().getComponentType(), len + (len >> 1));
- System.arraycopy(old, 0, arr, 0, len);
- return arr;
- }
-
- /**
- * Method similar to {@link #growArrayBy50Pct}, but it also ensures that
- * the new size is at least as big as the specified minimum size.
- */
- public static Object growArrayToAtLeast(Object arr, int minLen)
- {
- if (arr == null) {
- throw new IllegalArgumentException(NO_TYPE);
- }
- Object old = arr;
- int oldLen = Array.getLength(arr);
- int newLen = oldLen + ((oldLen + 1) >> 1);
- if (newLen < minLen) {
- newLen = minLen;
- }
- arr = Array.newInstance(arr.getClass().getComponentType(), newLen);
- System.arraycopy(old, 0, arr, 0, oldLen);
- return arr;
- }
-
- public static String[] growArrayBy(String[] arr, int more)
- {
- if (arr == null) {
- return new String[more];
- }
- String[] old = arr;
- int len = arr.length;
- arr = new String[len + more];
- System.arraycopy(old, 0, arr, 0, len);
- return arr;
- }
-
- public static int[] growArrayBy(int[] arr, int more)
- {
- if (arr == null) {
- return new int[more];
- }
- int[] old = arr;
- int len = arr.length;
- arr = new int[len + more];
- System.arraycopy(old, 0, arr, 0, len);
- return arr;
- }
-}
-
diff -Nru libwoodstox-java-4.1.3/src/java/com/ctc/wstx/util/DefaultXmlSymbolTable.java libwoodstox-java-5.1.0/src/java/com/ctc/wstx/util/DefaultXmlSymbolTable.java
--- libwoodstox-java-4.1.3/src/java/com/ctc/wstx/util/DefaultXmlSymbolTable.java 2012-04-24 04:38:20.000000000 +0000
+++ libwoodstox-java-5.1.0/src/java/com/ctc/wstx/util/DefaultXmlSymbolTable.java 1970-01-01 00:00:00.000000000 +0000
@@ -1,93 +0,0 @@
-package com.ctc.wstx.util;
-
-import com.ctc.wstx.util.SymbolTable;
-
-/**
- * Factory class used for instantiating pre-populated XML symbol
- * tables. Such tables already have basic String constants that
- * XML standard defines.
- */
-public final class DefaultXmlSymbolTable
-{
- /**
- * Root symbol table from which child instances are derived.
- */
- final static SymbolTable sInstance;
-
- final static String mNsPrefixXml;
- final static String mNsPrefixXmlns;
-
- /* Although theoretically there'd be no strict need to pre-populate
- * the default table, if all access was done using suggested usage
- * patterns (reuse input factories consistently, esp. for same types
- * of documents), it is possible some developers just use each factory
- * just once. As such, it does matter how tables are pre-populated.
- * Thus, let's use limited sensible set of predefined prefixes and
- * names.
- */
- static {
- /* 128 means it's ok without resize up to ~96 symbols; true that
- * default symbols added will be interned.
- */
- sInstance = new SymbolTable(true, 128);
-
- // Let's add default namespace binding prefixes
- mNsPrefixXml = sInstance.findSymbol("xml");
- mNsPrefixXmlns = sInstance.findSymbol("xmlns");
-
- /* No need to add keywords, as they are checked directly by
- * Reader, without constructing Strings.
- */
-
- // Ok, any common prefixes?
-
- // or local names (element, attribute)?
- sInstance.findSymbol("id");
- sInstance.findSymbol("name");
-
- // XML Schema?
- // prefixes:
- sInstance.findSymbol("xsd");
- sInstance.findSymbol("xsi");
- // local names:
- sInstance.findSymbol("type");
-
- // How about some common prefixes and names for Soap?
- // commonly used prefixes:
- sInstance.findSymbol("soap");
- sInstance.findSymbol("SOAP-ENC");
- sInstance.findSymbol("SOAP-ENV");
- // local names:
- sInstance.findSymbol("Body");
- sInstance.findSymbol("Envelope");
- }
-
- /*
- ///////////////////////////////////////////////////
- // Public API, factory method(s):
- ///////////////////////////////////////////////////
- */
-
- /**
- * Method that will return an instance of SymbolTable that has basic
- * XML 1.0 constants pre-populated.
- */
- public static SymbolTable getInstance() {
- return sInstance.makeChild();
- }
-
- /*
- ///////////////////////////////////////////////////
- // Public API, efficient access to (shared)
- // constants values:
- ///////////////////////////////////////////////////
- */
-
- public static String getXmlSymbol() {
- return mNsPrefixXml;
- }
-
- public static String getXmlnsSymbol() {
- return mNsPrefixXmlns;
- }
-}
diff -Nru libwoodstox-java-4.1.3/src/java/com/ctc/wstx/util/ElementId.java libwoodstox-java-5.1.0/src/java/com/ctc/wstx/util/ElementId.java
--- libwoodstox-java-4.1.3/src/java/com/ctc/wstx/util/ElementId.java 2012-04-24 04:38:20.000000000 +0000
+++ libwoodstox-java-5.1.0/src/java/com/ctc/wstx/util/ElementId.java 1970-01-01 00:00:00.000000000 +0000
@@ -1,162 +0,0 @@
-package com.ctc.wstx.util;
-
-import javax.xml.stream.Location;
-
-import com.ctc.wstx.cfg.ErrorConsts;
-
-/**
- * Simple container Object used to store information about id attribute
- * values, and references to such (as of yet undefined) values.
- *
- * Instances can be in one of 2 modes: either in fully defined mode,
- * in which case information refers to location where value was defined
- * (ie. we had id as a value of ID type attribute); or in undefined mode,
- * in which case information refers to the first reference.
- *
- * Note: this class is designed to be used with {@link ElementIdMap},
- * and as a result has some information specifically needed by the
- * map implementation (such as collision links).
- */
-public final class ElementId
-{
- /**
- * Flag that indicates whether this Object presents a defined id
- * value (value of an ID attribute) or just a reference to one.
- */
- private boolean mDefined;
-
- /*
- /////////////////////////////////////////////////
- // Information about id value or value reference,
- // depending on mDefined flag
- /////////////////////////////////////////////////
- */
-
- /**
- * Actual id value
- */
- private final String mIdValue;
-
- /**
- * Location of either definition (if {@link #mDefined} is true; or
- * first reference (otherwise). Used when reporting errors; either
- * a referenced id has not been defined, or there are multiple
- * definitions of same id.
- */
- private Location mLocation;
-
- /**
- * Name of element for which this id refers.
- */
- private PrefixedName mElemName;
-
- /**
- * Name of the attribute that contains this id value (often "id",
- * but need not be)
- */
- private PrefixedName mAttrName;
-
- /*
- ////////////////////////////////////////////////////
- // Linking information, needed by the map to keep
- // track of collided ids, as well as undefined ids
- ////////////////////////////////////////////////////
- */
-
- private ElementId mNextUndefined;
-
- /**
- * Pointer to the next element within collision chain.
- */
- private ElementId mNextColl;
-
- /*
- /////////////////////////////////////////////////
- // Life cycle
- /////////////////////////////////////////////////
- */
-
- ElementId(String id, Location loc, boolean defined,
- PrefixedName elemName, PrefixedName attrName)
- {
- mIdValue = id;
- mLocation = loc;
- mDefined = defined;
- mElemName = elemName;
- mAttrName = attrName;
- }
-
- protected void linkUndefined(ElementId undefined)
- {
- if (mNextUndefined != null) {
- throw new IllegalStateException("ElementId '"+this+"' already had net undefined set ('"+mNextUndefined+"')");
- }
- mNextUndefined = undefined;
- }
-
- protected void setNextColliding(ElementId nextColl)
- {
- // May add/remove link, no point in checking
- mNextColl = nextColl;
- }
-
- /*
- /////////////////////////////////////////////////
- // Public API
- /////////////////////////////////////////////////
- */
-
- public String getId() { return mIdValue; }
- public Location getLocation() { return mLocation; }
- public PrefixedName getElemName() { return mElemName; }
- public PrefixedName getAttrName() { return mAttrName; }
-
- public boolean isDefined() { return mDefined; }
-
- public boolean idMatches(char[] buf, int start, int len)
- {
- if (mIdValue.length() != len) {
- return false;
- }
- // Assumes it's always at least one char long
- if (buf[start] != mIdValue.charAt(0)) {
- return false;
- }
- int i = 1;
- len += start;
- while (++start < len) {
- if (buf[start] != mIdValue.charAt(i)) {
- return false;
- }
- ++i;
- }
- return true;
- }
-
- public boolean idMatches(String idStr)
- {
- return mIdValue.equals(idStr);
- }
-
- public ElementId nextUndefined() { return mNextUndefined; }
- public ElementId nextColliding() { return mNextColl; }
-
- public void markDefined(Location defLoc) {
- if (mDefined) { // sanity check
- throw new IllegalStateException(ErrorConsts.ERR_INTERNAL);
- }
- mDefined = true;
- mLocation = defLoc;
- }
-
- /*
- /////////////////////////////////////////////////
- // Other methods
- /////////////////////////////////////////////////
- */
-
- public String toString() {
- return mIdValue;
- }
-}
-
diff -Nru libwoodstox-java-4.1.3/src/java/com/ctc/wstx/util/ElementIdMap.java libwoodstox-java-5.1.0/src/java/com/ctc/wstx/util/ElementIdMap.java
--- libwoodstox-java-4.1.3/src/java/com/ctc/wstx/util/ElementIdMap.java 2012-04-24 04:38:20.000000000 +0000
+++ libwoodstox-java-5.1.0/src/java/com/ctc/wstx/util/ElementIdMap.java 1970-01-01 00:00:00.000000000 +0000
@@ -1,425 +0,0 @@
-/* Woodstox XML processor
- *
- * Copyright (c) 2004- Tatu Saloranta, tatu.saloranta@iki.fi
- *
- * Licensed under the License specified in the file LICENSE which is
- * included with the source code.
- * You may not use this file except in compliance with the License.
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.ctc.wstx.util;
-
-import javax.xml.stream.Location;
-
-
-/**
- * This class is a specialized type-safe linked hash map used for
- * storing {@link ElementId} instances. {@link ElementId} instances
- * represent both id definitions (values of element attributes that
- * have type ID in DTD), and references (values of element attributes
- * of type IDREF and IDREFS). These definitions and references are
- * stored for the purpose of verifying
- * that all referenced id values are defined, and that none are defined
- * more than once.
- *
- * Note: there are 2 somewhat distinct usage modes, by DTDValidator and
- * by MSV-based validators.
- * DTDs pass raw character arrays, whereas
- * MSV-based validators operate on Strings. This is the main reason
- * for 2 distinct sets of methods.
- */
-
-public final class ElementIdMap
-{
- /**
- * Default initial table size; set so that usually it need not
- * be expanded.
- */
- protected static final int DEFAULT_SIZE = 128;
-
- protected static final int MIN_SIZE = 16;
-
- /**
- * Let's use 80% fill factor...
- */
- protected static final int FILL_PCT = 80;
-
- /*
- ////////////////////////////////////////
- // Actual hash table structure
- ////////////////////////////////////////
- */
-
- /**
- * Actual hash table area
- */
- protected ElementId[] mTable;
-
- /**
- * Current size (number of entries); needed to know if and when
- * rehash.
- */
- protected int mSize;
-
- /**
- * Limit that indicates maximum size this instance can hold before
- * it needs to be expanded and rehashed. Calculated using fill
- * factor passed in to constructor.
- */
- protected int mSizeThreshold;
-
- /**
- * Mask used to get index from hash values; equal to
- * mBuckets.length - 1
, when mBuckets.length is
- * a power of two.
- */
- protected int mIndexMask;
-
- /*
- ////////////////////////////////////////
- // Linked list info
- ////////////////////////////////////////
- */
-
- protected ElementId mHead;
-
- protected ElementId mTail;
-
- /*
- ////////////////////////////////////////
- // Life-cycle:
- ////////////////////////////////////////
- */
-
- public ElementIdMap()
- {
- this(DEFAULT_SIZE);
- }
-
- /**
- * This constructor is mainly used for testing, as it can be sized
- * appropriately to test rehashing etc.
- */
- public ElementIdMap(int initialSize)
- {
- int actual = MIN_SIZE;
- while (actual < initialSize) {
- actual += actual;
- }
- mTable = new ElementId[actual];
- // Mask is easy to calc for powers of two.
- mIndexMask = actual - 1;
- mSize = 0;
- mSizeThreshold = (actual * FILL_PCT) / 100;
- mHead = mTail = null;
- }
-
- /*
- ////////////////////////////////////////////////////
- // Public API
- ////////////////////////////////////////////////////
- */
-
- public ElementId getFirstUndefined()
- {
- /* Since the linked list is pruned to always start with
- * the first (in doc order) undefined id, we can just
- * return head:
- */
- return mHead;
- }
-
- /**
- * Method called when a reference to id is encountered. If so, need
- * to check if specified id entry (ref or definiton) exists; and if not,
- * to add a reference marker.
- */
- public ElementId addReferenced(char[] buffer, int start, int len, int hash,
- Location loc, PrefixedName elemName, PrefixedName attrName)
- {
- int index = (hash & mIndexMask);
- ElementId id = mTable[index];
-
- while (id != null) {
- if (id.idMatches(buffer, start, len)) { // found existing one
- return id;
- }
- id = id.nextColliding();
- }
-
- // Not found, need to create a placeholder...
-
- // But first, do we need more room?
- if (mSize >= mSizeThreshold) {
- rehash();
- // Index changes, for the new entr:
- index = (hash & mIndexMask);
- }
- ++mSize;
-
- // Ok, then, let's create the entry
- String idStr = new String(buffer, start, len);
- id = new ElementId(idStr, loc, false, elemName, attrName);
-
- // First, let's link it to Map; all ids have to be connected
- id.setNextColliding(mTable[index]);
- mTable[index] = id;
-
- // And then add the undefined entry at the end of list
- if (mHead == null) {
- mHead = mTail = id;
- } else {
- mTail.linkUndefined(id);
- mTail = id;
- }
- return id;
- }
-
- public ElementId addReferenced(String idStr,
- Location loc, PrefixedName elemName, PrefixedName attrName)
- {
- int hash = calcHash(idStr);
- int index = (hash & mIndexMask);
- ElementId id = mTable[index];
-
- while (id != null) {
- if (id.idMatches(idStr)) { // found existing one
- return id;
- }
- id = id.nextColliding();
- }
-
- // Not found, need to create a placeholder...
-
- // But first, do we need more room?
- if (mSize >= mSizeThreshold) {
- rehash();
- // Index changes, for the new entr:
- index = (hash & mIndexMask);
- }
- ++mSize;
-
- // Ok, then, let's create the entry
- id = new ElementId(idStr, loc, false, elemName, attrName);
-
- // First, let's link it to Map; all ids have to be connected
- id.setNextColliding(mTable[index]);
- mTable[index] = id;
-
- // And then add the undefined entry at the end of list
- if (mHead == null) {
- mHead = mTail = id;
- } else {
- mTail.linkUndefined(id);
- mTail = id;
- }
- return id;
- }
-
- /**
- * Method called when an id definition is encountered. If so, need
- * to check if specified id entry (ref or definiton) exists. If not,
- * need to add the definition marker. If it does exist, need to
- * 'upgrade it', if it was a reference marker; otherwise need to
- * just return the old entry, and expect caller to check for dups
- * and report the error.
- */
- public ElementId addDefined(char[] buffer, int start, int len, int hash,
- Location loc, PrefixedName elemName, PrefixedName attrName)
- {
- int index = (hash & mIndexMask);
- ElementId id = mTable[index];
-
- while (id != null) {
- if (id.idMatches(buffer, start, len)) {
- break;
- }
- id = id.nextColliding();
- }
-
- /* Not found, can just add it to the Map; no need to add to the
- * linked list as it's not undefined
- */
- if (id == null) {
- // First, do we need more room?
- if (mSize >= mSizeThreshold) {
- rehash();
- index = (hash & mIndexMask);
- }
- ++mSize;
- String idStr = new String(buffer, start, len);
- id = new ElementId(idStr, loc, true, elemName, attrName);
- id.setNextColliding(mTable[index]);
- mTable[index] = id;
- } else {
- /* If already defined, nothing additional to do (we could
- * signal an error here, though... for now, we'll let caller
- * do that
- */
- if (id.isDefined()) {
- ;
- } else {
- /* Not defined, just need to upgrade, and possibly remove from
- * the linked list.
- */
- id.markDefined(loc);
-
- /* Ok; if it was the first undefined, need to unlink it, as
- * well as potentially next items.
- */
- if (id == mHead) {
- do {
- mHead = mHead.nextUndefined();
- } while (mHead != null && mHead.isDefined());
-
- // Did we clear up all undefined ids?
- if (mHead == null) {
- mTail = null;
- }
- }
- }
- }
-
- return id;
- }
-
- public ElementId addDefined(String idStr,
- Location loc, PrefixedName elemName, PrefixedName attrName)
- {
- int hash = calcHash(idStr);
- int index = (hash & mIndexMask);
- ElementId id = mTable[index];
-
- while (id != null) {
- if (id.idMatches(idStr)) {
- break;
- }
- id = id.nextColliding();
- }
-
- /* Not found, can just add it to the Map; no need to add to the
- * linked list as it's not undefined
- */
- if (id == null) {
- if (mSize >= mSizeThreshold) { // need more room
- rehash();
- index = (hash & mIndexMask);
- }
- ++mSize;
- id = new ElementId(idStr, loc, true, elemName, attrName);
- id.setNextColliding(mTable[index]);
- mTable[index] = id;
- } else {
- /* If already defined, nothing additional to do (we could
- * signal an error here, though... for now, we'll let caller
- * do that
- */
- if (id.isDefined()) {
- ;
- } else {
- /* Not defined, just need to upgrade, and possibly remove from
- * the linked list.
- */
- id.markDefined(loc);
-
- /* Ok; if it was the first undefined, need to unlink it, as
- * well as potentially next items.
- */
- if (id == mHead) {
- do {
- mHead = mHead.nextUndefined();
- } while (mHead != null && mHead.isDefined());
- if (mHead == null) { // cleared up all undefined ids?
- mTail = null;
- }
- }
- }
- }
-
- return id;
- }
-
- /**
- * Implementation of a hashing method for variable length
- * Strings. Most of the time intention is that this calculation
- * is done by caller during parsing, not here; however, sometimes
- * it needs to be done for parsed "String" too.
- *
- * Note: identical to {@link com.ctc.wstx.util.SymbolTable#calcHash},
- * although not required to be.
- *
- * @param len Length of String; has to be at least 1 (caller guarantees
- * this pre-condition)
- */
- public static int calcHash(char[] buffer, int start, int len)
- {
- int hash = (int) buffer[0];
- for (int i = 1; i < len; ++i) {
- hash = (hash * 31) + (int) buffer[i];
- }
- return hash;
- }
-
- public static int calcHash(String key)
- {
- int hash = (int) key.charAt(0);
- for (int i = 1, len = key.length(); i < len; ++i) {
- hash = (hash * 31) + (int) key.charAt(i);
-
- }
- return hash;
- }
-
- /*
- //////////////////////////////////////////////////////////
- // Internal methods
- //////////////////////////////////////////////////////////
- */
-
- /**
- * Method called when size (number of entries) of symbol table grows
- * so big that load factor is exceeded. Since size has to remain
- * power of two, arrays will then always be doubled. Main work
- * is really redistributing old entries into new String/Bucket
- * entries.
- */
- private void rehash()
- {
- int size = mTable.length;
- /* Let's grow aggressively; this should minimize number of
- * resizes, while adding to mem usage. But since these Maps
- * are never long-lived (only during parsing and validation of
- * a single doc), that shouldn't greatly matter.
- */
- int newSize = (size << 2);
- ElementId[] oldSyms = mTable;
- mTable = new ElementId[newSize];
-
- // Let's update index mask, threshold, now (needed for rehashing)
- mIndexMask = newSize - 1;
- mSizeThreshold <<= 2;
-
- int count = 0; // let's do sanity check
-
- for (int i = 0; i < size; ++i) {
- for (ElementId id = oldSyms[i]; id != null; ) {
- ++count;
- int index = calcHash(id.getId()) & mIndexMask;
- ElementId nextIn = id.nextColliding();
- id.setNextColliding(mTable[index]);
- mTable[index] = id;
- id = nextIn;
- }
- }
-
- if (count != mSize) {
- ExceptionUtil.throwInternal("on rehash(): had "+mSize+" entries; now have "+count+".");
- }
- }
-}
diff -Nru libwoodstox-java-4.1.3/src/java/com/ctc/wstx/util/EmptyNamespaceContext.java libwoodstox-java-5.1.0/src/java/com/ctc/wstx/util/EmptyNamespaceContext.java
--- libwoodstox-java-4.1.3/src/java/com/ctc/wstx/util/EmptyNamespaceContext.java 2012-04-24 04:38:20.000000000 +0000
+++ libwoodstox-java-5.1.0/src/java/com/ctc/wstx/util/EmptyNamespaceContext.java 1970-01-01 00:00:00.000000000 +0000
@@ -1,71 +0,0 @@
-package com.ctc.wstx.util;
-
-import java.io.Writer;
-import java.util.Iterator;
-
-import javax.xml.namespace.NamespaceContext;
-import javax.xml.stream.XMLStreamWriter;
-
-import org.codehaus.stax2.ri.EmptyIterator;
-
-/**
- * Dummy {@link NamespaceContext} (and {@link BaseNsContext})
- * implementation that is usually used in
- * non-namespace-aware mode.
- *
- * Note: differs from Stax2 reference implementation's version
- * slightly, since it needs to support Woodstox specific extensions
- * for efficient namespace declaration serialization.
- */
-public final class EmptyNamespaceContext
- extends BaseNsContext
-{
- final static EmptyNamespaceContext sInstance = new EmptyNamespaceContext();
-
- private EmptyNamespaceContext() { }
-
- public static EmptyNamespaceContext getInstance() { return sInstance; }
-
- /*
- /////////////////////////////////////////////
- // Extended API
- /////////////////////////////////////////////
- */
-
- public Iterator getNamespaces() {
- return EmptyIterator.getInstance();
- }
-
- /**
- * Method called by the matching start element class to
- * output all namespace declarations active in current namespace
- * scope, if any.
- */
- public void outputNamespaceDeclarations(Writer w)
- {
- ; // nothing to output
- }
-
- public void outputNamespaceDeclarations(XMLStreamWriter w)
- {
- ; // nothing to output
- }
-
- /*
- /////////////////////////////////////////////////
- // Template methods sub-classes need to implement
- /////////////////////////////////////////////////
- */
-
- public String doGetNamespaceURI(String prefix) {
- return null;
- }
-
- public String doGetPrefix(String nsURI) {
- return null;
- }
-
- public Iterator doGetPrefixes(String nsURI) {
- return EmptyIterator.getInstance();
- }
-}
diff -Nru libwoodstox-java-4.1.3/src/java/com/ctc/wstx/util/ExceptionUtil.java libwoodstox-java-5.1.0/src/java/com/ctc/wstx/util/ExceptionUtil.java
--- libwoodstox-java-4.1.3/src/java/com/ctc/wstx/util/ExceptionUtil.java 2012-04-24 04:38:20.000000000 +0000
+++ libwoodstox-java-5.1.0/src/java/com/ctc/wstx/util/ExceptionUtil.java 1970-01-01 00:00:00.000000000 +0000
@@ -1,72 +0,0 @@
-package com.ctc.wstx.util;
-
-public final class ExceptionUtil
-{
- private ExceptionUtil() { }
-
- /**
- * Method that can be used to convert any Throwable to a RuntimeException;
- * conversion is only done for checked exceptions.
- */
- public static void throwRuntimeException(Throwable t)
- {
- // Unchecked? Can re-throw as is
- throwIfUnchecked(t);
- // Otherwise, let's just change its type:
- RuntimeException rex = new RuntimeException("[was "+t.getClass()+"] "+t.getMessage());
- // And indicate the root cause
- setInitCause(rex, t);
- throw rex;
- }
-
- public static void throwAsIllegalArgument(Throwable t)
- {
- // Unchecked? Can re-throw as is
- throwIfUnchecked(t);
- // Otherwise, let's just change its type:
- IllegalArgumentException rex = new IllegalArgumentException("[was "+t.getClass()+"] "+t.getMessage());
- // And indicate the root cause
- setInitCause(rex, t);
- throw rex;
- }
-
- public static void throwIfUnchecked(Throwable t)
- {
- // If it's not checked, let's throw it as is
- if (t instanceof RuntimeException) {
- throw (RuntimeException) t;
- }
- if (t instanceof Error) {
- throw (Error) t;
- }
- }
-
- /**
- * This method is just added for convenience, and only to be used for
- * assertion style of exceptions. For errors that actually occur, method
- * with the string arg should be called instead.
- */
- public static void throwGenericInternal()
- {
- throwInternal(null);
- }
-
- public static void throwInternal(String msg)
- {
- if (msg == null) {
- msg = "[no description]";
- }
- throw new RuntimeException("Internal error: "+msg);
- }
-
- public static void setInitCause(Throwable newT, Throwable rootT)
- {
- /* [WSTX-110]: Better make sure we do not already have
- * a chained exception...
- */
- if (newT.getCause() == null) {
- newT.initCause(rootT);
- }
- }
-}
-
diff -Nru libwoodstox-java-4.1.3/src/java/com/ctc/wstx/util/InternCache.java libwoodstox-java-5.1.0/src/java/com/ctc/wstx/util/InternCache.java
--- libwoodstox-java-4.1.3/src/java/com/ctc/wstx/util/InternCache.java 2012-04-24 04:38:20.000000000 +0000
+++ libwoodstox-java-5.1.0/src/java/com/ctc/wstx/util/InternCache.java 1970-01-01 00:00:00.000000000 +0000
@@ -1,72 +0,0 @@
-package com.ctc.wstx.util;
-
-import java.util.LinkedHashMap;
-import java.util.Map;
-
-/**
- * Singleton class that implements "fast intern" functionality, essentially
- * adding a layer that caches Strings that have been previously intern()ed,
- * but that probably shouldn't be added to symbol tables.
- * This is usually used by improving intern()ing of things like namespace
- * URIs.
- *
- * Note: that this class extends {@link LinkedHashMap} is an implementation
- * detail -- no code should ever directly call Map methods.
- */
-public final class InternCache extends LinkedHashMap //
-{
- private static final long serialVersionUID = 1L;
-
- /**
- * Let's create cache big enough to usually have enough space for
- * all entries... (assuming NS URIs only)
- */
- private final static int DEFAULT_SIZE = 64;
-
- /**
- * Let's limit to hash area size of 1024.
- */
- private final static int MAX_SIZE = 660;
-
- private final static InternCache sInstance = new InternCache();
-
- private InternCache() {
- /* Let's also try to seriously minimize collisions... since
- * collisions are likely to be more costly here, with longer
- * Strings; so let's use 2/3 ratio (67%) instead of default
- * (75%)
- */
- super(DEFAULT_SIZE, 0.6666f, false);
- }
-
- public static InternCache getInstance() {
- return sInstance;
- }
-
- public String intern(String input)
- {
- String result;
-
- /* Let's split sync block to help in edge cases like
- * [WSTX-220]
- */
- synchronized (this) {
- result = (String) get(input);
- }
- if (result == null) {
- result = input.intern();
- synchronized (this) {
- put(result, result);
- }
- }
- return result;
- }
-
- // We will force maximum size here (for [WSTX-237])
- //@Override protected boolean removeEldestEntry(Map.Entry eldest)
- protected boolean removeEldestEntry(Map.Entry eldest)
- {
- return size() > MAX_SIZE;
- }
-}
-
diff -Nru libwoodstox-java-4.1.3/src/java/com/ctc/wstx/util/package.html libwoodstox-java-5.1.0/src/java/com/ctc/wstx/util/package.html
--- libwoodstox-java-4.1.3/src/java/com/ctc/wstx/util/package.html 2012-04-24 04:38:21.000000000 +0000
+++ libwoodstox-java-5.1.0/src/java/com/ctc/wstx/util/package.html 1970-01-01 00:00:00.000000000 +0000
@@ -1,7 +0,0 @@
-
-Contains utility classes that are not directly Woodstox specific, but are
-for now only used by Woodstox.
-
-Note that some of more generic classes may eventually be moved to more
-generic packages under com.ctc
package.
-
diff -Nru libwoodstox-java-4.1.3/src/java/com/ctc/wstx/util/PrefixedName.java libwoodstox-java-5.1.0/src/java/com/ctc/wstx/util/PrefixedName.java
--- libwoodstox-java-4.1.3/src/java/com/ctc/wstx/util/PrefixedName.java 2012-04-24 04:38:20.000000000 +0000
+++ libwoodstox-java-5.1.0/src/java/com/ctc/wstx/util/PrefixedName.java 1970-01-01 00:00:00.000000000 +0000
@@ -1,185 +0,0 @@
-/* Woodstox XML processor
- *
- * Copyright (c) 2004 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 com.ctc.wstx.util;
-
-import javax.xml.namespace.QName;
-
-/**
- * Simple key Object to be used for storing/accessing of potentially namespace
- * scoped element and attribute names.
- *
- * One important note about usage is that two of the name components (prefix
- * and local name) HAVE to have been interned some way, as all comparisons
- * are done using identity comparison; whereas URI is NOT necessarily
- * interned.
- *
- * Note that the main reason this class is mutable -- unlike most key classes
- * -- is that this allows reusing key objects for access, as long as the code
- * using it knows ramifications of trying to modify a key that's used
- * in a data structure.
- *
- * Note, too, that the hash code is cached as this class is mostly used as
- * a Map key, and hash code is used a lot.
- */
-public final class PrefixedName
- implements Comparable // to allow alphabetic ordering
-{
- private String mPrefix, mLocalName;
-
- volatile int mHash = 0;
-
- /*
- ///////////////////////////////////////////////////
- // Life-cycle
- ///////////////////////////////////////////////////
- */
-
- public PrefixedName(String prefix, String localName)
- {
- mLocalName = localName;
- mPrefix = (prefix != null && prefix.length() == 0) ?
- null : prefix;
- }
-
- public PrefixedName reset(String prefix, String localName)
- {
- mLocalName = localName;
- mPrefix = (prefix != null && prefix.length() == 0) ?
- null : prefix;
- mHash = 0;
- return this;
- }
-
- public static PrefixedName valueOf(QName n)
- {
- return new PrefixedName(n.getPrefix(), n.getLocalPart());
- }
-
- /*
- ///////////////////////////////////////////////////
- // Accessors:
- ///////////////////////////////////////////////////
- */
-
- public String getPrefix() { return mPrefix; }
-
- public String getLocalName() { return mLocalName; }
-
- /**
- * @return True, if this attribute name would result in a namespace
- * binding (ie. it's "xmlns" or starts with "xmlns:").
- */
- public boolean isaNsDeclaration()
- {
- if (mPrefix == null) {
- return mLocalName == "xmlns";
- }
- return mPrefix == "xmlns";
- }
-
- /**
- * Method used to check for xml reserved attribute names, like
- * "xml:space" and "xml:id".
- *
- * Note: it is assumed that the passed-in localName is also
- * interned.
- */
- public boolean isXmlReservedAttr(boolean nsAware, String localName)
- {
- if (nsAware) {
- if ("xml" == mPrefix) {
- return mLocalName == localName;
- }
- } else {
- if (mLocalName.length() == (4 + localName.length())) {
- return (mLocalName.startsWith("xml:")
- && mLocalName.endsWith(localName));
- }
- }
- return false;
- }
-
- /*
- ///////////////////////////////////////////////////
- // Overridden standard methods:
- ///////////////////////////////////////////////////
- */
-
- public String toString()
- {
- if (mPrefix == null || mPrefix.length() == 0) {
- return mLocalName;
- }
- StringBuffer sb = new StringBuffer(mPrefix.length() + 1 + mLocalName.length());
- sb.append(mPrefix);
- sb.append(':');
- sb.append(mLocalName);
- return sb.toString();
- }
-
- public boolean equals(Object o)
- {
- if (o == this) {
- return true;
- }
- if (!(o instanceof PrefixedName)) { // also filters out nulls
- return false;
- }
- PrefixedName other = (PrefixedName) o;
-
- if (mLocalName != other.mLocalName) { // assumes equality
- return false;
- }
- return (mPrefix == other.mPrefix);
- }
-
- public int hashCode() {
- int hash = mHash;
-
- if (hash == 0) {
- hash = mLocalName.hashCode();
- if (mPrefix != null) {
- hash ^= mPrefix.hashCode();
- }
- mHash = hash;
- }
- return hash;
- }
-
- public int compareTo(Object o)
- {
- PrefixedName other = (PrefixedName) o;
-
- // First, by prefix, then by local name:
- String op = other.mPrefix;
-
- // Missing prefix is ordered before existing prefix
- if (op == null || op.length() == 0) {
- if (mPrefix != null && mPrefix.length() > 0) {
- return 1;
- }
- } else if (mPrefix == null || mPrefix.length() == 0) {
- return -1;
- } else {
- int result = mPrefix.compareTo(op);
- if (result != 0) {
- return result;
- }
- }
-
- return mLocalName.compareTo(other.mLocalName);
- }
-}
diff -Nru libwoodstox-java-4.1.3/src/java/com/ctc/wstx/util/SimpleCache.java libwoodstox-java-5.1.0/src/java/com/ctc/wstx/util/SimpleCache.java
--- libwoodstox-java-4.1.3/src/java/com/ctc/wstx/util/SimpleCache.java 2012-04-24 04:38:21.000000000 +0000
+++ libwoodstox-java-5.1.0/src/java/com/ctc/wstx/util/SimpleCache.java 1970-01-01 00:00:00.000000000 +0000
@@ -1,59 +0,0 @@
-package com.ctc.wstx.util;
-
-import java.util.*;
-
-/**
- * Simple Map implementation usable for caches where contents do not
- * expire, but where size needs to remain bounded.
- *
- * Note: we probably should use weak references, or something similar
- * to limit maximum memory usage. This could be implemented in many
- * ways, perhaps by using two areas: first, smaller one, with strong
- * refs, and secondary bigger one that uses soft references.
- */
-public final class SimpleCache
-{
- protected final LimitMap mItems;
-
- protected final int mMaxSize;
-
- public SimpleCache(int maxSize)
- {
- mItems = new LimitMap(maxSize);
- mMaxSize = maxSize;
- }
-
- public Object find(Object key) {
- return mItems.get(key);
- }
-
- public void add(Object key, Object value)
- {
- mItems.put(key, value);
- }
-
- /*
- ///////////////////////////////////////////////////////////////////////
- // Helper classes
- ///////////////////////////////////////////////////////////////////////
- */
-
- final static class LimitMap
- extends LinkedHashMap
- {
- private static final long serialVersionUID = 1L;
-
- protected final int mMaxSize;
-
- public LimitMap(int size)
- {
- super(size, 0.8f, true);
- // Let's not allow silly low values...
- mMaxSize = size;
- }
-
- public boolean removeEldestEntry(Map.Entry eldest) {
- return (size() >= mMaxSize);
- }
- }
-}
diff -Nru libwoodstox-java-4.1.3/src/java/com/ctc/wstx/util/StringUtil.java libwoodstox-java-5.1.0/src/java/com/ctc/wstx/util/StringUtil.java
--- libwoodstox-java-4.1.3/src/java/com/ctc/wstx/util/StringUtil.java 2012-04-24 04:38:21.000000000 +0000
+++ libwoodstox-java-5.1.0/src/java/com/ctc/wstx/util/StringUtil.java 1970-01-01 00:00:00.000000000 +0000
@@ -1,339 +0,0 @@
-package com.ctc.wstx.util;
-
-import java.util.Collection;
-import java.util.Iterator;
-
-public final class StringUtil
-{
- final static char CHAR_SPACE = ' '; // 0x0020
- private final static char INT_SPACE = 0x0020;
-
- static String sLF = null;
-
- public static String getLF()
- {
- String lf = sLF;
- if (lf == null) {
- try {
- lf = (String) System.getProperty("line.separator");
- sLF = (lf == null) ? "\n" : lf;
- } catch (Throwable t) {
- // Doh.... whatever; most likely SecurityException
- sLF = lf = "\n";
- }
- }
- return lf;
- }
-
- public static void appendLF(StringBuffer sb) {
- sb.append(getLF());
- }
-
- public static String concatEntries(Collection coll, String sep, String lastSep) {
- if (lastSep == null) {
- lastSep = sep;
- }
- int len = coll.size();
- StringBuffer sb = new StringBuffer(16 + (len << 3));
- Iterator it = coll.iterator();
- int i = 0;
- while (it.hasNext()) {
- if (i == 0) {
- ;
- } else if (i == (len - 1)) {
- sb.append(lastSep);
- } else {
- sb.append(sep);
- }
- ++i;
- sb.append(it.next());
- }
- return sb.toString();
- }
-
- /**
- * Method that will check character array passed, and remove all
- * "extra" spaces (leading and trailing space), and normalize
- * other white space (more than one consequtive space character
- * replaced with a single space).
- *
- * NOTE: we only remove explicit space characters (char code 0x0020);
- * the reason being that other white space must have come from
- * non-normalizable sources, ie. via entity expansion, and is thus
- * not to be normalized
- *
- * @param buf Buffer that contains the String to check
- * @param origStart Offset of the first character of the text to check
- * in the buffer
- * @param origEnd Offset of the character following the last character
- * of the text (as per usual Java API convention)
- *
- * @return Normalized String, if any white space was removed or
- * normalized; null if no changes were necessary.
- */
- public static String normalizeSpaces(char[] buf, int origStart, int origEnd)
- {
- --origEnd;
-
- int start = origStart;
- int end = origEnd;
-
- // First let's trim start...
- while (start <= end && buf[start] == CHAR_SPACE) {
- ++start;
- }
- // Was it all empty?
- if (start > end) {
- return "";
- }
-
- /* Nope, need to trim from the end then (note: it's known that char
- * at index 'start' is not a space, at this point)
- */
- while (end > start && buf[end] == CHAR_SPACE) {
- --end;
- }
-
- /* Ok, may have changes or not: now need to normalize
- * intermediate duplicate spaces. We also now that the
- * first and last characters can not be spaces.
- */
- int i = start+1;
-
- while (i < end) {
- if (buf[i] == CHAR_SPACE) {
- if (buf[i+1] == CHAR_SPACE) {
- break;
- }
- // Nah; no hole for these 2 chars!
- i += 2;
- } else {
- ++i;
- }
- }
-
- // Hit the end?
- if (i >= end) {
- // Any changes?
- if (start == origStart && end == origEnd) {
- return null; // none
- }
- return new String(buf, start, (end-start)+1);
- }
-
- /* Nope, got a hole, need to constuct the damn thing. Shouldn't
- * happen too often... so let's just use StringBuffer()
- */
- StringBuffer sb = new StringBuffer(end-start); // can't be longer
- sb.append(buf, start, i-start); // won't add the starting space
-
- while (i <= end) {
- char c = buf[i++];
- if (c == CHAR_SPACE) {
- sb.append(CHAR_SPACE);
- // Need to skip dups
- while (true) {
- c = buf[i++];
- if (c != CHAR_SPACE) {
- sb.append(c);
- break;
- }
- }
- } else {
- sb.append(c);
- }
- }
-
- return sb.toString();
- }
-
- public static boolean isAllWhitespace(String str)
- {
- for (int i = 0, len = str.length(); i < len; ++i) {
- if (str.charAt(i) > CHAR_SPACE) {
- return false;
- }
- }
- return true;
- }
-
- public static boolean isAllWhitespace(char[] ch, int start, int len)
- {
- len += start;
- for (; start < len; ++start) {
- if (ch[start] > CHAR_SPACE) {
- return false;
- }
- }
- return true;
- }
-
- /**
- * Internal constant used to denote END-OF-STRING
- */
- private final static int EOS = 0x10000;
-
- /**
- * Method that implements a loose String compairon for encoding
- * Strings. It will work like {@link String#equalsIgnoreCase},
- * except that it will also ignore all hyphen, underscore and
- * space characters.
- */
- public static boolean equalEncodings(String str1, String str2)
- {
- final int len1 = str1.length();
- final int len2 = str2.length();
-
- // Need to loop completely over both Strings
- for (int i1 = 0, i2 = 0; i1 < len1 || i2 < len2; ) {
- int c1 = (i1 >= len1) ? EOS : str1.charAt(i1++);
- int c2 = (i2 >= len2) ? EOS : str2.charAt(i2++);
-
- // Can first do a quick comparison (usually they are equal)
- if (c1 == c2) {
- continue;
- }
-
- // if not equal, maybe there are WS/hyphen/underscores to skip
- while (c1 <= INT_SPACE || c1 == '_' || c1 == '-') {
- c1 = (i1 >= len1) ? EOS : str1.charAt(i1++);
- }
- while (c2 <= INT_SPACE || c2 == '_' || c2 == '-') {
- c2 = (i2 >= len2) ? EOS : str2.charAt(i2++);
- }
- // Ok, how about case differences, then?
- if (c1 != c2) {
- // If one is EOF, can't match (one is substring of the other)
- if (c1 == EOS || c2 == EOS) {
- return false;
- }
- if (c1 < 127) { // ascii is easy...
- if (c1 <= 'Z' && c1 >= 'A') {
- c1 = c1 + ('a' - 'A');
- }
- } else {
- c1 = Character.toLowerCase((char)c1);
- }
- if (c2 < 127) { // ascii is easy...
- if (c2 <= 'Z' && c2 >= 'A') {
- c2 = c2 + ('a' - 'A');
- }
- } else {
- c2 = Character.toLowerCase((char)c2);
- }
- if (c1 != c2) {
- return false;
- }
- }
- }
-
- // If we got this far, we are ok as long as we got through it all
- return true;
- }
-
- public static boolean encodingStartsWith(String enc, String prefix)
- {
- int len1 = enc.length();
- int len2 = prefix.length();
-
- int i1 = 0, i2 = 0;
-
- // Need to loop completely over both Strings
- while (i1 < len1 || i2 < len2) {
- int c1 = (i1 >= len1) ? EOS : enc.charAt(i1++);
- int c2 = (i2 >= len2) ? EOS : prefix.charAt(i2++);
-
- // Can first do a quick comparison (usually they are equal)
- if (c1 == c2) {
- continue;
- }
-
- // if not equal, maybe there are WS/hyphen/underscores to skip
- while (c1 <= CHAR_SPACE || c1 == '_' || c1 == '-') {
- c1 = (i1 >= len1) ? EOS : enc.charAt(i1++);
- }
- while (c2 <= CHAR_SPACE || c2 == '_' || c2 == '-') {
- c2 = (i2 >= len2) ? EOS : prefix.charAt(i2++);
- }
- // Ok, how about case differences, then?
- if (c1 != c2) {
- if (c2 == EOS) { // Prefix done, good!
- return true;
- }
- if (c1 == EOS) { // Encoding done, not good
- return false;
- }
- if (Character.toLowerCase((char)c1) != Character.toLowerCase((char)c2)) {
- return false;
- }
- }
- }
-
- // Ok, prefix was exactly the same as encoding... that's fine
- return true;
- }
-
- /**
- * Method that will remove all non-alphanumeric characters, and optionally
- * upper-case included letters, from the given String.
- */
- public static String trimEncoding(String str, boolean upperCase)
- {
- int i = 0;
- int len = str.length();
-
- // Let's first check if String is fine as is:
- for (; i < len; ++i) {
- char c = str.charAt(i);
- if (c <= CHAR_SPACE || !Character.isLetterOrDigit(c)) {
- break;
- }
- }
-
- if (i == len) {
- return str;
- }
-
- // Nope: have to trim it
- StringBuffer sb = new StringBuffer();
- if (i > 0) {
- sb.append(str.substring(0, i));
- }
- for (; i < len; ++i) {
- char c = str.charAt(i);
- if (c > CHAR_SPACE && Character.isLetterOrDigit(c)) {
- if (upperCase) {
- c = Character.toUpperCase(c);
- }
- sb.append(c);
- }
- }
-
- return sb.toString();
- }
-
- public static boolean matches(String str, char[] cbuf, int offset, int len)
- {
- if (str.length() != len) {
- return false;
- }
- for (int i = 0; i < len; ++i) {
- if (str.charAt(i) != cbuf[offset+i]) {
- return false;
- }
- }
- return true;
- }
-
- /**
- *
- * 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)
- */
- public final static boolean isSpace(char c)
- {
- return ((int) c) <= 0x0020;
- }
-}
diff -Nru libwoodstox-java-4.1.3/src/java/com/ctc/wstx/util/StringVector.java libwoodstox-java-5.1.0/src/java/com/ctc/wstx/util/StringVector.java
--- libwoodstox-java-4.1.3/src/java/com/ctc/wstx/util/StringVector.java 2012-04-24 04:38:21.000000000 +0000
+++ libwoodstox-java-5.1.0/src/java/com/ctc/wstx/util/StringVector.java 1970-01-01 00:00:00.000000000 +0000
@@ -1,244 +0,0 @@
-package com.ctc.wstx.util;
-
-/**
- * Data container similar {@link java.util.List} (from storage perspective),
- * but that can be used in multiple ways. For some uses it acts more like
- * type-safe String list/vector; for others as order associative list of
- * String-to-String mappings.
- */
-public final class StringVector
-{
- private String[] mStrings;
-
- private int mSize;
-
- /*
- ///////////////////////////////////////////////////////
- // Life-cycle:
- ///////////////////////////////////////////////////////
- */
-
- public StringVector(int initialCount) {
- mStrings = new String[initialCount];
- }
-
- /*
- ///////////////////////////////////////////////////////
- // Basic accessors
- ///////////////////////////////////////////////////////
- */
-
- public int size() { return mSize; }
-
- public boolean isEmpty() { return mSize == 0; }
-
- public String getString(int index) {
- if (index < 0 || index >= mSize) {
- throw new IllegalArgumentException("Index "+index+" out of valid range; current size: "+mSize+".");
- }
- return mStrings[index];
- }
-
- public String getLastString() {
- if (mSize < 1) {
- throw new IllegalStateException("getLastString() called on empty StringVector.");
- }
- return mStrings[mSize-1];
- }
-
- public String[] getInternalArray() {
- return mStrings;
- }
-
- public String[] asArray() {
- String[] strs = new String[mSize];
- System.arraycopy(mStrings, 0, strs, 0, mSize);
- return strs;
- }
-
- public boolean containsInterned(String value) {
- String[] str = mStrings;
- for (int i = 0, len = mSize; i < len; ++i) {
- if (str[i] == value) {
- return true;
- }
- }
- return false;
- }
-
- /*
- ///////////////////////////////////////////////////////
- // Mutators:
- ///////////////////////////////////////////////////////
- */
-
- public void addString(String str) {
- if (mSize == mStrings.length) {
- String[] old = mStrings;
- int oldSize = old.length;
- mStrings = new String[oldSize + (oldSize << 1)];
- System.arraycopy(old, 0, mStrings, 0, oldSize);
- }
- mStrings[mSize++] = str;
- }
-
- public void addStrings(String str1, String str2) {
- if ((mSize + 2) > mStrings.length) {
- String[] old = mStrings;
- int oldSize = old.length;
- mStrings = new String[oldSize + (oldSize << 1)];
- System.arraycopy(old, 0, mStrings, 0, oldSize);
- }
- mStrings[mSize] = str1;
- mStrings[mSize+1] = str2;
- mSize += 2;
- }
-
- public void setString(int index, String str) {
- mStrings[index] = str;
- }
-
- public void clear(boolean removeRefs) {
- if (removeRefs) {
- for (int i = 0, len = mSize; i < len; ++i) {
- mStrings[i] = null;
- }
- }
- mSize = 0;
- }
-
- public String removeLast() {
- String result = mStrings[--mSize];
- mStrings[mSize] = null;
- return result;
- }
-
- public void removeLast(int count) {
- while (--count >= 0) {
- mStrings[--mSize] = null;
- }
- }
-
- /*
- ///////////////////////////////////////////////////////
- // Specialized "map accessors":
- ///////////////////////////////////////////////////////
- */
-
- /**
- * Specialized access method; treats vector as a Map, with 2 Strings
- * per entry; first one being key, second value. Further, keys are
- * assumed to be canonicalized with passed in key (ie. either intern()ed,
- * or resolved from symbol table).
- * Starting from the
- * end (assuming even number of entries), tries to find an entry with
- * matching key, and if so, returns value.
- */
- public String findLastFromMap(String key) {
- int index = mSize;
- while ((index -= 2) >= 0) {
- if (mStrings[index] == key) {
- return mStrings[index+1];
- }
- }
- return null;
- }
-
- public String findLastNonInterned(String key)
- {
- int index = mSize;
- while ((index -= 2) >= 0) {
- String curr = mStrings[index];
- if (curr == key || (curr != null && curr.equals(key))) {
- return mStrings[index+1];
- }
- }
- return null;
- }
-
- public int findLastIndexNonInterned(String key) {
- int index = mSize;
- while ((index -= 2) >= 0) {
- String curr = mStrings[index];
- if (curr == key || (curr != null && curr.equals(key))) {
- return index;
- }
- }
- return -1;
- }
-
- public String findLastByValueNonInterned(String value) {
- for (int index = mSize-1; index > 0; index -= 2) {
- String currVal = mStrings[index];
- if (currVal == value || (currVal != null && currVal.equals(value))) {
- return mStrings[index-1];
- }
- }
- return null;
- }
-
- public int findLastIndexByValueNonInterned(String value) {
- for (int index = mSize-1; index > 0; index -= 2) {
- String currVal = mStrings[index];
- if (currVal == value || (currVal != null && currVal.equals(value))) {
- return index-1;
- }
- }
- return -1;
- }
-
- /*
- // Not needed any more
- public Iterator findAllByValueNonInterned(String value) {
- String first = null;
- ArrayList all = null;
- for (int index = mSize-1; index > 0; index -= 2) {
- String currVal = mStrings[index];
- if (currVal == value || (currVal != null && currVal.equals(value))) {
- if (first == null) {
- first = mStrings[index-1];
- } else {
- if (all == null) {
- all = new ArrayList();
- all.add(first);
- }
- all.add(mStrings[index-1]);
- }
- }
- }
- if (all != null) {
- return all.iterator();
- }
- if (first != null) {
- return new SingletonIterator(first);
- }
- return EmptyIterator.getInstance();
- }
- */
-
- /*
- ///////////////////////////////////////////////////////
- // Other methods
- ///////////////////////////////////////////////////////
- */
-
- public String toString() {
- StringBuffer sb = new StringBuffer(mSize * 16);
- sb.append("[(size = ");
- sb.append(mSize);
- sb.append(" ) ");
- for (int i = 0; i < mSize; ++i) {
- if (i > 0) {
- sb.append(", ");
- }
- sb.append('"');
- sb.append(mStrings[i]);
- sb.append('"');
-
- sb.append(" == ");
- sb.append(Integer.toHexString(System.identityHashCode(mStrings[i])));
- }
- sb.append(']');
- return sb.toString();
- }
-}
diff -Nru libwoodstox-java-4.1.3/src/java/com/ctc/wstx/util/SymbolTable.java libwoodstox-java-5.1.0/src/java/com/ctc/wstx/util/SymbolTable.java
--- libwoodstox-java-4.1.3/src/java/com/ctc/wstx/util/SymbolTable.java 2012-04-24 04:38:21.000000000 +0000
+++ libwoodstox-java-5.1.0/src/java/com/ctc/wstx/util/SymbolTable.java 1970-01-01 00:00:00.000000000 +0000
@@ -1,731 +0,0 @@
-/* Woodstox XML processor
- *
- * Copyright (c) 2004- Tatu Saloranta, tatu.saloranta@iki.fi
- *
- * Licensed under the License specified in the file LICENSE which is
- * included with the source code.
- * You may not use this file except in compliance with the License.
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.ctc.wstx.util;
-
-/**
- * This class is a kind of specialized type-safe Map, from char array to
- * String value. Specialization means that in addition to type-safety
- * and specific access patterns (key char array, Value optionally interned
- * String; values added on access if necessary), and that instances are
- * meant to be used concurrently, but by using well-defined mechanisms
- * to obtain such concurrently usable instances. Main use for the class
- * is to store symbol table information for things like compilers and
- * parsers; especially when number of symbols (keywords) is limited.
- *
- * For optimal performance, usage pattern should be one where matches
- * should be very common (esp. after "warm-up"), and as with most hash-based
- * maps/sets, that hash codes are uniformly distributed. Also, collisions
- * are slightly more expensive than with HashMap or HashSet, since hash codes
- * are not used in resolving collisions; that is, equals() comparison is
- * done with all symbols in same bucket index.
- * Finally, rehashing is also more expensive, as hash codes are not
- * stored; rehashing requires all entries' hash codes to be recalculated.
- * Reason for not storing hash codes is reduced memory usage, hoping
- * for better memory locality.
- *
- * Usual usage pattern is to create a single "master" instance, and either
- * use that instance in sequential fashion, or to create derived "child"
- * instances, which after use, are asked to return possible symbol additions
- * to master instance. In either case benefit is that symbol table gets
- * initialized so that further uses are more efficient, as eventually all
- * symbols needed will already be in symbol table. At that point no more
- * Symbol String allocations are needed, nor changes to symbol table itself.
- *
- * Note that while individual SymbolTable instances are NOT thread-safe
- * (much like generic collection classes), concurrently used "child"
- * instances can be freely used without synchronization. However, using
- * master table concurrently with child instances can only be done if
- * access to master instance is read-only (ie. no modifications done).
- */
-
-public class SymbolTable {
-
- /**
- * Default initial table size; no need to make it miniscule, due
- * to couple of things: first, overhead of array reallocation
- * is significant,
- * and second, overhead of rehashing is also non-negligible.
- *
- * Let's use 128 as the default; it allows for up to 96 symbols,
- * and uses about 512 bytes on 32-bit machines.
- */
- protected static final int DEFAULT_TABLE_SIZE = 128;
-
- protected static final float DEFAULT_FILL_FACTOR = 0.75f;
-
- protected static final String EMPTY_STRING = "";
-
- /*
- ////////////////////////////////////////
- // Configuration:
- ////////////////////////////////////////
- */
-
- /**
- * Flag that determines whether Strings to be added need to be
- * interned before being added or not. Forcing intern()ing will add
- * some overhead when adding new Strings, but may be beneficial if such
- * Strings are generally used by other parts of system. Note that even
- * without interning, all returned String instances are guaranteed
- * to be comparable with equality (==) operator; it's just that such
- * guarantees are not made for Strings other classes return.
- */
- protected boolean mInternStrings;
-
- /*
- ////////////////////////////////////////
- // Actual symbol table data:
- ////////////////////////////////////////
- */
-
- /**
- * Primary matching symbols; it's expected most match occur from
- * here.
- */
- protected String[] mSymbols;
-
- /**
- * Overflow buckets; if primary doesn't match, lookup is done
- * from here.
- *
- * Note: Number of buckets is half of number of symbol entries, on
- * assumption there's less need for buckets.
- */
- protected Bucket[] mBuckets;
-
- /**
- * Current size (number of entries); needed to know if and when
- * rehash.
- */
- protected int mSize;
-
- /**
- * Limit that indicates maximum size this instance can hold before
- * it needs to be expanded and rehashed. Calculated using fill
- * factor passed in to constructor.
- */
- protected int mSizeThreshold;
-
- /**
- * Mask used to get index from hash values; equal to
- * mBuckets.length - 1
, when mBuckets.length is
- * a power of two.
- */
- protected int mIndexMask;
-
- /*
- ////////////////////////////////////////
- // Information about concurrency
- ////////////////////////////////////////
- */
-
- /**
- * Version of this table instance; used when deriving new concurrently
- * used versions from existing 'master' instance.
- */
- protected int mThisVersion;
-
- /**
- * Flag that indicates if any changes have been made to the data;
- * used to both determine if bucket array needs to be copied when
- * (first) change is made, and potentially if updated bucket list
- * is to be resync'ed back to master instance.
- */
- protected boolean mDirty;
-
- /*
- ////////////////////////////////////////
- // Life-cycle:
- ////////////////////////////////////////
- */
-
- /**
- * Method for constructing a master symbol table instance; this one
- * will create master instance with default size, and with interning
- * enabled.
- */
- public SymbolTable() {
- this(true);
- }
-
- /**
- * Method for constructing a master symbol table instance.
- */
- public SymbolTable(boolean internStrings) {
- this(internStrings, DEFAULT_TABLE_SIZE);
- }
-
- /**
- * Method for constructing a master symbol table instance.
- */
- public SymbolTable(boolean internStrings, int initialSize) {
- this(internStrings, initialSize, DEFAULT_FILL_FACTOR);
- }
-
- /**
- * Main method for constructing a master symbol table instance; will
- * be called by other public constructors.
- *
- * @param internStrings Whether Strings to add are intern()ed or not
- * @param initialSize Minimum initial size for bucket array; internally
- * will always use a power of two equal to or bigger than this value.
- * @param fillFactor Maximum fill factor allowed for bucket table;
- * when more entries are added, table will be expanded.
- */
- public SymbolTable(boolean internStrings, int initialSize,
- float fillFactor)
- {
- mInternStrings = internStrings;
- // Let's start versions from 1
- mThisVersion = 1;
- // And we'll also set flags so no copying of buckets is needed:
- mDirty = true;
-
- // No point in requesting funny initial sizes...
- if (initialSize < 1) {
- throw new IllegalArgumentException("Can not use negative/zero initial size: "+initialSize);
- }
- /* Initial size has to be a power of two. Also, let's not honour
- * sizes that are ridiculously small...
- */
- {
- int currSize = 4;
- while (currSize < initialSize) {
- currSize += currSize;
- }
- initialSize = currSize;
- }
-
- mSymbols = new String[initialSize];
- mBuckets = new Bucket[initialSize >> 1];
- // Mask is easy to calc for powers of two.
- mIndexMask = initialSize - 1;
- mSize = 0;
-
- // Sanity check for fill factor:
- if (fillFactor < 0.01f) {
- throw new IllegalArgumentException("Fill factor can not be lower than 0.01.");
- }
- if (fillFactor > 10.0f) { // just to catch stupid values, ie. useless from performance perspective
- throw new IllegalArgumentException("Fill factor can not be higher than 10.0.");
- }
- mSizeThreshold = (int) (initialSize * fillFactor + 0.5);
- }
-
- /**
- * Internal constructor used when creating child instances.
- */
- private SymbolTable(boolean internStrings, String[] symbols,
- Bucket[] buckets, int size, int sizeThreshold,
- int indexMask, int version)
- {
- mInternStrings = internStrings;
- mSymbols = symbols;
- mBuckets = buckets;
- mSize = size;
- mSizeThreshold = sizeThreshold;
- mIndexMask = indexMask;
- mThisVersion = version;
-
- // Need to make copies of arrays, if/when adding new entries
- mDirty = false;
- }
-
- /**
- * "Factory" method; will create a new child instance of this symbol
- * table. It will be a copy-on-write instance, ie. it will only use
- * read-only copy of parent's data, but when changes are needed, a
- * copy will be created.
- *
- * Note: while this method is synchronized, it is generally not
- * safe to both use makeChild/mergeChild, AND to use instance
- * actively. Instead, a separate 'root' instance should be used
- * on which only makeChild/mergeChild are called, but instance itself
- * is not used as a symbol table.
- */
- public synchronized SymbolTable makeChild() {
- return new SymbolTable(mInternStrings, mSymbols, mBuckets,
- mSize, mSizeThreshold, mIndexMask,
- mThisVersion+1);
- }
-
- /**
- * Method that allows contents of child table to potentially be
- * "merged in" with contents of this symbol table.
- *
- * Note that caller has to make sure symbol table passed in is
- * really a child or sibling of this symbol table.
- */
- public synchronized void mergeChild(SymbolTable child)
- {
- // Let's do a basic sanity check first:
- if (child.size() <= size()) { // nothing to add
- return;
- }
-
- // Okie dokie, let's get the data in!
- mSymbols = child.mSymbols;
- mBuckets = child.mBuckets;
- mSize = child.mSize;
- mSizeThreshold = child.mSizeThreshold;
- mIndexMask = child.mIndexMask;
- mThisVersion++; // to prevent other children from overriding
-
- // Dirty flag... well, let's just clear it, to force copying just
- // in case. Shouldn't really matter, for master tables.
- mDirty = false;
-
- /* However, we have to mark child as dirty, so that it will not
- * be modifying arrays we "took over" (since child may have
- * returned an updated table before it stopped fully using
- * the SymbolTable: for example, it may still use it for
- * parsing PI targets in epilog)
- */
- child.mDirty = false;
- }
-
- /*
- ////////////////////////////////////////////////////
- // Public API, configuration
- ////////////////////////////////////////////////////
- */
-
- public void setInternStrings(boolean state) {
- mInternStrings = state;
- }
-
- /*
- ////////////////////////////////////////////////////
- // Public API, generic accessors:
- ////////////////////////////////////////////////////
- */
-
- public int size() { return mSize; }
-
- public int version() { return mThisVersion; }
-
- public boolean isDirty() { return mDirty; }
-
- public boolean isDirectChildOf(SymbolTable t)
- {
- /* Actually, this doesn't really prove it is a child (would have to
- * use sequence number, or identityHash to really prove it), but
- * it's good enough if relationship is known to exist.
- */
- /* (for real check, one would need to child/descendant stuff; or
- * at least an identity hash... or maybe even just a _static_ global
- * counter for instances... maybe that would actually be worth
- * doing?)
- */
- if (mThisVersion == (t.mThisVersion + 1)) {
- return true;
- }
- return false;
- }
-
- /*
- ////////////////////////////////////////////////////
- // Public API, accessing symbols:
- ////////////////////////////////////////////////////
- */
-
- /**
- * Main access method; will check if actual symbol String exists;
- * if so, returns it; if not, will create, add and return it.
- *
- * @return The symbol matching String in input array
- */
- /*
- public String findSymbol(char[] buffer, int start, int len)
- {
- return findSymbol(buffer, start, len, calcHash(buffer, start, len));
- }
- */
-
- public String findSymbol(char[] buffer, int start, int len, int hash)
- {
- // Sanity check:
- if (len < 1) {
- return EMPTY_STRING;
- }
-
- hash &= mIndexMask;
-
- String sym = mSymbols[hash];
-
- // Optimal case; checking existing primary symbol for hash index:
- if (sym != null) {
- // Let's inline primary String equality checking:
- if (sym.length() == len) {
- int i = 0;
- do {
- if (sym.charAt(i) != buffer[start+i]) {
- break;
- }
- } while (++i < len);
- // Optimal case; primary match found
- if (i == len) {
- return sym;
- }
- }
- // How about collision bucket?
- Bucket b = mBuckets[hash >> 1];
- if (b != null) {
- sym = b.find(buffer, start, len);
- if (sym != null) {
- return sym;
- }
- }
- }
-
- // Need to expand?
- if (mSize >= mSizeThreshold) {
- rehash();
- /* Need to recalc hash; rare occurence (index mask has been
- * recalculated as part of rehash)
- */
- hash = calcHash(buffer, start, len) & mIndexMask;
- } else if (!mDirty) {
- // Or perhaps we need to do copy-on-write?
- copyArrays();
- mDirty = true;
- }
- ++mSize;
-
- String newSymbol = new String(buffer, start, len);
- if (mInternStrings) {
- newSymbol = newSymbol.intern();
- }
- // Ok; do we need to add primary entry, or a bucket?
- if (mSymbols[hash] == null) {
- mSymbols[hash] = newSymbol;
- } else {
- int bix = hash >> 1;
- mBuckets[bix] = new Bucket(newSymbol, mBuckets[bix]);
- }
-
- return newSymbol;
- }
-
- /**
- * Similar to {link #findSymbol}, but will not add passed in symbol
- * if it is not in symbol table yet.
- */
- public String findSymbolIfExists(char[] buffer, int start, int len, int hash)
- {
- // Sanity check:
- if (len < 1) {
- return EMPTY_STRING;
- }
- hash &= mIndexMask;
-
- String sym = mSymbols[hash];
- // Optimal case; checking existing primary symbol for hash index:
- if (sym != null) {
- // Let's inline primary String equality checking:
- if (sym.length() == len) {
- int i = 0;
- do {
- if (sym.charAt(i) != buffer[start+i]) {
- break;
- }
- } while (++i < len);
- // Optimal case; primary match found
- if (i == len) {
- return sym;
- }
- }
- // How about collision bucket?
- Bucket b = mBuckets[hash >> 1];
- if (b != null) {
- sym = b.find(buffer, start, len);
- if (sym != null) {
- return sym;
- }
- }
- }
- return null;
- }
-
- /**
- * Similar to to {@link #findSymbol(char[],int,int,int)}; used to either
- * do potentially cheap intern() (if table already has intern()ed version),
- * or to pre-populate symbol table with known values.
- */
- public String findSymbol(String str)
- {
- int len = str.length();
- // Sanity check:
- if (len < 1) {
- return EMPTY_STRING;
- }
-
- int index = calcHash(str) & mIndexMask;
- String sym = mSymbols[index];
-
- // Optimal case; checking existing primary symbol for hash index:
- if (sym != null) {
- // Let's inline primary String equality checking:
- if (sym.length() == len) {
- int i = 0;
- for (; i < len; ++i) {
- if (sym.charAt(i) != str.charAt(i)) {
- break;
- }
- }
- // Optimal case; primary match found
- if (i == len) {
- return sym;
- }
- }
- // How about collision bucket?
- Bucket b = mBuckets[index >> 1];
- if (b != null) {
- sym = b.find(str);
- if (sym != null) {
- return sym;
- }
- }
- }
-
- // Need to expand?
- if (mSize >= mSizeThreshold) {
- rehash();
- /* Need to recalc hash; rare occurence (index mask has been
- * recalculated as part of rehash)
- */
- index = calcHash(str) & mIndexMask;
- } else if (!mDirty) {
- // Or perhaps we need to do copy-on-write?
- copyArrays();
- mDirty = true;
- }
- ++mSize;
-
- if (mInternStrings) {
- str = str.intern();
- }
- // Ok; do we need to add primary entry, or a bucket?
- if (mSymbols[index] == null) {
- mSymbols[index] = str;
- } else {
- int bix = index >> 1;
- mBuckets[bix] = new Bucket(str, mBuckets[bix]);
- }
-
- return str;
- }
-
- /**
- * Implementation of a hashing method for variable length
- * Strings. Most of the time intention is that this calculation
- * is done by caller during parsing, not here; however, sometimes
- * it needs to be done for parsed "String" too.
- *
- * @param len Length of String; has to be at least 1 (caller guarantees
- * this pre-condition)
- */
- public static int calcHash(char[] buffer, int start, int len) {
- int hash = (int) buffer[0];
- for (int i = 1; i < len; ++i) {
- hash = (hash * 31) + (int) buffer[i];
- }
- return hash;
- }
-
- public static int calcHash(String key) {
- int hash = (int) key.charAt(0);
- for (int i = 1, len = key.length(); i < len; ++i) {
- hash = (hash * 31) + (int) key.charAt(i);
-
- }
- return hash;
- }
-
- /*
- //////////////////////////////////////////////////////////
- // Internal methods
- //////////////////////////////////////////////////////////
- */
-
- /**
- * Method called when copy-on-write is needed; generally when first
- * change is made to a derived symbol table.
- */
- private void copyArrays() {
- String[] oldSyms = mSymbols;
- int size = oldSyms.length;
- mSymbols = new String[size];
- System.arraycopy(oldSyms, 0, mSymbols, 0, size);
- Bucket[] oldBuckets = mBuckets;
- size = oldBuckets.length;
- mBuckets = new Bucket[size];
- System.arraycopy(oldBuckets, 0, mBuckets, 0, size);
- }
-
- /**
- * Method called when size (number of entries) of symbol table grows
- * so big that load factor is exceeded. Since size has to remain
- * power of two, arrays will then always be doubled. Main work
- * is really redistributing old entries into new String/Bucket
- * entries.
- */
- private void rehash()
- {
- int size = mSymbols.length;
- int newSize = size + size;
- String[] oldSyms = mSymbols;
- Bucket[] oldBuckets = mBuckets;
- mSymbols = new String[newSize];
- mBuckets = new Bucket[newSize >> 1];
- // Let's update index mask, threshold, now (needed for rehashing)
- mIndexMask = newSize - 1;
- mSizeThreshold += mSizeThreshold;
-
- int count = 0; // let's do sanity check
-
- /* Need to do two loops, unfortunately, since spillover area is
- * only half the size:
- */
- for (int i = 0; i < size; ++i) {
- String symbol = oldSyms[i];
- if (symbol != null) {
- ++count;
- int index = calcHash(symbol) & mIndexMask;
- if (mSymbols[index] == null) {
- mSymbols[index] = symbol;
- } else {
- int bix = index >> 1;
- mBuckets[bix] = new Bucket(symbol, mBuckets[bix]);
- }
- }
- }
-
- size >>= 1;
- for (int i = 0; i < size; ++i) {
- Bucket b = oldBuckets[i];
- while (b != null) {
- ++count;
- String symbol = b.getSymbol();
- int index = calcHash(symbol) & mIndexMask;
- if (mSymbols[index] == null) {
- mSymbols[index] = symbol;
- } else {
- int bix = index >> 1;
- mBuckets[bix] = new Bucket(symbol, mBuckets[bix]);
- }
- b = b.getNext();
- }
- }
-
- if (count != mSize) {
- throw new IllegalStateException("Internal error on SymbolTable.rehash(): had "+mSize+" entries; now have "+count+".");
- }
- }
-
- /*
- //////////////////////////////////////////////////////////
- // Test/debug support:
- //////////////////////////////////////////////////////////
- */
-
- public double calcAvgSeek() {
- int count = 0;
-
- for (int i = 0, len = mSymbols.length; i < len; ++i) {
- if (mSymbols[i] != null) {
- ++count;
- }
- }
-
- for (int i = 0, len = mBuckets.length; i < len; ++i) {
- Bucket b = mBuckets[i];
- int cost = 2;
- while (b != null) {
- count += cost;
- ++cost;
- b = b.getNext();
- }
- }
-
- return ((double) count) / ((double) mSize);
- }
-
- /*
- //////////////////////////////////////////////////////////
- // Bucket class
- //////////////////////////////////////////////////////////
- */
-
- /**
- * This class is a symbol table entry. Each entry acts as a node
- * in a linked list.
- */
- static final class Bucket {
- private final String mSymbol;
- private final Bucket mNext;
-
- public Bucket(String symbol, Bucket next) {
- mSymbol = symbol;
- mNext = next;
- }
-
- public String getSymbol() { return mSymbol; }
- public Bucket getNext() { return mNext; }
-
- public String find(char[] buf, int start, int len) {
- String sym = mSymbol;
- Bucket b = mNext;
-
- while (true) { // Inlined equality comparison:
- if (sym.length() == len) {
- int i = 0;
- do {
- if (sym.charAt(i) != buf[start+i]) {
- break;
- }
- } while (++i < len);
- if (i == len) {
- return sym;
- }
- }
- if (b == null) {
- break;
- }
- sym = b.getSymbol();
- b = b.getNext();
- }
- return null;
- }
-
- public String find(String str) {
- String sym = mSymbol;
- Bucket b = mNext;
-
- while (true) {
- if (sym.equals(str)) {
- return sym;
- }
- if (b == null) {
- break;
- }
- sym = b.getSymbol();
- b = b.getNext();
- }
- return null;
- }
- }
-}
diff -Nru libwoodstox-java-4.1.3/src/java/com/ctc/wstx/util/TextAccumulator.java libwoodstox-java-5.1.0/src/java/com/ctc/wstx/util/TextAccumulator.java
--- libwoodstox-java-4.1.3/src/java/com/ctc/wstx/util/TextAccumulator.java 2012-04-24 04:38:21.000000000 +0000
+++ libwoodstox-java-5.1.0/src/java/com/ctc/wstx/util/TextAccumulator.java 1970-01-01 00:00:00.000000000 +0000
@@ -1,75 +0,0 @@
-package com.ctc.wstx.util;
-
-/**
- * Simple utility class used to efficiently accumulate and concatenate
- * text passed in various forms
- */
-public final class TextAccumulator
-{
- 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 TextAccumulator() { }
-
- public boolean hasText() {
- return (mBuilder != null) || (mText != null);
- }
-
- public void addText(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 void addText(char[] buf, int start, int end)
- {
- int len = end-start;
- if (len > 0) {
- // Any prior text?
- if (mText != null) {
- mBuilder = new StringBuffer(mText.length() + len);
- mBuilder.append(mText);
- mText = null;
- } else if (mBuilder == null) {
- /* more efficient to use a builder than a string; and although
- * could use a char array, StringBuilder has the benefit of
- * being able to share the array, eventually.
- */
- mBuilder = new StringBuffer(len);
- }
- mBuilder.append(buf, start, end-start);
- }
- }
-
- public String getAndClear()
- {
- String result;
-
- if (mText != null) {
- result = mText;
- mText = null;
- } else if (mBuilder != null) {
- result = mBuilder.toString();
- mBuilder = null;
- } else {
- result = "";
- }
- return result;
- }
-}
diff -Nru libwoodstox-java-4.1.3/src/java/com/ctc/wstx/util/TextBuffer.java libwoodstox-java-5.1.0/src/java/com/ctc/wstx/util/TextBuffer.java
--- libwoodstox-java-4.1.3/src/java/com/ctc/wstx/util/TextBuffer.java 2012-04-24 04:38:21.000000000 +0000
+++ libwoodstox-java-5.1.0/src/java/com/ctc/wstx/util/TextBuffer.java 1970-01-01 00:00:00.000000000 +0000
@@ -1,1406 +0,0 @@
-package com.ctc.wstx.util;
-
-import java.io.*;
-import java.util.ArrayList;
-import javax.xml.stream.Location;
-import javax.xml.stream.XMLStreamException;
-
-import org.xml.sax.ContentHandler;
-import org.xml.sax.SAXException;
-import org.xml.sax.ext.LexicalHandler;
-
-import org.codehaus.stax2.typed.Base64Variant;
-import org.codehaus.stax2.typed.TypedArrayDecoder;
-import org.codehaus.stax2.typed.TypedValueDecoder;
-import org.codehaus.stax2.typed.TypedXMLStreamException;
-import org.codehaus.stax2.validation.XMLValidator;
-
-import org.codehaus.stax2.ri.typed.CharArrayBase64Decoder;
-
-import com.ctc.wstx.api.ReaderConfig;
-import com.ctc.wstx.dtd.DTDEventListener;
-import com.ctc.wstx.sr.InputProblemReporter;
-import com.ctc.wstx.util.StringUtil;
-
-/**
- * TextBuffer is a class similar to {@link StringBuffer}, with
- * following differences:
- *
- * - TextBuffer uses segments character arrays, to avoid having
- * to do additional array copies when array is not big enough. This
- * means that only reallocating that is necessary is done only once --
- * if and when caller
- * wants to access contents in a linear array (char[], String).
- *
- * - TextBuffer is not synchronized.
- *
- *
- *
- * Over time more and more cruft has accumulated here, mostly to
- * support efficient access to collected text. Since access is
- * easiest to do efficiently using callbacks, this class now needs
- * to known interfaces of SAX classes and validators.
- *
- * Notes about usage: for debugging purposes, it's suggested to use
- * {@link #toString} method, as opposed to
- * {@link #contentsAsArray} or {@link #contentsAsString}. Internally
- * resulting code paths may or may not be different, WRT caching.
- *
- * @author Tatu Saloranta
- */
-public final class TextBuffer
-{
- /* 23-Mar-2006, TSa: Memory buffer clearing is a significant overhead
- * for small documents, no need to use huge buffer -- it will expand
- * as necessary for larger docs, but commonly text segments just
- * aren't that long.
- */
- /**
- * Size of the first text segment buffer to allocate; need not contain
- * the biggest segment, since new ones will get allocated as needed.
- * However, it's sensible to use something that often is big enough
- * to contain segments.
- */
- final static int DEF_INITIAL_BUFFER_SIZE = 500; // 1k
-
- /**
- * We will also restrict maximum length of individual segments
- * to allocate (not including cases where we must return a single
- * segment). Value is somewhat arbitrary, let's use it so that
- * memory used is no more than 1/2 megabytes.
- */
- final static int MAX_SEGMENT_LENGTH = 256 * 1024;
-
- final static int INT_SPACE = 0x0020;
-
- // // // Configuration:
-
- private final ReaderConfig mConfig;
-
- // // // Shared read-only input buffer:
-
- /**
- * Shared input buffer; stored here in case some input can be returned
- * as is, without being copied to collector's own buffers. Note that
- * this is read-only for this Objet.
- */
- private char[] mInputBuffer;
-
- /**
- * Character offset of first char in input buffer; -1 to indicate
- * that input buffer currently does not contain any useful char data
- */
- private int mInputStart;
-
- /**
- * When using shared buffer, offset after the last character in
- * shared buffer
- */
- private int mInputLen;
-
- // // // Internal non-shared collector buffers:
-
- private boolean mHasSegments = false;
-
- /**
- * List of segments prior to currently active segment.
- */
- private ArrayList mSegments;
-
-
- // // // Currently used segment; not (yet) contained in mSegments
-
- /**
- * Amount of characters in segments in {@link mSegments}
- */
- private int mSegmentSize;
-
- private char[] mCurrentSegment;
-
- /**
- * Number of characters in currently active (last) segment
- */
- private int mCurrentSize;
-
- // // // Temporary caching for Objects to return
-
- /**
- * String that will be constructed when the whole contents are
- * needed; will be temporarily stored in case asked for again.
- */
- private String mResultString;
-
- private char[] mResultArray;
-
- // // // Canonical indentation objects (up to 32 spaces, 8 tabs)
-
- public final static int MAX_INDENT_SPACES = 32;
- public final static int MAX_INDENT_TABS = 8;
-
- // Let's add one more space at the end, for safety...
- private final static String sIndSpaces =
- // 123456789012345678901234567890123
- "\n ";
- private final static char[] sIndSpacesArray = sIndSpaces.toCharArray();
- private final static String[] sIndSpacesStrings = new String[sIndSpacesArray.length];
-
- private final static String sIndTabs =
- // 1 2 3 4 5 6 7 8 9
- "\n\t\t\t\t\t\t\t\t\t";
- private final static char[] sIndTabsArray = sIndTabs.toCharArray();
- private final static String[] sIndTabsStrings = new String[sIndTabsArray.length];
-
- /*
- //////////////////////////////////////////////
- // Life-cycle
- //////////////////////////////////////////////
- */
-
- private TextBuffer(ReaderConfig cfg)
- {
- mConfig = cfg;
- }
-
- public static TextBuffer createRecyclableBuffer(ReaderConfig cfg)
- {
- return new TextBuffer(cfg);
- }
-
- public static TextBuffer createTemporaryBuffer()
- {
- return new TextBuffer(null);
- }
-
- /**
- * Method called to indicate that the underlying buffers should now
- * be recycled if they haven't yet been recycled. Although caller
- * can still use this text buffer, it is not advisable to call this
- * method if that is likely, since next time a buffer is needed,
- * buffers need to reallocated.
- * Note: calling this method automatically also clears contents
- * of the buffer.
- */
- public void recycle(boolean force)
- {
- if (mConfig != null && mCurrentSegment != null) {
- if (force) {
- /* If we are allowed to wipe out all existing data, it's
- * quite easy; we'll just wipe out contents, and return
- * biggest buffer:
- */
- resetWithEmpty();
- } else {
- /* But if there's non-shared data (ie. buffer is still
- * in use), can't return it yet:
- */
- if (mInputStart < 0 && (mSegmentSize + mCurrentSize) > 0) {
- return;
- }
- // If no data (or only shared data), can continue
- if (mSegments != null && mSegments.size() > 0) {
- // No need to use anything from list, curr segment not null
- mSegments.clear();
- mSegmentSize = 0;
- }
- }
-
- char[] buf = mCurrentSegment;
- mCurrentSegment = null;
- mConfig.freeMediumCBuffer(buf);
- }
- }
-
- /**
- * Method called to clear out any content text buffer may have, and
- * initializes buffer to use non-shared data.
- */
- public void resetWithEmpty()
- {
- mInputBuffer = null;
- mInputStart = -1; // indicates shared buffer not used
- mInputLen = 0;
-
- mResultString = null;
- mResultArray = null;
-
- // And then reset internal input buffers, if necessary:
- if (mHasSegments) {
- clearSegments();
- }
- mCurrentSize = 0;
- }
-
- /**
- * Similar to {@link #resetWithEmpty}, but actively marks current
- * text content to be empty string (whereas former method leaves
- * content as undefined).
- */
- public void resetWithEmptyString()
- {
- mInputBuffer = null;
- mInputStart = -1; // indicates shared buffer not used
- mInputLen = 0;
- mResultString = "";
- mResultArray = null;
- if (mHasSegments) {
- clearSegments();
- }
- mCurrentSize = 0;
- }
-
- /**
- * Method called to initialize the buffer with a shared copy of data;
- * this means that buffer will just have pointers to actual data. It
- * also means that if anything is to be appended to the buffer, it
- * will first have to unshare it (make a local copy).
- */
- public void resetWithShared(char[] buf, int start, int len)
- {
- // Let's first mark things we need about input buffer
- mInputBuffer = buf;
- mInputStart = start;
- mInputLen = len;
-
- // Then clear intermediate values, if any:
- mResultString = null;
- mResultArray = null;
-
- // And then reset internal input buffers, if necessary:
- if (mHasSegments) {
- clearSegments();
- }
- }
-
- public void resetWithCopy(char[] buf, int start, int len)
- {
- mInputBuffer = null;
- mInputStart = -1; // indicates shared buffer not used
- mInputLen = 0;
-
- mResultString = null;
- mResultArray = null;
-
- // And then reset internal input buffers, if necessary:
- if (mHasSegments) {
- clearSegments();
- } else {
- if (mCurrentSegment == null) {
- mCurrentSegment = allocBuffer(len);
- }
- mCurrentSize = mSegmentSize = 0;
- }
- append(buf, start, len);
- }
-
- /**
- * Method called to make sure there is a non-shared segment to use, without
- * appending any content yet.
- */
- public void resetInitialized()
- {
- resetWithEmpty();
- if (mCurrentSegment == null) {
- mCurrentSegment = allocBuffer(0);
- }
- }
-
- private final char[] allocBuffer(int needed)
- {
- int size = Math.max(needed, DEF_INITIAL_BUFFER_SIZE);
- char[] buf = null;
- if (mConfig != null) {
- buf = mConfig.allocMediumCBuffer(size);
- if (buf != null) {
- return buf;
- }
- }
- return new char[size];
- }
-
- private final void clearSegments()
- {
- mHasSegments = false;
- /* Since the current segment should be the biggest one
- * (as we allocate 50% bigger each time), let's retain it,
- * and clear others
- */
- mSegments.clear();
- mCurrentSize = mSegmentSize = 0;
- }
-
- public void resetWithIndentation(int indCharCount, char indChar)
- {
- mInputStart = 0;
- mInputLen = indCharCount+1;
- String text;
- if (indChar == '\t') { // tabs?
- mInputBuffer = sIndTabsArray;
- text = sIndTabsStrings[indCharCount];
- if (text == null) {
- sIndTabsStrings[indCharCount] = text = sIndTabs.substring(0, mInputLen);
- }
- } else { // nope, spaces (should assert indChar?)
- mInputBuffer = sIndSpacesArray;
- text = sIndSpacesStrings[indCharCount];
- if (text == null) {
- sIndSpacesStrings[indCharCount] = text = sIndSpaces.substring(0, mInputLen);
- }
- }
- mResultString = text;
-
- /* Should not need the explicit non-shared array; no point in
- * pre-populating it (can be changed if this is not true)
- */
- mResultArray = null;
-
- // And then reset internal input buffers, if necessary:
- if (mSegments != null && mSegments.size() > 0) {
- mSegments.clear();
- mCurrentSize = mSegmentSize = 0;
- }
- }
-
- /*
- //////////////////////////////////////////////
- // Accessors for implementing StAX interface:
- //////////////////////////////////////////////
- */
-
- /**
- * @return Number of characters currently stored by this collector
- */
- public int size() {
- if (mInputStart >= 0) { // shared copy from input buf
- return mInputLen;
- }
- // local segmented buffers
- return mSegmentSize + mCurrentSize;
- }
-
- public int getTextStart()
- {
- /* Only shared input buffer can have non-zero offset; buffer
- * segments start at 0, and if we have to create a combo buffer,
- * that too will start from beginning of the buffer
- */
- return (mInputStart >= 0) ? mInputStart : 0;
- }
-
- public char[] getTextBuffer()
- {
- // Are we just using shared input buffer?
- if (mInputStart >= 0) {
- return mInputBuffer;
- }
- // Nope; but does it fit in just one segment?
- if (mSegments == null || mSegments.size() == 0) {
- return mCurrentSegment;
- }
- // Nope, need to have/create a non-segmented array and return it
- return contentsAsArray();
- }
-
- /*
- /////////////////////////////////////////////////
- // Accessors for implementing StAX2 Typed access
- /////////////////////////////////////////////////
- */
-
- /**
- * Generic pass-through method which call given decoder
- * with accumulated data
- */
- public void decode(TypedValueDecoder tvd)
- throws IllegalArgumentException
- {
- char[] buf;
- int start, end;
-
- if (mInputStart >= 0) { // shared buffer, common case
- buf = mInputBuffer;
- start = mInputStart;
- end = start + mInputLen;
- } else {
- buf = getTextBuffer();
- start = 0;
- end = mSegmentSize + mCurrentSize;
- }
-
- // Need to trim first
- while (true) {
- if (start >= end) {
- tvd.handleEmptyValue();
- return;
- }
- if (!StringUtil.isSpace(buf[start])) {
- break;
- }
- ++start;
- }
- // Trailing space?
- while (--end > start && StringUtil.isSpace(buf[end])) { }
- tvd.decode(buf, start, end+1);
- }
-
- /**
- * Pass-through decode method called to find find the next token,
- * decode it, and repeat the process as long as there are more
- * tokens and the array decoder accepts more entries.
- * All tokens processed will be "consumed", such that they will
- * not be visible via buffer.
- *
- * @return Number of tokens decoded; 0 means that no (more) tokens
- * were found from this buffer.
- */
- public int decodeElements(TypedArrayDecoder tad, InputProblemReporter rep)
- throws TypedXMLStreamException
- {
- int count = 0;
-
- /* First: for simplicity, we require a single flat buffer to
- * decode from. Second: to be able to update start location
- * (to keep track of what's available), we need to fake that
- * we are using a shared buffer (since that has offset)
- */
- if (mInputStart < 0) {
- if (mHasSegments) {
- mInputBuffer = buildResultArray();
- mInputLen = mInputBuffer.length;
- // let's also clear segments since they are not needed any more
- clearSegments();
- } else {
- // just current buffer, easier to fake
- mInputBuffer = mCurrentSegment;
- mInputLen = mCurrentSize;
- }
- mInputStart = 0;
- }
-
- // And then let's decode
- int ptr = mInputStart;
- final int end = ptr + mInputLen;
- final char[] buf = mInputBuffer;
- int start = ptr;
-
- try {
- decode_loop:
- while (ptr < end) {
- // First, any space to skip?
- while (buf[ptr] <= INT_SPACE) {
- if (++ptr >= end) {
- break decode_loop;
- }
- }
- // Then let's figure out non-space char (token)
- start = ptr;
- ++ptr;
- while (ptr < end && buf[ptr] > INT_SPACE) {
- ++ptr;
- }
- ++count;
- int tokenEnd = ptr;
- ++ptr; // to skip trailing space (or, beyond end)
- // And there we have it
- if (tad.decodeValue(buf, start, tokenEnd)) {
- break;
- }
- }
- } catch (IllegalArgumentException iae) {
- // Need to convert to a checked stream exception
-
- /* Hmmh. This is probably not an accurate location... but
- * we can't do much better as content we have has been
- * normalized already.
- */
- Location loc = rep.getLocation();
- // -1 to move it back after being advanced earlier (to skip trailing space)
- String lexical = new String(buf, start, (ptr-start-1));
- throw new TypedXMLStreamException(lexical, iae.getMessage(), loc, iae);
- } finally {
- mInputStart = ptr;
- mInputLen = end-ptr;
- }
- return count;
- }
-
- /**
- * Method that needs to be called to configure given base64 decoder
- * with textual contents collected by this buffer.
- *
- * @param dec Decoder that will need data
- * @param firstChunk Whether this is the first segment fed or not;
- * if it is, state needs to be fullt reset; if not, only partially.
- */
- public void initBinaryChunks(Base64Variant v, CharArrayBase64Decoder dec, boolean firstChunk)
- {
- if (mInputStart < 0) { // non-shared
- dec.init(v, firstChunk, mCurrentSegment, 0, mCurrentSize, mSegments);
- } else { // shared
- dec.init(v, firstChunk, mInputBuffer, mInputStart, mInputLen, null);
- }
- }
-
- /*
- //////////////////////////////////////////////
- // Accessors:
- //////////////////////////////////////////////
- */
-
- public String contentsAsString()
- {
- if (mResultString == null) {
- // Has array been requested? Can make a shortcut, if so:
- if (mResultArray != null) {
- mResultString = new String(mResultArray);
- } else {
- // Do we use shared array?
- if (mInputStart >= 0) {
- if (mInputLen < 1) {
- return (mResultString = "");
- }
- mResultString = new String(mInputBuffer, mInputStart, mInputLen);
- } else { // nope... need to copy
- // But first, let's see if we have just one buffer
- int segLen = mSegmentSize;
- int currLen = mCurrentSize;
-
- if (segLen == 0) { // yup
- mResultString = (currLen == 0) ? "" : new String(mCurrentSegment, 0, currLen);
- } else { // no, need to combine
- StringBuffer sb = new StringBuffer(segLen + currLen);
- // First stored segments
- if (mSegments != null) {
- for (int i = 0, len = mSegments.size(); i < len; ++i) {
- char[] curr = (char[]) mSegments.get(i);
- sb.append(curr, 0, curr.length);
- }
- }
- // And finally, current segment:
- sb.append(mCurrentSegment, 0, mCurrentSize);
- mResultString = sb.toString();
- }
- }
- }
- }
- return mResultString;
- }
-
- /**
- * Similar to {@link #contentsAsString}, but constructs a StringBuffer
- * for further appends.
- *
- * @param extraSpace Number of extra characters to preserve in StringBuffer
- * beyond space immediately needed to hold the contents
- */
- public StringBuffer contentsAsStringBuffer(int extraSpace)
- {
- if (mResultString != null) {
- return new StringBuffer(mResultString);
- }
- if (mResultArray != null) {
- StringBuffer sb = new StringBuffer(mResultArray.length + extraSpace);
- sb.append(mResultArray, 0, mResultArray.length);
- return sb;
- }
- if (mInputStart >= 0) { // shared array
- if (mInputLen < 1) {
- return new StringBuffer();
- }
- StringBuffer sb = new StringBuffer(mInputLen + extraSpace);
- sb.append(mInputBuffer, mInputStart, mInputLen);
- return sb;
- }
- int segLen = mSegmentSize;
- int currLen = mCurrentSize;
-
- StringBuffer sb = new StringBuffer(segLen + currLen + extraSpace);
- // First stored segments
- if (mSegments != null) {
- for (int i = 0, len = mSegments.size(); i < len; ++i) {
- char[] curr = (char[]) mSegments.get(i);
- sb.append(curr, 0, curr.length);
- }
- }
- // And finally, current segment:
- sb.append(mCurrentSegment, 0, currLen);
- return sb;
- }
-
- public void contentsToStringBuffer(StringBuffer sb)
- {
- if (mResultString != null) {
- sb.append(mResultString);
- } else if (mResultArray != null) {
- sb.append(mResultArray);
- } else if (mInputStart >= 0) { // shared array
- if (mInputLen > 0) {
- sb.append(mInputBuffer, mInputStart, mInputLen);
- }
- } else {
- // First stored segments
- if (mSegments != null) {
- for (int i = 0, len = mSegments.size(); i < len; ++i) {
- char[] curr = (char[]) mSegments.get(i);
- sb.append(curr, 0, curr.length);
- }
- }
- // And finally, current segment:
- sb.append(mCurrentSegment, 0, mCurrentSize);
- }
- }
-
- public char[] contentsAsArray()
- {
- char[] result = mResultArray;
- if (result == null) {
- mResultArray = result = buildResultArray();
- }
- return result;
- }
-
- public int contentsToArray(int srcStart, char[] dst, int dstStart, int len) {
- // Easy to copy from shared buffer:
- if (mInputStart >= 0) {
- int amount = mInputLen - srcStart;
- if (amount > len) {
- amount = len;
- } else if (amount < 0) {
- amount = 0;
- }
- if (amount > 0) {
- System.arraycopy(mInputBuffer, mInputStart+srcStart,
- dst, dstStart, amount);
- }
- return amount;
- }
-
- /* Could also check if we have array, but that'd only help with
- * braindead clients that get full array first, then segments...
- * which hopefully aren't that common
- */
- // Copying from segmented array is bit more involved:
- int totalAmount = 0;
- if (mSegments != null) {
- for (int i = 0, segc = mSegments.size(); i < segc; ++i) {
- char[] segment = (char[]) mSegments.get(i);
- int segLen = segment.length;
- int amount = segLen - srcStart;
- if (amount < 1) { // nothing from this segment?
- srcStart -= segLen;
- continue;
- }
- if (amount >= len) { // can get rest from this segment?
- System.arraycopy(segment, srcStart, dst, dstStart, len);
- return (totalAmount + len);
- }
- // Can get some from this segment, offset becomes zero:
- System.arraycopy(segment, srcStart, dst, dstStart, amount);
- totalAmount += amount;
- dstStart += amount;
- len -= amount;
- srcStart = 0;
- }
- }
-
- // Need to copy anything from last segment?
- if (len > 0) {
- int maxAmount = mCurrentSize - srcStart;
- if (len > maxAmount) {
- len = maxAmount;
- }
- if (len > 0) { // should always be true
- System.arraycopy(mCurrentSegment, srcStart, dst, dstStart, len);
- totalAmount += len;
- }
- }
-
- return totalAmount;
- }
-
- /**
- * Method that will stream contents of this buffer into specified
- * Writer.
- */
- public int rawContentsTo(Writer w)
- throws IOException
- {
- // Let's first see if we have created helper objects:
- if (mResultArray != null) {
- w.write(mResultArray);
- return mResultArray.length;
- }
- if (mResultString != null) {
- w.write(mResultString);
- return mResultString.length();
- }
-
- // Do we use shared array?
- if (mInputStart >= 0) {
- if (mInputLen > 0) {
- w.write(mInputBuffer, mInputStart, mInputLen);
- }
- return mInputLen;
- }
- // Nope, need to do full segmented output
- int rlen = 0;
- if (mSegments != null) {
- for (int i = 0, len = mSegments.size(); i < len; ++i) {
- char[] ch = (char[]) mSegments.get(i);
- w.write(ch);
- rlen += ch.length;
- }
- }
- if (mCurrentSize > 0) {
- w.write(mCurrentSegment, 0, mCurrentSize);
- rlen += mCurrentSize;
- }
- return rlen;
- }
-
- public Reader rawContentsViaReader()
- throws IOException
- {
- // Let's first see if we have created helper objects:
- if (mResultArray != null) {
- return new CharArrayReader(mResultArray);
- }
- if (mResultString != null) {
- return new StringReader(mResultString);
- }
-
- // Do we use shared array?
- if (mInputStart >= 0) {
- if (mInputLen > 0) {
- return new CharArrayReader(mInputBuffer, mInputStart, mInputLen);
- }
- return new StringReader("");
- }
- // or maybe it's all in the current segment
- if (mSegments == null || mSegments.size() == 0) {
- return new CharArrayReader(mCurrentSegment, 0, mCurrentSize);
- }
- // Nope, need to do full segmented output
- return new BufferReader(mSegments, mCurrentSegment, mCurrentSize);
- }
-
- public boolean isAllWhitespace()
- {
- if (mInputStart >= 0) { // using single shared buffer?
- char[] buf = mInputBuffer;
- int i = mInputStart;
- int last = i + mInputLen;
- for (; i < last; ++i) {
- if (buf[i] > INT_SPACE) {
- return false;
- }
- }
- return true;
- }
-
- // Nope, need to do full segmented output
- if (mSegments != null) {
- for (int i = 0, len = mSegments.size(); i < len; ++i) {
- char[] buf = (char[]) mSegments.get(i);
- for (int j = 0, len2 = buf.length; j < len2; ++j) {
- if (buf[j] > INT_SPACE) {
- return false;
- }
- }
- }
- }
-
- char[] buf = mCurrentSegment;
- for (int i = 0, len = mCurrentSize; i < len; ++i) {
- if (buf[i] > INT_SPACE) {
- return false;
- }
- }
- return true;
- }
-
- /**
- * Method that can be used to check if the contents of the buffer end
- * in specified String.
- *
- * @return True if the textual content buffer contains ends with the
- * specified String; false otherwise
- */
- public boolean endsWith(String str)
- {
- /* Let's just play this safe; should seldom if ever happen...
- * and because of that, can be sub-optimal, performancewise, to
- * alternatives.
- */
- if (mInputStart >= 0) {
- unshare(16);
- }
-
- int segIndex = (mSegments == null) ? 0 : mSegments.size();
- int inIndex = str.length() - 1;
- char[] buf = mCurrentSegment;
- int bufIndex = mCurrentSize-1;
-
- while (inIndex >= 0) {
- if (str.charAt(inIndex) != buf[bufIndex]) {
- return false;
- }
- if (--inIndex == 0) {
- break;
- }
- if (--bufIndex < 0) {
- if (--segIndex < 0) { // no more data?
- return false;
- }
- buf = (char[]) mSegments.get(segIndex);
- bufIndex = buf.length-1;
- }
- }
-
- return true;
- }
-
- /**
- * Note: it is assumed that this method is not used often enough to
- * be a bottleneck, or for long segments. Based on this, it is optimized
- * for common simple cases where there is only one single character
- * segment to use; fallback for other cases is to create such segment.
- */
- public boolean equalsString(String str)
- {
- int expLen = str.length();
-
- // First the easy check; if we have a shared buf:
- if (mInputStart >= 0) {
- if (mInputLen != expLen) {
- return false;
- }
- for (int i = 0; i < expLen; ++i) {
- if (str.charAt(i) != mInputBuffer[mInputStart+i]) {
- return false;
- }
- }
- return true;
- }
-
- // Otherwise, segments:
- if (expLen != size()) {
- return false;
- }
- char[] seg;
- if (mSegments == null || mSegments.size() == 0) {
- // just one segment, still easy
- seg = mCurrentSegment;
- } else {
- /* Ok; this is the sub-optimal case. Could obviously juggle through
- * segments, but probably not worth the hassle, we seldom if ever
- * get here...
- */
- seg = contentsAsArray();
- }
-
- for (int i = 0; i < expLen; ++i) {
- if (seg[i] != str.charAt(i)) {
- return false;
- }
- }
- return true;
- }
-
- /*
- //////////////////////////////////////////////
- // Access using SAX handlers:
- //////////////////////////////////////////////
- */
-
- public void fireSaxCharacterEvents(ContentHandler h)
- throws SAXException
- {
- if (mResultArray != null) { // already have single array?
- h.characters(mResultArray, 0, mResultArray.length);
- } else if (mInputStart >= 0) { // sharing input buffer?
- h.characters(mInputBuffer, mInputStart, mInputLen);
- } else {
- if (mSegments != null) {
- for (int i = 0, len = mSegments.size(); i < len; ++i) {
- char[] ch = (char[]) mSegments.get(i);
- h.characters(ch, 0, ch.length);
- }
- }
- if (mCurrentSize > 0) {
- h.characters(mCurrentSegment, 0, mCurrentSize);
- }
- }
- }
-
- public void fireSaxSpaceEvents(ContentHandler h)
- throws SAXException
- {
- if (mResultArray != null) { // only happens for indentation
- h.ignorableWhitespace(mResultArray, 0, mResultArray.length);
- } else if (mInputStart >= 0) { // sharing input buffer?
- h.ignorableWhitespace(mInputBuffer, mInputStart, mInputLen);
- } else {
- if (mSegments != null) {
- for (int i = 0, len = mSegments.size(); i < len; ++i) {
- char[] ch = (char[]) mSegments.get(i);
- h.ignorableWhitespace(ch, 0, ch.length);
- }
- }
- if (mCurrentSize > 0) {
- h.ignorableWhitespace(mCurrentSegment, 0, mCurrentSize);
- }
- }
- }
-
- public void fireSaxCommentEvent(LexicalHandler h)
- throws SAXException
- {
- // Comment can not be split, so may need to combine the array
- if (mResultArray != null) { // only happens for indentation
- h.comment(mResultArray, 0, mResultArray.length);
- } else if (mInputStart >= 0) { // sharing input buffer?
- h.comment(mInputBuffer, mInputStart, mInputLen);
- } else if (mSegments != null && mSegments.size() > 0) {
- char[] ch = contentsAsArray();
- h.comment(ch, 0, ch.length);
- } else {
- h.comment(mCurrentSegment, 0, mCurrentSize);
- }
- }
-
- public void fireDtdCommentEvent(DTDEventListener l)
- {
- // Comment can not be split, so may need to combine the array
- if (mResultArray != null) { // only happens for indentation
- l.dtdComment(mResultArray, 0, mResultArray.length);
- } else if (mInputStart >= 0) { // sharing input buffer?
- l.dtdComment(mInputBuffer, mInputStart, mInputLen);
- } else if (mSegments != null && mSegments.size() > 0) {
- char[] ch = contentsAsArray();
- l.dtdComment(ch, 0, ch.length);
- } else {
- l.dtdComment(mCurrentSegment, 0, mCurrentSize);
- }
- }
-
- /*
- //////////////////////////////////////////////
- // Support for validation
- //////////////////////////////////////////////
- */
-
- public void validateText(XMLValidator vld, boolean lastSegment)
- throws XMLStreamException
- {
- // Shared buffer? Let's just pass that
- if (mInputStart >= 0) {
- vld.validateText(mInputBuffer, mInputStart, mInputStart + mInputLen, lastSegment);
- } else {
- /* Otherwise, can either create a combine buffer, or construct
- * a String. While former could be more efficient, let's do latter
- * for now since current validator implementations work better
- * with Strings.
- */
- vld.validateText(contentsAsString(), lastSegment);
- }
- }
-
- /*
- //////////////////////////////////////////////
- // Public mutators:
- //////////////////////////////////////////////
- */
-
- /**
- * Method called to make sure that buffer is not using shared input
- * buffer; if it is, it will copy such contents to private buffer.
- */
- public void ensureNotShared() {
- if (mInputStart >= 0) {
- unshare(16);
- }
- }
-
- public void append(char c) {
- // Using shared buffer so far?
- if (mInputStart >= 0) {
- unshare(16);
- }
- mResultString = null;
- mResultArray = null;
- // Room in current segment?
- char[] curr = mCurrentSegment;
- if (mCurrentSize >= curr.length) {
- expand(1);
- curr = mCurrentSegment;
- }
- curr[mCurrentSize++] = c;
- }
-
- public void append(char[] c, int start, int len)
- {
- // Can't append to shared buf (sanity check)
- if (mInputStart >= 0) {
- unshare(len);
- }
- mResultString = null;
- mResultArray = null;
-
- // Room in current segment?
- char[] curr = mCurrentSegment;
- int max = curr.length - mCurrentSize;
-
- if (max >= len) {
- System.arraycopy(c, start, curr, mCurrentSize, len);
- mCurrentSize += len;
- } else {
- // No room for all, need to copy part(s):
- if (max > 0) {
- System.arraycopy(c, start, curr, mCurrentSize, max);
- start += max;
- len -= max;
- }
- /* And then allocate new segment; we are guaranteed to now
- * have enough room in segment.
- */
- expand(len); // note: curr != mCurrentSegment after this
- System.arraycopy(c, start, mCurrentSegment, 0, len);
- mCurrentSize = len;
- }
- }
-
- public void append(String str)
- {
- // Can't append to shared buf (sanity check)
- int len = str.length();
- if (mInputStart >= 0) {
- unshare(len);
- }
- mResultString = null;
- mResultArray = null;
-
- // Room in current segment?
- char[] curr = mCurrentSegment;
- int max = curr.length - mCurrentSize;
- if (max >= len) {
- str.getChars(0, len, curr, mCurrentSize);
- mCurrentSize += len;
- } else {
- // No room for all, need to copy part(s):
- if (max > 0) {
- str.getChars(0, max, curr, mCurrentSize);
- len -= max;
- }
- /* And then allocate new segment; we are guaranteed to now
- * have enough room in segment.
- */
- expand(len);
- str.getChars(max, max+len, mCurrentSegment, 0);
- mCurrentSize = len;
- }
- }
-
- /*
- //////////////////////////////////////////////
- // Raw access, for high-performance use:
- //////////////////////////////////////////////
- */
-
- public char[] getCurrentSegment()
- {
- /* Since the intention of the caller is to directly add stuff into
- * buffers, we should NOT have anything in shared buffer... ie. may
- * need to unshare contents.
- */
- if (mInputStart >= 0) {
- unshare(1);
- } else {
- char[] curr = mCurrentSegment;
- if (curr == null) {
- mCurrentSegment = allocBuffer(0);
- } else if (mCurrentSize >= curr.length) {
- // Plus, we better have room for at least one more char
- expand(1);
- }
- }
- return mCurrentSegment;
- }
-
- public int getCurrentSegmentSize() {
- return mCurrentSize;
- }
-
- public void setCurrentLength(int len) {
- mCurrentSize = len;
- }
-
- public char[] finishCurrentSegment()
- {
- if (mSegments == null) {
- mSegments = new ArrayList();
- }
- mHasSegments = true;
- mSegments.add(mCurrentSegment);
- int oldLen = mCurrentSegment.length;
- mSegmentSize += oldLen;
- char[] curr = new char[calcNewSize(oldLen)];
- mCurrentSize = 0;
- mCurrentSegment = curr;
- return curr;
- }
-
- /**
- * Method used to determine size of the next segment to
- * allocate to contain textual content.
- */
- private int calcNewSize(int latestSize)
- {
- // Let's grow segments by 50%, when over 8k
- int incr = (latestSize < 8000) ? latestSize : (latestSize >> 1);
- int size = latestSize + incr;
- // but let's not create too big chunks
- return Math.min(size, MAX_SEGMENT_LENGTH);
- }
-
- /*
- //////////////////////////////////////////////
- // Standard methods:
- //////////////////////////////////////////////
- */
-
- /**
- * Note: calling this method may not be as efficient as calling
- * {@link #contentsAsString}, since it's not guaranteed that resulting
- * String is cached.
- */
- public String toString() {
- return contentsAsString();
- }
-
- /*
- //////////////////////////////////////////////
- // Internal methods:
- //////////////////////////////////////////////
- */
-
- /**
- * Method called if/when we need to append content when we have been
- * initialized to use shared buffer.
- */
- public void unshare(int needExtra)
- {
- int len = mInputLen;
- mInputLen = 0;
- char[] inputBuf = mInputBuffer;
- mInputBuffer = null;
- int start = mInputStart;
- mInputStart = -1;
-
- // Is buffer big enough, or do we need to reallocate?
- int needed = len+needExtra;
- if (mCurrentSegment == null || needed > mCurrentSegment.length) {
- mCurrentSegment = allocBuffer(needed);
- }
- if (len > 0) {
- System.arraycopy(inputBuf, start, mCurrentSegment, 0, len);
- }
- mSegmentSize = 0;
- mCurrentSize = len;
- }
-
- /**
- * Method called when current segment is full, to allocate new
- * segment.
- *
- * @param roomNeeded Number of characters that the resulting
- * new buffer must have
- */
- private void expand(int roomNeeded)
- {
- // First, let's move current segment to segment list:
- if (mSegments == null) {
- mSegments = new ArrayList();
- }
- char[] curr = mCurrentSegment;
- mHasSegments = true;
- mSegments.add(curr);
- int oldLen = curr.length;
- mSegmentSize += oldLen;
- int newSize = Math.max(roomNeeded, calcNewSize(oldLen));
- curr = new char[newSize];
- mCurrentSize = 0;
- mCurrentSegment = curr;
- }
-
- private char[] buildResultArray()
- {
- if (mResultString != null) { // Can take a shortcut...
- return mResultString.toCharArray();
- }
- char[] result;
-
- // Do we use shared array?
- if (mInputStart >= 0) {
- if (mInputLen < 1) {
- return DataUtil.getEmptyCharArray();
- }
- result = new char[mInputLen];
- System.arraycopy(mInputBuffer, mInputStart, result, 0,
- mInputLen);
- } else { // nope
- int size = size();
- if (size < 1) {
- return DataUtil.getEmptyCharArray();
- }
- int offset = 0;
- result = new char[size];
- if (mSegments != null) {
- for (int i = 0, len = mSegments.size(); i < len; ++i) {
- char[] curr = (char[]) mSegments.get(i);
- int currLen = curr.length;
- System.arraycopy(curr, 0, result, offset, currLen);
- offset += currLen;
- }
- }
- System.arraycopy(mCurrentSegment, 0, result, offset, mCurrentSize);
- }
- return result;
- }
-
- private final static class BufferReader
- extends Reader
- {
- ArrayList _Segments;
- char[] _CurrentSegment;
- final int _CurrentLength;
-
- int _SegmentIndex;
- int _SegmentOffset;
- int _CurrentOffset;
-
- public BufferReader(ArrayList segs, char[] currSeg, int currSegLen)
- {
- _Segments = segs;
- _CurrentSegment = currSeg;
- _CurrentLength = currSegLen;
-
- _SegmentIndex = 0;
- _SegmentOffset = _CurrentOffset = 0;
- }
-
- public void close() {
- _Segments = null;
- _CurrentSegment = null;
- }
-
- public void mark(int x)
- throws IOException
- {
- throw new IOException("mark() not supported");
- }
-
- public boolean markSupported() {
- return false;
- }
-
- public int read(char[] cbuf, int offset, int len)
- {
- if (len < 1) {
- return 0;
- }
-
- int origOffset = offset;
- // First need to copy stuff from previous segments
- while (_Segments != null) {
- char[] curr = (char[]) _Segments.get(_SegmentIndex);
- int max = curr.length - _SegmentOffset;
- if (len <= max) { // this is enough
- System.arraycopy(curr, _SegmentOffset, cbuf, offset, len);
- _SegmentOffset += len;
- offset += len;
- return (offset - origOffset);
- }
- // Not enough, but helps...
- if (max > 0) {
- System.arraycopy(curr, _SegmentOffset, cbuf, offset, max);
- offset += max;
- }
- if (++_SegmentIndex >= _Segments.size()) { // last one
- _Segments = null;
- } else {
- _SegmentOffset = 0;
- }
- }
-
- // ok, anything to copy from the active segment?
- if (len > 0 && _CurrentSegment != null) {
- int max = _CurrentLength - _CurrentOffset;
- if (len >= max) { // reading it all
- len = max;
- System.arraycopy(_CurrentSegment, _CurrentOffset,
- cbuf, offset, len);
- _CurrentSegment = null;
- } else {
- System.arraycopy(_CurrentSegment, _CurrentOffset,
- cbuf, offset, len);
- _CurrentOffset += len;
- }
- offset += len;
- }
-
- return (origOffset == offset) ? -1 : (offset - origOffset);
- }
-
- public boolean ready() {
- return true;
- }
-
- public void reset()
- throws IOException
- {
- throw new IOException("reset() not supported");
- }
-
- public long skip(long amount)
- {
- /* Note: implementation is almost identical to that of read();
- * difference being that no data is copied.
- */
- if (amount < 0) {
- return 0L;
- }
-
- long origAmount= amount;
-
- while (_Segments != null) {
- char[] curr = (char[]) _Segments.get(_SegmentIndex);
- int max = curr.length - _SegmentOffset;
- if (max >= amount) { // this is enough
- _SegmentOffset += (int) amount;
- return origAmount;
- }
- // Not enough, but helps...
- amount -= max;
- if (++_SegmentIndex >= _Segments.size()) { // last one
- _Segments = null;
- } else {
- _SegmentOffset = 0;
- }
- }
-
- // ok, anything left in the active segment?
- if (amount > 0 && _CurrentSegment != null) {
- int max = _CurrentLength - _CurrentOffset;
- if (amount >= max) { // reading it all
- amount -= max;
- _CurrentSegment = null;
- } else {
- amount = 0L;
- _CurrentOffset += (int) amount;
- }
- }
-
- return (amount == origAmount) ? -1L : (origAmount - amount);
- }
- }
-}
diff -Nru libwoodstox-java-4.1.3/src/java/com/ctc/wstx/util/TextBuilder.java libwoodstox-java-5.1.0/src/java/com/ctc/wstx/util/TextBuilder.java
--- libwoodstox-java-4.1.3/src/java/com/ctc/wstx/util/TextBuilder.java 2012-04-24 04:38:21.000000000 +0000
+++ libwoodstox-java-5.1.0/src/java/com/ctc/wstx/util/TextBuilder.java 1970-01-01 00:00:00.000000000 +0000
@@ -1,133 +0,0 @@
-package com.ctc.wstx.util;
-
-/**
- * Class similar to {@link StringBuffer}, except that it can be used to
- * construct multiple Strings, that will share same underlying character
- * buffer. This is generally useful for closely related value Strings,
- * such as attribute values of a single XML start element.
- */
-public final class TextBuilder
-{
- private final static int MIN_LEN = 60;
- private final static int MAX_LEN = 120;
-
- private char[] mBuffer;
-
- private int mBufferLen;
-
- private String mResultString;
-
- /*
- ///////////////////////////////////////////////
- // Life-cycle:
- ///////////////////////////////////////////////
- */
-
- public TextBuilder(int initialSize)
- {
- int charSize = (initialSize << 4); // multiply by 16 (-> def. 192 chars)
- if (charSize < MIN_LEN) {
- charSize = MIN_LEN;
- } else if (charSize > MAX_LEN) {
- charSize = MAX_LEN;
- }
- mBuffer = new char[charSize];
- }
-
- /**
- * Method called before starting to (re)use the buffer, will discard
- * any existing content, and start collecting new set of values.
- */
- public void reset() {
- mBufferLen = 0;
- mResultString = null;
- }
-
- /*
- ///////////////////////////////////////////////
- // Accesors:
- ///////////////////////////////////////////////
- */
-
- public boolean isEmpty() {
- return mBufferLen == 0;
- }
-
- public String getAllValues()
- {
- if (mResultString == null) {
- mResultString = new String(mBuffer, 0, mBufferLen);
- }
- return mResultString;
- }
-
- /**
- * Method that gives access to underlying character buffer
- */
- public char[] getCharBuffer() {
- return mBuffer;
- }
-
- public int getCharSize() {
- return mBufferLen;
- }
-
- /*
- ///////////////////////////////////////////////
- // Mutators:
- ///////////////////////////////////////////////
- */
-
- public void append(char c) {
- if (mBuffer.length == mBufferLen) {
- resize(1);
- }
- mBuffer[mBufferLen++] = c;
- }
-
- public void append(char[] src, int start, int len) {
- if (len > (mBuffer.length - mBufferLen)) {
- resize(len);
- }
- System.arraycopy(src, start, mBuffer, mBufferLen, len);
- mBufferLen += len;
- }
-
- public void setBufferSize(int newSize) {
- mBufferLen = newSize;
- }
-
- public char[] bufferFull(int needSpaceFor) {
- mBufferLen = mBuffer.length;
- resize(1);
- return mBuffer;
- }
-
- /*
- ///////////////////////////////////////////////
- // Debugging:
- ///////////////////////////////////////////////
- */
-
- public String toString() {
- return new String(mBuffer, 0, mBufferLen);
- }
-
- /*
- ///////////////////////////////////////////////
- // Internal methods:
- ///////////////////////////////////////////////
- */
-
- private void resize(int needSpaceFor) {
- char[] old = mBuffer;
- int oldLen = old.length;
- int addition = oldLen >> 1; // Grow by 50%
- needSpaceFor -= (oldLen - mBufferLen);
- if (addition < needSpaceFor) {
- addition = needSpaceFor;
- }
- mBuffer = new char[oldLen+addition];
- System.arraycopy(old, 0, mBuffer, 0, mBufferLen);
- }
-}
diff -Nru libwoodstox-java-4.1.3/src/java/com/ctc/wstx/util/URLUtil.java libwoodstox-java-5.1.0/src/java/com/ctc/wstx/util/URLUtil.java
--- libwoodstox-java-4.1.3/src/java/com/ctc/wstx/util/URLUtil.java 2012-04-24 04:38:21.000000000 +0000
+++ libwoodstox-java-5.1.0/src/java/com/ctc/wstx/util/URLUtil.java 1970-01-01 00:00:00.000000000 +0000
@@ -1,190 +0,0 @@
-package com.ctc.wstx.util;
-
-import java.io.*;
-import java.net.URI;
-import java.net.URL;
-import java.net.URLDecoder;
-import java.net.MalformedURLException;
-import java.net.URISyntaxException;
-
-public final class URLUtil
-{
- private URLUtil() { }
-
- /**
- * Method that tries to figure out how to create valid URL from a system
- * id, without additional contextual information.
- * If we could use URIs this might be easier to do, but they are part
- * of JDK 1.4, and preferably code should only require 1.2 (or maybe 1.3)
- */
- public static URL urlFromSystemId(String sysId)
- throws IOException
- {
- try {
- /* Ok, does it look like a full URL? For one, you need a colon. Also,
- * to reduce likelihood of collision with Windows paths, let's only
- * accept it if there are 3 preceding other chars...
- * Not sure if Mac might be a problem? (it uses ':' as file path
- * separator, alas, at least prior to MacOS X)
- */
- int ix = sysId.indexOf(':', 0);
- /* Also, protocols are generally fairly short, usually 3 or 4
- * chars (http, ftp, urn); so let's put upper limit of 8 chars too
- */
- if (ix >= 3 && ix <= 8) {
- return new URL(sysId);
- }
- // Ok, let's just assume it's local file reference...
- /* 24-May-2006, TSa: Amazingly, this single call does show in
- * profiling, for small docs. The problem is that deep down it
- * tries to check physical file system, to check if the File
- * pointed to is a directory: and that is (relatively speaking)
- * a very expensive call. Since in this particular case it
- * should never be a dir (and/or doesn't matter), let's just
- * implement conversion locally
- */
- String absPath = new java.io.File(sysId).getAbsolutePath();
- // Need to convert colons/backslashes to regular slashes?
- {
- char sep = File.separatorChar;
- if (sep != '/') {
- absPath = absPath.replace(sep, '/');
- }
- }
- if (absPath.length() > 0 && absPath.charAt(0) != '/') {
- absPath = "/" + absPath;
- }
- return new URL("file", "", absPath);
- } catch (MalformedURLException e) {
- throwIOException(e, sysId);
- return null; // never gets here
- }
- }
-
- /**
- * @since 4.1
- */
- public static URI uriFromSystemId(String sysId) throws IOException
- {
- // note: mostly a copy of matching method above, but with URI instead of URL
- try {
- int ix = sysId.indexOf(':', 0);
- if (ix >= 3 && ix <= 8) {
- return new URI(sysId);
- }
- String absPath = new java.io.File(sysId).getAbsolutePath();
- char sep = File.separatorChar;
- if (sep != '/') {
- absPath = absPath.replace(sep, '/');
- }
- if (absPath.length() > 0 && absPath.charAt(0) != '/') {
- absPath = "/" + absPath;
- }
- return new URI("file", absPath, null);
- } catch (URISyntaxException e) {
- throwIOException(e, sysId);
- return null; // never gets here
- }
- }
-
- public static URL urlFromSystemId(String sysId, URL ctxt) throws IOException
- {
- if (ctxt == null) {
- return urlFromSystemId(sysId);
- }
- try {
- return new URL(ctxt, sysId);
- } catch (MalformedURLException e) {
- throwIOException(e, sysId);
- return null; // never gets here
- }
- }
-
- /**
- * Method that tries to create and return URL that denotes current
- * working directory. Usually used to create a context, when one is
- * not explicitly passed.
- */
- public static URL urlFromCurrentDir()
- throws java.net.MalformedURLException /* an IOException */
- {
- /* This seems to work; independent of whether there happens to
- * be such/file dir or not.
- */
- return new File("a").getAbsoluteFile().getParentFile().toURL();
- }
-
- /**
- * Method that tries to get a stream (ideally, optimal one) to read from
- * the specified URL.
- * Currently it just means creating a simple file input stream if the
- * URL points to a (local) file, and otherwise relying on URL classes
- * input stream creation method.
- */
- public static InputStream inputStreamFromURL(URL url)
- throws IOException
- {
- if ("file".equals(url.getProtocol())) {
- /* As per [WSTX-82], can not do this if the path refers
- * to a network drive on windows. This fixes the problem;
- * might not be needed on all platforms (NFS?), but should not
- * matter a lot: performance penalty of extra wrapping is more
- * relevant when accessing local file system.
- */
- String host = url.getHost();
- if (host == null || host.length() == 0) {
- /* One more test: if there are quoted characters, need
- * to decoded [WSTX-207]:
- */
- String path = url.getPath();
- if (path.indexOf('%') >= 0) {
- path = URLDecoder.decode(path, "UTF-8");
- }
- return new FileInputStream(path);
- }
- }
- return url.openStream();
- }
-
- /**
- * Method that tries to get a stream (ideally, optimal one) to write to
- * the resource specified by given URL.
- * Currently it just means creating a simple file output stream if the
- * URL points to a (local) file, and otherwise relying on URL classes
- * input stream creation method.
- */
- public static OutputStream outputStreamFromURL(URL url)
- throws IOException
- {
- if ("file".equals(url.getProtocol())) {
- /* As per [WSTX-82], can not do this if the path refers
- * to a network drive on windows.
- */
- String host = url.getHost();
- if (host == null || host.length() == 0) {
- return new FileOutputStream(url.getPath());
- }
- }
- return url.openConnection().getOutputStream();
- }
-
- /*
- ///////////////////////////////////////////////////////////////////////
- // Private helper methods
- ///////////////////////////////////////////////////////////////////////
- */
-
- /**
- * Helper method that tries to fully convert strange URL-specific exception
- * to more general IO exception. Also, to try to use JDK 1.4 feature without
- * creating requirement, uses reflection to try to set the root cause, if
- * we are running on JDK1.4
- */
- private static void throwIOException(Exception mex, String sysId)
- throws IOException
- {
- IOException ie = new IOException("[resolving systemId '"+sysId+"']: "+mex.toString());
- ExceptionUtil.setInitCause(ie, mex);
- throw ie;
- }
-}
diff -Nru libwoodstox-java-4.1.3/src/java/com/ctc/wstx/util/WordResolver.java libwoodstox-java-5.1.0/src/java/com/ctc/wstx/util/WordResolver.java
--- libwoodstox-java-4.1.3/src/java/com/ctc/wstx/util/WordResolver.java 2012-04-24 04:38:21.000000000 +0000
+++ libwoodstox-java-5.1.0/src/java/com/ctc/wstx/util/WordResolver.java 1970-01-01 00:00:00.000000000 +0000
@@ -1,580 +0,0 @@
-package com.ctc.wstx.util;
-
-import java.util.*;
-
-/**
- * A specialized Map/Symbol table - like data structure that can be used
- * for both checking whether a word (passed in as a char array) exists
- * in certain set of words AND getting that word as a String.
- * It is reasonably efficient both time and speed-wise, at least for
- * certain use cases; specifically, if there is no existing key to use,
- * it is more efficient way to get to a shared copy of that String
- * The general usage pattern is expected
- * to be such that most checks are positive, ie. that the word indeed
- * is contained in the structure.
- *
- * Although this is an efficient data struct for specific set of usage
- * patterns, one restriction is that the full set of words to include has to
- * be known before constructing the instnace. Also, the size of the set is
- * limited to total word content of about 20k characters.
- *
- * TODO: Should document the internal data structure...
- */
-public final class WordResolver
-{
- /**
- * Maximum number of words (Strings) an instance can contain
- */
- public final static int MAX_WORDS = 0x2000;
-
- final static char CHAR_NULL = (char) 0;
-
- /**
- * Offset added to numbers to mark 'negative' numbers. Asymmetric,
- * since range of negative markers needed is smaller than positive
- * numbers...
- */
- final static int NEGATIVE_OFFSET = 0x10000 - MAX_WORDS;
-
- /**
- * This is actually just a guess; but in general linear search should
- * be faster for short sequences (definitely for 4 or less; maybe up
- * to 8 or less?)
- */
- final static int MIN_BINARY_SEARCH = 7;
-
- /**
- * Compressed presentation of the word set.
- */
- final char[] mData;
-
- /**
- * Array of actual words returned resolved for matches.
- */
- final String[] mWords;
-
- /*
- ////////////////////////////////////////////////
- // Life-cycle
- ////////////////////////////////////////////////
- */
-
- private WordResolver(String[] words, char[] index) {
- mWords = words;
- mData = index;
- }
-
- /**
- * Tries to construct an instance given ordered set of words.
- *
- * Note: currently maximum number of words that can be contained
- * is limited to {@link #MAX_WORDS}; additionally, maximum length
- * of all such words can not exceed roughly 28000 characters.
- *
- * @return WordResolver constructed for given set of words, if
- * the word set size is not too big; null to indicate "too big"
- * instance.
- */
- public static WordResolver constructInstance(TreeSet wordSet)
- {
- if (wordSet.size() > MAX_WORDS) {
- return null;
- }
- return new Builder(wordSet).construct();
- }
-
- /*
- ////////////////////////////////////////////////
- // Public API
- ////////////////////////////////////////////////
- */
-
- /**
- * @return Number of words contained
- */
- public int size() {
- return mWords.length;
- }
-
- /*
- public int indexSize() {
- return mData.length;
- }
- */
-
- /**
- * @param str Character array that contains the word to find
- * @param start Index of the first character of the word
- * @param end Index following the last character of the word,
- * so that end - start
equals word length (similar
- * to the way String.substring()
has).
- *
- * @return (Shared) string instance of the word, if it exists in
- * the word set; null if not.
- */
- public String find(char[] str, final int start, final int end)
- {
- char[] data = mData;
-
- // 03-Jan-2006, TSa: Special case; one entry
- if (data == null) {
- return findFromOne(str, start, end);
- }
-
- int ptr = 0; // pointer to compressed set data
- int offset = start;
-
- while (true) {
- // End of input String? Need to match the runt entry!
- if (offset == end) {
- if (data[ptr+1] == CHAR_NULL) {
- return mWords[data[ptr+2] - NEGATIVE_OFFSET];
- }
- return null;
- }
-
- int count = data[ptr++];
- // Need to find the branch to follow, if any
- char c = str[offset++];
-
- inner_block:
- do { // dummy loop, need to have break
- // Linear or binary search?
- if (count < MIN_BINARY_SEARCH) {
- // always at least two branches; never less
- if (data[ptr] == c) {
- ptr = (int) data[ptr+1];
- break inner_block;
- }
- if (data[ptr+2] == c) {
- ptr = (int) data[ptr+3];
- break inner_block;
- }
- int branchEnd = ptr + (count << 1);
- // Starts from entry #3, if such exists
- for (ptr += 4; ptr < branchEnd; ptr += 2) {
- if (data[ptr] == c) {
- ptr = (int) data[ptr+1];
- break inner_block;
- }
- }
- return null; // No match!
- } else { // Ok, binary search:
- int low = 0;
- int high = count-1;
- int mid;
-
- while (low <= high) {
- mid = (low + high) >> 1;
- int ix = ptr + (mid << 1);
- int diff = data[ix] - c;
- if (diff > 0) { // char was 'higher', need to go down
- high = mid-1;
- } else if (diff < 0) { // lower, need to go up
- low = mid+1;
- } else { // match (so far)
- ptr = (int) data[ix+1];
- break inner_block;
- }
- }
- return null; // No match!
- }
- } while (false);
-
- // Ok; now, is it the end?
- if (ptr >= NEGATIVE_OFFSET) {
- String word = mWords[ptr - NEGATIVE_OFFSET];
- int expLen = (end - start);
- if (word.length() != expLen) {
- return null;
- }
- for (int i = offset - start; offset < end; ++i, ++offset) {
- if (word.charAt(i) != str[offset]) {
- return null;
- }
- }
- return word;
- }
- }
- // never gets here
- }
-
- private String findFromOne(char[] str, final int start, final int end)
- {
- String word = mWords[0];
- int len = end-start;
- if (word.length() != len) {
- return null;
- }
- for (int i = 0; i < len; ++i) {
- if (word.charAt(i) != str[start+i]) {
- return null;
- }
- }
- return word;
- }
-
- /**
- * @return (Shared) string instance of the word, if it exists in
- * the word set; null if not.
- */
- public String find(String str)
- {
- char[] data = mData;
-
- // 03-Jan-2006, TSa: Special case; one entry
- if (data == null) {
- String word = mWords[0];
- return word.equals(str) ? word : null;
- }
-
- int ptr = 0; // pointer to compressed set data
- int offset = 0;
- int end = str.length();
-
- while (true) {
- // End of input String? Need to match the runt entry!
- if (offset == end) {
- if (data[ptr+1] == CHAR_NULL) {
- return mWords[data[ptr+2] - NEGATIVE_OFFSET];
- }
- return null;
- }
-
- int count = data[ptr++];
- // Need to find the branch to follow, if any
- char c = str.charAt(offset++);
-
- inner_block:
- do { // dummy loop, need to have break
- // Linear or binary search?
- if (count < MIN_BINARY_SEARCH) {
- // always at least two branches; never less
- if (data[ptr] == c) {
- ptr = (int) data[ptr+1];
- break inner_block;
- }
- if (data[ptr+2] == c) {
- ptr = (int) data[ptr+3];
- break inner_block;
- }
- int branchEnd = ptr + (count << 1);
- // Starts from entry #3, if such exists
- for (ptr += 4; ptr < branchEnd; ptr += 2) {
- if (data[ptr] == c) {
- ptr = (int) data[ptr+1];
- break inner_block;
- }
- }
- return null; // No match!
- } else { // Ok, binary search:
- int low = 0;
- int high = count-1;
- int mid;
-
- while (low <= high) {
- mid = (low + high) >> 1;
- int ix = ptr + (mid << 1);
- int diff = data[ix] - c;
- if (diff > 0) { // char was 'higher', need to go down
- high = mid-1;
- } else if (diff < 0) { // lower, need to go up
- low = mid+1;
- } else { // match (so far)
- ptr = (int) data[ix+1];
- break inner_block;
- }
- }
- return null; // No match!
- }
- } while (false);
-
- // Ok; now, is it the end?
- if (ptr >= NEGATIVE_OFFSET) {
- String word = mWords[ptr - NEGATIVE_OFFSET];
- if (word.length() != str.length()) {
- return null;
- }
- for (; offset < end; ++offset) {
- if (word.charAt(offset) != str.charAt(offset)) {
- return null;
- }
- }
- return word;
- }
- }
- // never gets here
- }
-
- /*
- ////////////////////////////////////////////////
- // Re-defined public methods
- ////////////////////////////////////////////////
- */
-
- public String toString()
- {
- StringBuffer sb = new StringBuffer(16 + (mWords.length << 3));
- for (int i = 0, len = mWords.length; i < len; ++i) {
- if (i > 0) {
- sb.append(", ");
- }
- sb.append(mWords[i]);
- }
- return sb.toString();
- }
-
- /*
- ////////////////////////////////////////////////
- // Private methods
- ////////////////////////////////////////////////
- */
-
- /*
- ////////////////////////////////////////////////
- // Helper classes
- ////////////////////////////////////////////////
- */
-
- private final static class Builder
- {
- final String[] mWords;
-
- char[] mData;
-
- /**
- * Number of characters currently used from mData
- */
- int mSize;
-
- public Builder(TreeSet wordSet)
- {
- int wordCount = wordSet.size();
-
- mWords = new String[wordCount];
- wordSet.toArray(mWords);
-
- /* 03-Jan-2006, TSa: Special case: just one entry; if so,
- * let's leave char array null, and just have the String
- * array with one entry.
- */
- if (wordCount < 2) {
- if (wordCount == 0) {
- throw new IllegalArgumentException(); // not legal
- }
- mData = null;
- } else {
- /* Let's guess approximate size we should need, assuming
- * average word length of 6 characters, overhead matching
- * compression (ie. about 1-to-1 ratio overall)
- */
- int size = wordCount * 6;
- if (size < 256) {
- size = 256;
- }
- mData = new char[size];
- }
- }
-
- /**
- * @return Raw character data that contains compressed structure
- * of the word set
- */
- public WordResolver construct()
- {
- char[] result;
-
- /* 03-Jan-2006, TSa: Special case: just one entry; if so,
- * let's leave char array null, and just have the String
- * array with one entry.
- */
- if (mData == null) {
- result = null;
- } else {
- constructBranch(0, 0, mWords.length);
-
- // Too big?
- if (mSize > NEGATIVE_OFFSET) {
- return null;
- }
-
- result = new char[mSize];
- System.arraycopy(mData, 0, result, 0, mSize);
- }
-
- return new WordResolver(mWords, result);
- }
-
- /**
- * Method that is called recursively to build the data
- * representation for a branch, ie. part of word set tree
- * that still has more than one ending
- *
- * @param charIndex Index of the character in words to consider
- * for this round
- * @param start Index of the first word to be processed
- * @param end Index of the word after last word to be processed
- * (so that number of words is end - start - 1
- */
- private void constructBranch(int charIndex, int start, int end)
- {
- // If more than one entry, need to divide into groups
-
- // First, need to add placeholder for branch count:
- if (mSize >= mData.length) {
- expand(1);
- }
- mData[mSize++] = 0; // placeholder!
- /* structStart will point to second char of first entry
- * (which will temporarily have entry count, eventually 'link'
- * to continuation)
- */
- int structStart = mSize + 1;
- int groupCount = 0;
- int groupStart = start;
- String[] words = mWords;
- boolean gotRunt;
-
- /* First thing we need to do is a special check for the
- * first entry -- it may be "runt" word, one that has no
- * more chars but also has a longer version ("id" vs.
- * "identifier"). If so, it needs to be marked; this is done
- * by adding a special entry before other entries (since such
- * entry would always be ordered first alphabetically)
- */
- if (words[groupStart].length() == charIndex) { // yup, got one:
- if ((mSize + 2) > mData.length) {
- expand(2);
- }
- /* First null marks the "missing" char (or, end-of-word);
- * and then we need the index
- */
- mData[mSize++] = CHAR_NULL;
- mData[mSize++] = (char) (NEGATIVE_OFFSET + groupStart);
-
- // Ok, let's then ignore that entry
- ++groupStart;
- ++groupCount;
- gotRunt = true;
- } else {
- gotRunt = false;
- }
-
- // Ok, then, let's find the ('real') groupings:
- while (groupStart < end) {
- // Inner loop, let's find the group:
- char c = words[groupStart].charAt(charIndex);
- int j = groupStart+1;
- while (j < end && words[j].charAt(charIndex) == c) {
- ++j;
- }
- /* Ok, let's store the char in there, along with count;
- * count will be needed in second, and will then get
- * overwritten with actual data later on
- */
- if ((mSize + 2) > mData.length) {
- expand(2);
- }
- mData[mSize++] = c;
- mData[mSize++] = (char) (j - groupStart); // entries in group
- groupStart = j;
- ++groupCount;
- }
-
- /* Ok, groups found; need to loop through them, recursively
- * calling branch and/or leaf methods
- */
- // first let's output the header, ie. group count:
- mData[structStart-2] = (char) groupCount;
- groupStart = start;
-
- // Do we have the "runt" to skip?
- if (gotRunt) {
- structStart += 2;
- ++groupStart;
- }
-
- int structEnd = mSize;
- ++charIndex;
- for (; structStart < structEnd; structStart += 2) {
- groupCount = (int) mData[structStart]; // no sign expansion, is ok
- /* Ok, count gotten, can either create a branch (if more than
- * one entry) or leaf (just one entry)
- */
- if (groupCount == 1) {
- mData[structStart] = (char) (NEGATIVE_OFFSET + groupStart);
- } else {
- mData[structStart] = (char) mSize;
- constructBranch(charIndex, groupStart,
- groupStart + groupCount);
- }
- groupStart += groupCount;
- }
-
- // done!
- }
-
- private char[] expand(int needSpace)
- {
- char[] old = mData;
- int len = old.length;
- int newSize = len + ((len < 4096) ? len : (len >> 1));
-
- /* Let's verify we get enough; should always be true but
- * better safe than sorry
- */
- if (newSize < (mSize + needSpace)) {
- newSize = mSize + needSpace + 64;
- }
- mData = new char[newSize];
- System.arraycopy(old, 0, mData, 0, len);
- return mData;
- }
- }
-
- /*
- ////////////////////////////////////////////////////
- // Simple test driver, useful for debugging
- // (uncomment if needed -- commented out so it won't
- // affect coverage testing)
- ////////////////////////////////////////////////////
- */
-
- /*
- public static void main(String[] args)
- {
- if (args.length < 2) {
- System.err.println("Usage: "+WordResolver.class+" word1 [word2] ... [wordN] keyword");
- System.exit(1);
- }
- String key = args[args.length-1];
- TreeSet words = new TreeSet();
- for (int i = 0; i < args.length-1; ++i) {
- words.add(args[i]);
- }
-
- WordResolver set = WordResolver.constructInstance(words);
-
-//outputData(set.mData);
-
- // Ok, and then the test!
- char[] keyA = new char[key.length() + 4];
- key.getChars(0, key.length(), keyA, 2);
- //System.out.println("Word '"+key+"' found via array search: "+WordResolver.find(data, keyA, 2, key.length() + 2));
- System.out.println("Word '"+key+"' found via array search: "+set.find(keyA, 2, key.length() + 2));
- }
-
- static void outputData(char[] data)
- {
- for (int i = 0; i < data.length; ++i) {
- char c = data[i];
- System.out.print(Integer.toHexString(i)+" ["+Integer.toHexString(c)+"]");
- if (c > 32 && c <= 127) { // printable char (letter)
- System.out.println(" -> '"+c+"'");
- } else {
- System.out.println();
- }
- }
- }
- */
-}
diff -Nru libwoodstox-java-4.1.3/src/java/com/ctc/wstx/util/WordSet.java libwoodstox-java-5.1.0/src/java/com/ctc/wstx/util/WordSet.java
--- libwoodstox-java-4.1.3/src/java/com/ctc/wstx/util/WordSet.java 2012-04-24 04:38:21.000000000 +0000
+++ libwoodstox-java-5.1.0/src/java/com/ctc/wstx/util/WordSet.java 1970-01-01 00:00:00.000000000 +0000
@@ -1,476 +0,0 @@
-package com.ctc.wstx.util;
-
-import java.util.*;
-
-/**
- * An efficient (both memory and time) implementation of a Set used to
- * verify that a given
- * word is contained within the set. The general usage pattern is expected
- * to be such that most checks are positive, ie. that the word indeed
- * is contained in the set.
- *
- * Performance of the set is comparable to that of {@link java.util.TreeSet}
- * for Strings, ie. 2-3x slower than {@link java.util.HashSet} when
- * using pre-constructed Strings. This is generally result of algorithmic
- * complexity of structures; Word and Tree sets are roughly logarithmic
- * to the whole data, whereas Hash set is linear to the length of key.
- * However:
- *
- * - WordSet can use char arrays as keys, without constructing Strings.
- * In cases where there is no (need for) Strings, WordSet seems to be
- * about twice as fast, even without considering additional GC caused
- * by temporary String instances.
- *
- * - WordSet is more compact in its memory presentation; if Strings are
- * shared its size is comparable to optimally filled HashSet, and if
- * no such Strings exists, its much more compact (relatively speaking)
- *
- *
- *
- * Although this is an efficient set for specific set of usage patterns,
- * one restriction is that the full set of words to include has to be
- * known before constructing the set. Also, the size of the set is
- * limited to total word content of about 20k characters; factory method
- * does verify the limit and indicates if an instance can not be created.
- */
-public final class WordSet
-{
- final static char CHAR_NULL = (char) 0;
-
- /**
- * Offset added to numbers to mark 'negative' numbers. Asymmetric,
- * since range of negative markers needed is smaller than positive
- * numbers...
- */
- final static int NEGATIVE_OFFSET = 0xC000;
-
- /**
- * This is actually just a guess; but in general linear search should
- * be faster for short sequences (definitely for 4 or less; maybe up
- * to 8 or less?)
- */
- final static int MIN_BINARY_SEARCH = 7;
-
- /**
- * Compressed presentation of the word set.
- */
- final char[] mData;
-
- /*
- ////////////////////////////////////////////////
- // Life-cycle
- ////////////////////////////////////////////////
- */
-
- private WordSet(char[] data) {
- mData = data;
- }
-
- public static WordSet constructSet(TreeSet wordSet)
- {
- return new WordSet(new Builder(wordSet).construct());
- }
-
- public static char[] constructRaw(TreeSet wordSet)
- {
- return new Builder(wordSet).construct();
- }
-
- /*
- ////////////////////////////////////////////////
- // Public API
- ////////////////////////////////////////////////
- */
-
- public boolean contains(char[] buf, int start, int end) {
- return contains(mData, buf, start, end);
- }
-
- public static boolean contains(char[] data, char[] str, int start, int end)
- {
- int ptr = 0; // pointer to compressed set data
-
- main_loop:
- do {
- int left = end-start;
-
- // End of input String? Need to have the run entry:
- if (left == 0) {
- return (data[ptr+1] == CHAR_NULL);
- }
-
- int count = data[ptr++];
-
- // Nope, but do we have an end marker?
- if (count >= NEGATIVE_OFFSET) {
- // How many chars do we need to have left to match?
- int expCount = count - NEGATIVE_OFFSET;
- if (left != expCount) {
- return false;
- }
- while (start < end) {
- if (data[ptr] != str[start]) {
- return false;
- }
- ++ptr;
- ++start;
- }
- return true;
- }
-
- // No, need to find the branch to follow, if any
- char c = str[start++];
-
- // Linear or binary search?
- if (count < MIN_BINARY_SEARCH) {
- // always at least two branches; never less
- if (data[ptr] == c) {
- ptr = (int) data[ptr+1];
- continue main_loop;
- }
- if (data[ptr+2] == c) {
- ptr = (int) data[ptr+3];
- continue main_loop;
- }
- int branchEnd = ptr + (count << 1);
- // Starts from entry #3, if such exists
- for (ptr += 4; ptr < branchEnd; ptr += 2) {
- if (data[ptr] == c) {
- ptr = (int) data[ptr+1];
- continue main_loop;
- }
- }
- return false; // No match!
- }
-
- { // Ok, binary search:
- int low = 0;
- int high = count-1;
- int mid;
-
- while (low <= high) {
- mid = (low + high) >> 1;
- int ix = ptr + (mid << 1);
- int diff = data[ix] - c;
- if (diff > 0) { // char was 'higher', need to go down
- high = mid-1;
- } else if (diff < 0) { // lower, need to go up
- low = mid+1;
- } else { // match
- ptr = (int) data[ix+1];
- continue main_loop;
- }
- }
- }
-
- // If we fall here, no match!
- return false;
-
- } while (ptr != 0);
-
- // If we reached an end state, must match the length
- return (start == end);
- }
-
- public boolean contains(String str) {
- return contains(mData, str);
- }
-
- public static boolean contains(char[] data, String str)
- {
- // Let's use same vars as array-based code, to allow cut'n pasting
- int ptr = 0; // pointer to compressed set data
- int start = 0;
- int end = str.length();
-
- main_loop:
- do {
- int left = end-start;
-
- // End of input String? Need to have the run entry:
- if (left == 0) {
- return (data[ptr+1] == CHAR_NULL);
- }
-
- int count = data[ptr++];
-
- // Nope, but do we have an end marker?
- if (count >= NEGATIVE_OFFSET) {
- // How many chars do we need to have left to match?
- int expCount = count - NEGATIVE_OFFSET;
- if (left != expCount) {
- return false;
- }
- while (start < end) {
- if (data[ptr] != str.charAt(start)) {
- return false;
- }
- ++ptr;
- ++start;
- }
- return true;
- }
-
- // No, need to find the branch to follow, if any
- char c = str.charAt(start++);
-
- // Linear or binary search?
- if (count < MIN_BINARY_SEARCH) {
- // always at least two branches; never less
- if (data[ptr] == c) {
- ptr = (int) data[ptr+1];
- continue main_loop;
- }
- if (data[ptr+2] == c) {
- ptr = (int) data[ptr+3];
- continue main_loop;
- }
- int branchEnd = ptr + (count << 1);
- // Starts from entry #3, if such exists
- for (ptr += 4; ptr < branchEnd; ptr += 2) {
- if (data[ptr] == c) {
- ptr = (int) data[ptr+1];
- continue main_loop;
- }
- }
- return false; // No match!
- }
-
- { // Ok, binary search:
- int low = 0;
- int high = count-1;
- int mid;
-
- while (low <= high) {
- mid = (low + high) >> 1;
- int ix = ptr + (mid << 1);
- int diff = data[ix] - c;
- if (diff > 0) { // char was 'higher', need to go down
- high = mid-1;
- } else if (diff < 0) { // lower, need to go up
- low = mid+1;
- } else { // match
- ptr = (int) data[ix+1];
- continue main_loop;
- }
- }
- }
-
- // If we fall here, no match!
- return false;
-
- } while (ptr != 0);
-
- // If we reached an end state, must match the length
- return (start == end);
- }
-
- /*
- ////////////////////////////////////////////////
- // Private methods
- ////////////////////////////////////////////////
- */
-
- /*
- ////////////////////////////////////////////////
- // Helper classes
- ////////////////////////////////////////////////
- */
-
- private final static class Builder
- {
- final String[] mWords;
-
- char[] mData;
-
- /**
- * Number of characters currently used from mData
- */
- int mSize;
-
- public Builder(TreeSet wordSet) {
- int wordCount = wordSet.size();
- mWords = new String[wordCount];
- wordSet.toArray(mWords);
-
- /* Let's guess approximate size we should need, assuming
- * average word length of 6 characters, and 100% overhead
- * in structure:
- */
- int size = wordCount * 12;
- if (size < 256) {
- size = 256;
- }
- mData = new char[size];
- }
-
- /**
- * @return Raw character data that contains compressed structure
- * of the word set
- */
- public char[] construct()
- {
-// Uncomment if you need to debug array-out-of-bound probs
-//try {
- // Let's check degenerate case of 1 word:
- if (mWords.length == 1) {
- constructLeaf(0, 0);
- } else {
- constructBranch(0, 0, mWords.length);
- }
-//} catch (Throwable t) { System.err.println("Error: "+t); }
-
- char[] result = new char[mSize];
- System.arraycopy(mData, 0, result, 0, mSize);
- return result;
- }
-
- /**
- * Method that is called recursively to build the data
- * representation for a branch, ie. part of word set tree
- * that still has more than one ending
- *
- * @param charIndex Index of the character in words to consider
- * for this round
- * @param start Index of the first word to be processed
- * @param end Index of the word after last word to be processed
- * (so that number of words is end - start - 1
- */
- private void constructBranch(int charIndex, int start, int end)
- {
- // If more than one entry, need to divide into groups
-
- // First, need to add placeholder for branch count:
- if (mSize >= mData.length) {
- expand(1);
- }
- mData[mSize++] = 0; // placeholder!
- /* structStart will point to second char of first entry
- * (which will temporarily have entry count, eventually 'link'
- * to continuation)
- */
- int structStart = mSize + 1;
- int groupCount = 0;
- int groupStart = start;
- String[] words = mWords;
-
- /* First thing we need to do is a special check for the
- * first entry -- it may be "runt" word, one that has no
- * more chars but also has a longer version ("id" vs.
- * "identifier"). If there is such a word, it'll always
- * be first in alphabetic ordering:
- */
- if (words[groupStart].length() == charIndex) { // yup, got one:
- if ((mSize + 2) > mData.length) {
- expand(2);
- }
- /* Nulls mark both imaginary branching null char and
- * "missing link" to the rest
- */
- mData[mSize++] = CHAR_NULL;
- mData[mSize++] = CHAR_NULL;
-
- // Ok, let's then ignore that entry
- ++groupStart;
- ++groupCount;
- }
-
- // Ok, then, let's find the ('real') groupings:
- while (groupStart < end) {
- // Inner loop, let's find the group:
- char c = words[groupStart].charAt(charIndex);
- int j = groupStart+1;
- while (j < end && words[j].charAt(charIndex) == c) {
- ++j;
- }
- /* Ok, let's store the char in there, along with count;
- * count will be needed in second, and will then get
- * overwritten with actual data later on
- */
- if ((mSize + 2) > mData.length) {
- expand(2);
- }
- mData[mSize++] = c;
- mData[mSize++] = (char) (j - groupStart); // entries in group
- groupStart = j;
- ++groupCount;
- }
-
- /* Ok, groups found; need to loop through them, recursively
- * calling branch and/or leaf methods
- */
- // first let's output the header, ie. group count:
- mData[structStart-2] = (char) groupCount;
- groupStart = start;
-
- // Do we have the "runt" to skip?
- if (mData[structStart] == CHAR_NULL) {
- structStart += 2;
- ++groupStart;
- }
-
- int structEnd = mSize;
- ++charIndex;
- for (; structStart < structEnd; structStart += 2) {
- groupCount = (int) mData[structStart]; // no sign expansion, is ok
- // Ok, count gotten, can now put the 'link' (pointer) in there
- mData[structStart] = (char) mSize;
- if (groupCount == 1) {
- /* One optimization; if it'd lead to a single runt
- * entry, we can just add 'null' link:
- */
- String word = words[groupStart];
- if (word.length() == charIndex) {
- mData[structStart] = CHAR_NULL;
- } else { // otherwise, let's just create end state:
- constructLeaf(charIndex, groupStart);
- }
- } else {
- constructBranch(charIndex, groupStart,
- groupStart + groupCount);
- }
- groupStart += groupCount;
- }
-
- // done!
- }
-
- /**
- * Method called to add leaf entry to word set; basically
- * "here is the rest of the only matching word"
- */
- private void constructLeaf(int charIndex, int wordIndex)
- {
- String word = mWords[wordIndex];
- int len = word.length();
- char[] data = mData;
-
- // need room for 1 header char, rest of the word
- if ((mSize + len + 1) >= data.length) {
- data = expand(len+1);
- }
-
- data[mSize++] = (char) (NEGATIVE_OFFSET + (len - charIndex));
- for (; charIndex < len; ++charIndex) {
- data[mSize++] = word.charAt(charIndex);
- }
- }
-
- private char[] expand(int needSpace)
- {
- char[] old = mData;
- int len = old.length;
- int newSize = len + ((len < 4096) ? len : (len >> 1));
-
- /* Let's verify we get enough; should always be true but
- * better safe than sorry
- */
- if (newSize < (mSize + needSpace)) {
- newSize = mSize + needSpace + 64;
- }
- mData = new char[newSize];
- System.arraycopy(old, 0, mData, 0, len);
- return mData;
- }
- }
-}
diff -Nru libwoodstox-java-4.1.3/src/java/com/ctc/wstx/util/XmlChars.java libwoodstox-java-5.1.0/src/java/com/ctc/wstx/util/XmlChars.java
--- libwoodstox-java-4.1.3/src/java/com/ctc/wstx/util/XmlChars.java 2012-04-24 04:38:21.000000000 +0000
+++ libwoodstox-java-5.1.0/src/java/com/ctc/wstx/util/XmlChars.java 1970-01-01 00:00:00.000000000 +0000
@@ -1,532 +0,0 @@
-package com.ctc.wstx.util;
-
-/**
- * Simple utility class that encapsulates logic of determining validity
- * of characters outside basic 7-bit range of Unicode, for XML 1.0
- */
-public final class XmlChars
-{
- /* We don't need full 64k bits... (0x80 - 0x312C) / 32. But to
- * simplify things, let's just include first 0x80 entries in there etc
- */
- final static int SIZE = (0x3140 >> 5); // 32 bits per int
-
- final static int[] sXml10StartChars = new int[SIZE];
- static {
- SETBITS(sXml10StartChars, 0xC0, 0xD6);
- SETBITS(sXml10StartChars, 0xD8, 0xF6);
- SETBITS(sXml10StartChars, 0xF8, 0xFF);
- SETBITS(sXml10StartChars, 0x100, 0x131);
- SETBITS(sXml10StartChars, 0x134, 0x13e);
- SETBITS(sXml10StartChars, 0x141, 0x148);
- SETBITS(sXml10StartChars, 0x14a, 0x17e);
- SETBITS(sXml10StartChars, 0x180, 0x1c3);
- SETBITS(sXml10StartChars, 0x1cd, 0x1f0);
- SETBITS(sXml10StartChars, 0x1f4, 0x1f5);
- SETBITS(sXml10StartChars, 0x1fa, 0x217);
- SETBITS(sXml10StartChars, 0x250, 0x2a8);
- SETBITS(sXml10StartChars, 0x2bb, 0x2c1);
- SETBITS(sXml10StartChars, 0x386);
- SETBITS(sXml10StartChars, 0x388, 0x38a);
- SETBITS(sXml10StartChars, 0x38c);
- SETBITS(sXml10StartChars, 0x38e, 0x3a1);
- SETBITS(sXml10StartChars, 0x3a3, 0x3ce);
- SETBITS(sXml10StartChars, 0x3d0, 0x3d6);
- SETBITS(sXml10StartChars, 0x3da);
- SETBITS(sXml10StartChars, 0x3dc);
- SETBITS(sXml10StartChars, 0x3de);
- SETBITS(sXml10StartChars, 0x3e0);
- SETBITS(sXml10StartChars, 0x3e2, 0x3f3);
- SETBITS(sXml10StartChars, 0x401, 0x40c);
- SETBITS(sXml10StartChars, 0x40e, 0x44f);
- SETBITS(sXml10StartChars, 0x451, 0x45c);
- SETBITS(sXml10StartChars, 0x45e, 0x481);
- SETBITS(sXml10StartChars, 0x490, 0x4c4);
- SETBITS(sXml10StartChars, 0x4c7, 0x4c8);
- SETBITS(sXml10StartChars, 0x4cb, 0x4cc);
- SETBITS(sXml10StartChars, 0x4d0, 0x4eb);
- SETBITS(sXml10StartChars, 0x4ee, 0x4f5);
- SETBITS(sXml10StartChars, 0x4f8, 0x4f9);
-
- SETBITS(sXml10StartChars, 0x531, 0x556);
- SETBITS(sXml10StartChars, 0x559);
- SETBITS(sXml10StartChars, 0x561, 0x586);
- SETBITS(sXml10StartChars, 0x5d0, 0x5ea);
- SETBITS(sXml10StartChars, 0x5f0, 0x5f2);
- SETBITS(sXml10StartChars, 0x621, 0x63a);
- SETBITS(sXml10StartChars, 0x641, 0x64a);
- SETBITS(sXml10StartChars, 0x671, 0x6b7);
- SETBITS(sXml10StartChars, 0x6ba, 0x6be);
- SETBITS(sXml10StartChars, 0x6c0, 0x6ce);
- SETBITS(sXml10StartChars, 0x6d0, 0x6d3);
- SETBITS(sXml10StartChars, 0x6d5);
-
- SETBITS(sXml10StartChars, 0x6e5, 0x6e6);
- SETBITS(sXml10StartChars, 0x905, 0x939);
- SETBITS(sXml10StartChars, 0x93d);
- SETBITS(sXml10StartChars, 0x958, 0x961);
- SETBITS(sXml10StartChars, 0x985, 0x98c);
- SETBITS(sXml10StartChars, 0x98f, 0x990);
- SETBITS(sXml10StartChars, 0x993, 0x9a8);
- SETBITS(sXml10StartChars, 0x9aa, 0x9b0);
- SETBITS(sXml10StartChars, 0x9b2);
- SETBITS(sXml10StartChars, 0x9b6, 0x9b9);
- SETBITS(sXml10StartChars, 0x9dc);
- SETBITS(sXml10StartChars, 0x9dd);
- SETBITS(sXml10StartChars, 0x9df, 0x9e1);
- SETBITS(sXml10StartChars, 0x9f0); SETBITS(sXml10StartChars, 0x9f1);
- SETBITS(sXml10StartChars, 0xA05, 0xA0A);
- SETBITS(sXml10StartChars, 0xA0F); SETBITS(sXml10StartChars, 0xA10);
- SETBITS(sXml10StartChars, 0xA13, 0xA28);
- SETBITS(sXml10StartChars, 0xA2A, 0xA30);
- SETBITS(sXml10StartChars, 0xA32); SETBITS(sXml10StartChars, 0xA33);
- SETBITS(sXml10StartChars, 0xA35); SETBITS(sXml10StartChars, 0xA36);
- SETBITS(sXml10StartChars, 0xA38); SETBITS(sXml10StartChars, 0xA39);
- SETBITS(sXml10StartChars, 0xA59, 0xA5C);
- SETBITS(sXml10StartChars, 0xA5E);
- SETBITS(sXml10StartChars, 0xA72, 0xA74);
- SETBITS(sXml10StartChars, 0xA85, 0xA8B);
- SETBITS(sXml10StartChars, 0xA8D);
- SETBITS(sXml10StartChars, 0xA8F, 0xA91);
- SETBITS(sXml10StartChars, 0xA93, 0xAA8);
- SETBITS(sXml10StartChars, 0xAAA, 0xAB0);
- SETBITS(sXml10StartChars, 0xAB2, 0xAB3);
- SETBITS(sXml10StartChars, 0xAB5, 0xAB9);
- SETBITS(sXml10StartChars, 0xABD);
- SETBITS(sXml10StartChars, 0xAE0);
- SETBITS(sXml10StartChars, 0xB05, 0xB0C);
- SETBITS(sXml10StartChars, 0xB0F); SETBITS(sXml10StartChars, 0xB10);
- SETBITS(sXml10StartChars, 0xB13, 0xB28);
-
- SETBITS(sXml10StartChars, 0xB2A, 0xB30);
- SETBITS(sXml10StartChars, 0xB32); SETBITS(sXml10StartChars, 0xB33);
- SETBITS(sXml10StartChars, 0xB36, 0xB39);
- SETBITS(sXml10StartChars, 0xB3D);
- SETBITS(sXml10StartChars, 0xB5C); SETBITS(sXml10StartChars, 0xB5D);
- SETBITS(sXml10StartChars, 0xB5F, 0xB61);
- SETBITS(sXml10StartChars, 0xB85, 0xB8A);
- SETBITS(sXml10StartChars, 0xB8E, 0xB90);
-
- SETBITS(sXml10StartChars, 0xB92, 0xB95);
- SETBITS(sXml10StartChars, 0xB99, 0xB9A);
- SETBITS(sXml10StartChars, 0xB9C);
- SETBITS(sXml10StartChars, 0xB9E); SETBITS(sXml10StartChars, 0xB9F);
- SETBITS(sXml10StartChars, 0xBA3); SETBITS(sXml10StartChars, 0xBA4);
- SETBITS(sXml10StartChars, 0xBA8, 0xBAA);
- SETBITS(sXml10StartChars, 0xBAE, 0xBB5);
- SETBITS(sXml10StartChars, 0xBB7, 0xBB9);
- SETBITS(sXml10StartChars, 0xC05, 0xC0C);
- SETBITS(sXml10StartChars, 0xC0E, 0xC10);
-
- SETBITS(sXml10StartChars, 0xC12, 0xC28);
- SETBITS(sXml10StartChars, 0xC2A, 0xC33);
- SETBITS(sXml10StartChars, 0xC35, 0xC39);
- SETBITS(sXml10StartChars, 0xC60); SETBITS(sXml10StartChars, 0xC61);
- SETBITS(sXml10StartChars, 0xC85, 0xC8C);
- SETBITS(sXml10StartChars, 0xC8E, 0xC90);
- SETBITS(sXml10StartChars, 0xC92, 0xCA8);
- SETBITS(sXml10StartChars, 0xCAA, 0xCB3);
- SETBITS(sXml10StartChars, 0xCB5, 0xCB9);
- SETBITS(sXml10StartChars, 0xCDE);
- SETBITS(sXml10StartChars, 0xCE0); SETBITS(sXml10StartChars, 0xCE1);
- SETBITS(sXml10StartChars, 0xD05, 0xD0C);
- SETBITS(sXml10StartChars, 0xD0E, 0xD10);
- SETBITS(sXml10StartChars, 0xD12, 0xD28);
- SETBITS(sXml10StartChars, 0xD2A, 0xD39);
- SETBITS(sXml10StartChars, 0xD60); SETBITS(sXml10StartChars, 0xD61);
- SETBITS(sXml10StartChars, 0xE01, 0xE2E);
- SETBITS(sXml10StartChars, 0xE30);
- SETBITS(sXml10StartChars, 0xE32); SETBITS(sXml10StartChars, 0xE33);
- SETBITS(sXml10StartChars, 0xE40, 0xE45);
- SETBITS(sXml10StartChars, 0xE81); SETBITS(sXml10StartChars, 0xE82);
- SETBITS(sXml10StartChars, 0xE84);
- SETBITS(sXml10StartChars, 0xE87); SETBITS(sXml10StartChars, 0xE88);
- SETBITS(sXml10StartChars, 0xE8A); SETBITS(sXml10StartChars, 0xE8D);
- SETBITS(sXml10StartChars, 0xE94, 0xE97);
- SETBITS(sXml10StartChars, 0xE99, 0xE9F);
- SETBITS(sXml10StartChars, 0xEA1, 0xEA3);
- SETBITS(sXml10StartChars, 0xEA5); SETBITS(sXml10StartChars, 0xEA7);
- SETBITS(sXml10StartChars, 0xEAA); SETBITS(sXml10StartChars, 0xEAB);
- SETBITS(sXml10StartChars, 0xEAD); SETBITS(sXml10StartChars, 0xEAE);
- SETBITS(sXml10StartChars, 0xEB0);
- SETBITS(sXml10StartChars, 0xEB2); SETBITS(sXml10StartChars, 0xEB3);
- SETBITS(sXml10StartChars, 0xEBD);
-
- SETBITS(sXml10StartChars, 0xEC0, 0xEC4);
- SETBITS(sXml10StartChars, 0xF40, 0xF47);
- SETBITS(sXml10StartChars, 0xF49, 0xF69);
- SETBITS(sXml10StartChars, 0x10a0, 0x10c5);
- SETBITS(sXml10StartChars, 0x10d0, 0x10f6);
- SETBITS(sXml10StartChars, 0x1100);
- SETBITS(sXml10StartChars, 0x1102, 0x1103);
- SETBITS(sXml10StartChars, 0x1105, 0x1107);
- SETBITS(sXml10StartChars, 0x1109);
- SETBITS(sXml10StartChars, 0x110b, 0x110c);
- SETBITS(sXml10StartChars, 0x110e, 0x1112);
- SETBITS(sXml10StartChars, 0x113c);
- SETBITS(sXml10StartChars, 0x113e);
- SETBITS(sXml10StartChars, 0x1140);
- SETBITS(sXml10StartChars, 0x114c);
- SETBITS(sXml10StartChars, 0x114e);
- SETBITS(sXml10StartChars, 0x1150);
- SETBITS(sXml10StartChars, 0x1154, 0x1155);
- SETBITS(sXml10StartChars, 0x1159);
- SETBITS(sXml10StartChars, 0x115f, 0x1161);
- SETBITS(sXml10StartChars, 0x1163);
- SETBITS(sXml10StartChars, 0x1165);
- SETBITS(sXml10StartChars, 0x1167);
- SETBITS(sXml10StartChars, 0x1169);
- SETBITS(sXml10StartChars, 0x116d, 0x116e);
- SETBITS(sXml10StartChars, 0x1172, 0x1173);
- SETBITS(sXml10StartChars, 0x1175);
- SETBITS(sXml10StartChars, 0x119e);
- SETBITS(sXml10StartChars, 0x11a8);
- SETBITS(sXml10StartChars, 0x11ab);
- SETBITS(sXml10StartChars, 0x11ae, 0x11af);
- SETBITS(sXml10StartChars, 0x11b7, 0x11b8);
- SETBITS(sXml10StartChars, 0x11ba);
- SETBITS(sXml10StartChars, 0x11bc, 0x11c2);
- SETBITS(sXml10StartChars, 0x11eb);
- SETBITS(sXml10StartChars, 0x11f0);
- SETBITS(sXml10StartChars, 0x11f9);
- SETBITS(sXml10StartChars, 0x1e00, 0x1e9b);
- SETBITS(sXml10StartChars, 0x1ea0, 0x1ef9);
- SETBITS(sXml10StartChars, 0x1f00, 0x1f15);
- SETBITS(sXml10StartChars, 0x1f18, 0x1f1d);
- SETBITS(sXml10StartChars, 0x1f20, 0x1f45);
- SETBITS(sXml10StartChars, 0x1f48, 0x1f4d);
- SETBITS(sXml10StartChars, 0x1f50, 0x1f57);
- SETBITS(sXml10StartChars, 0x1f59);
- SETBITS(sXml10StartChars, 0x1f5b);
- SETBITS(sXml10StartChars, 0x1f5d);
- SETBITS(sXml10StartChars, 0x1f5f, 0x1f7d);
- SETBITS(sXml10StartChars, 0x1f80, 0x1fb4);
- SETBITS(sXml10StartChars, 0x1fb6, 0x1fbc);
- SETBITS(sXml10StartChars, 0x1fbe);
- SETBITS(sXml10StartChars, 0x1fc2, 0x1fc4);
- SETBITS(sXml10StartChars, 0x1fc6, 0x1fcc);
- SETBITS(sXml10StartChars, 0x1fd0, 0x1fd3);
- SETBITS(sXml10StartChars, 0x1fd6, 0x1fdb);
- SETBITS(sXml10StartChars, 0x1fe0, 0x1fec);
- SETBITS(sXml10StartChars, 0x1ff2, 0x1ff4);
- SETBITS(sXml10StartChars, 0x1ff6, 0x1ffc);
- SETBITS(sXml10StartChars, 0x2126);
- SETBITS(sXml10StartChars, 0x212a, 0x212b);
- SETBITS(sXml10StartChars, 0x212e);
- SETBITS(sXml10StartChars, 0x2180, 0x2182);
- SETBITS(sXml10StartChars, 0x3041, 0x3094);
- SETBITS(sXml10StartChars, 0x30a1, 0x30fa);
- SETBITS(sXml10StartChars, 0x3105, 0x312c);
- // note: AC00 - D7A3 handled separately
-
- // [86] Ideographic (but note: > 0x312c handled separately)
- SETBITS(sXml10StartChars, 0x3007);
- SETBITS(sXml10StartChars, 0x3021, 0x3029);
- }
-
- final static int[] sXml10Chars = new int[SIZE];
- static {
- // Let's start with all valid start chars:
- System.arraycopy(sXml10StartChars, 0, sXml10Chars, 0, SIZE);
-
- // [87] CombiningChar ::=
- SETBITS(sXml10Chars, 0x300, 0x345);
- SETBITS(sXml10Chars, 0x360, 0x361);
- SETBITS(sXml10Chars, 0x483, 0x486);
- SETBITS(sXml10Chars, 0x591, 0x5a1);
- SETBITS(sXml10Chars, 0x5a3, 0x5b9);
- SETBITS(sXml10Chars, 0x5bb, 0x5bd);
- SETBITS(sXml10Chars, 0x5bf);
-
- SETBITS(sXml10Chars, 0x5c1, 0x5c2);
- SETBITS(sXml10Chars, 0x5c4);
- SETBITS(sXml10Chars, 0x64b, 0x652);
- SETBITS(sXml10Chars, 0x670);
- SETBITS(sXml10Chars, 0x6d6, 0x6dc);
- SETBITS(sXml10Chars, 0x6dd, 0x6df);
- SETBITS(sXml10Chars, 0x6e0, 0x6e4);
- SETBITS(sXml10Chars, 0x6e7, 0x6e8);
- SETBITS(sXml10Chars, 0x6ea, 0x6ed);
-
- SETBITS(sXml10Chars, 0x901, 0x903);
- SETBITS(sXml10Chars, 0x93c);
- SETBITS(sXml10Chars, 0x93e, 0x94c);
- SETBITS(sXml10Chars, 0x94d);
- SETBITS(sXml10Chars, 0x951, 0x954);
- SETBITS(sXml10Chars, 0x962); SETBITS(sXml10Chars, 0x963);
- SETBITS(sXml10Chars, 0x981, 0x983);
- SETBITS(sXml10Chars, 0x9bc);
- SETBITS(sXml10Chars, 0x9be); SETBITS(sXml10Chars, 0x9bf);
- SETBITS(sXml10Chars, 0x9c0, 0x9c4);
- SETBITS(sXml10Chars, 0x9c7); SETBITS(sXml10Chars, 0x9c8);
- SETBITS(sXml10Chars, 0x9cb, 0x9cd);
- SETBITS(sXml10Chars, 0x9d7);
- SETBITS(sXml10Chars, 0x9e2); SETBITS(sXml10Chars, 0x9e3);
- SETBITS(sXml10Chars, 0xA02);
- SETBITS(sXml10Chars, 0xA3C);
- SETBITS(sXml10Chars, 0xA3E); SETBITS(sXml10Chars, 0xA3F);
- SETBITS(sXml10Chars, 0xA40, 0xA42);
- SETBITS(sXml10Chars, 0xA47); SETBITS(sXml10Chars, 0xA48);
- SETBITS(sXml10Chars, 0xA4B, 0xA4D);
- SETBITS(sXml10Chars, 0xA70); SETBITS(sXml10Chars, 0xA71);
- SETBITS(sXml10Chars, 0xA81, 0xA83);
- SETBITS(sXml10Chars, 0xABC);
- SETBITS(sXml10Chars, 0xABE, 0xAC5);
- SETBITS(sXml10Chars, 0xAC7, 0xAC9);
- SETBITS(sXml10Chars, 0xACB, 0xACD);
- SETBITS(sXml10Chars, 0xB01, 0xB03);
- SETBITS(sXml10Chars, 0xB3C);
- SETBITS(sXml10Chars, 0xB3E, 0xB43);
- SETBITS(sXml10Chars, 0xB47); SETBITS(sXml10Chars, 0xB48);
- SETBITS(sXml10Chars, 0xB4B, 0xB4D);
- SETBITS(sXml10Chars, 0xB56); SETBITS(sXml10Chars, 0xB57);
- SETBITS(sXml10Chars, 0xB82); SETBITS(sXml10Chars, 0xB83);
- SETBITS(sXml10Chars, 0xBBE, 0xBC2);
- SETBITS(sXml10Chars, 0xBC6, 0xBC8);
- SETBITS(sXml10Chars, 0xBCA, 0xBCD);
- SETBITS(sXml10Chars, 0xBD7);
- SETBITS(sXml10Chars, 0xC01, 0xC03);
- SETBITS(sXml10Chars, 0xC3E, 0xC44);
- SETBITS(sXml10Chars, 0xC46, 0xC48);
- SETBITS(sXml10Chars, 0xC4A, 0xC4D);
- SETBITS(sXml10Chars, 0xC55, 0xC56);
- SETBITS(sXml10Chars, 0xC82, 0xC83);
- SETBITS(sXml10Chars, 0xCBE, 0xCC4);
- SETBITS(sXml10Chars, 0xCC6, 0xCC8);
- SETBITS(sXml10Chars, 0xCCA, 0xCCD);
- SETBITS(sXml10Chars, 0xCD5, 0xCD6);
- SETBITS(sXml10Chars, 0xD02, 0xD03);
- SETBITS(sXml10Chars, 0xD3E, 0xD43);
- SETBITS(sXml10Chars, 0xD46, 0xD48);
- SETBITS(sXml10Chars, 0xD4A, 0xD4D);
- SETBITS(sXml10Chars, 0xD57);
- SETBITS(sXml10Chars, 0xE31);
- SETBITS(sXml10Chars, 0xE34, 0xE3A);
- SETBITS(sXml10Chars, 0xE47, 0xE4E);
- SETBITS(sXml10Chars, 0xEB1);
- SETBITS(sXml10Chars, 0xEB4, 0xEB9);
- SETBITS(sXml10Chars, 0xEBB, 0xEBC);
- SETBITS(sXml10Chars, 0xEC8, 0xECD);
- SETBITS(sXml10Chars, 0xF18, 0xF19);
- SETBITS(sXml10Chars, 0xF35); SETBITS(sXml10Chars, 0xF37);
- SETBITS(sXml10Chars, 0xF39);
- SETBITS(sXml10Chars, 0xF3E); SETBITS(sXml10Chars, 0xF3F);
- SETBITS(sXml10Chars, 0xF71, 0xF84);
- SETBITS(sXml10Chars, 0xF86, 0xF8B);
- SETBITS(sXml10Chars, 0xF90, 0xF95);
- SETBITS(sXml10Chars, 0xF97);
- SETBITS(sXml10Chars, 0xF99, 0xFAD);
- SETBITS(sXml10Chars, 0xFB1, 0xFB7);
- SETBITS(sXml10Chars, 0xFB9);
- SETBITS(sXml10Chars, 0x20D0, 0x20DC);
- SETBITS(sXml10Chars, 0x20E1);
- SETBITS(sXml10Chars, 0x302A, 0x302F);
- SETBITS(sXml10Chars, 0x3099); SETBITS(sXml10Chars, 0x309A);
- // [88] Digit:
- SETBITS(sXml10Chars, 0x660, 0x669);
- SETBITS(sXml10Chars, 0x6f0, 0x6f9);
- SETBITS(sXml10Chars, 0x966, 0x96f);
- SETBITS(sXml10Chars, 0x9e6, 0x9ef);
- SETBITS(sXml10Chars, 0xa66, 0xa6f);
- SETBITS(sXml10Chars, 0xae6, 0xaef);
- SETBITS(sXml10Chars, 0xb66, 0xb6f);
- SETBITS(sXml10Chars, 0xbe7, 0xbef);
- SETBITS(sXml10Chars, 0xc66, 0xc6f);
- SETBITS(sXml10Chars, 0xce6, 0xcef);
- SETBITS(sXml10Chars, 0xd66, 0xd6f);
- SETBITS(sXml10Chars, 0xe50, 0xe59);
- SETBITS(sXml10Chars, 0xed0, 0xed9);
- SETBITS(sXml10Chars, 0xf20, 0xf29);
-
- // [89] Extender:
- SETBITS(sXml10Chars, 0xb7);
- SETBITS(sXml10Chars, 0x2d0);
- SETBITS(sXml10Chars, 0x2d1);
- SETBITS(sXml10Chars, 0x387);
- SETBITS(sXml10Chars, 0x640);
- SETBITS(sXml10Chars, 0xE46);
- SETBITS(sXml10Chars, 0xEC6);
- SETBITS(sXml10Chars, 0x3005);
- SETBITS(sXml10Chars, 0x3031, 0x3035);
- SETBITS(sXml10Chars, 0x309d, 0x309e);
- SETBITS(sXml10Chars, 0x30fc, 0x30fe);
- }
-
- private XmlChars() { }
-
- public final static boolean is10NameStartChar(char c)
- {
- // First, let's deal with outliers
- if (c > 0x312C) { // Most valid chars are below this..
- if (c < 0xAC00) {
- return (c >= 0x4E00 && c <= 0x9FA5); // valid ideograms
- }
- if (c <= 0xD7A3) { // 0xAC00 - 0xD7A3, valid base chars
- return true;
- }
- /* As to surrogate pairs... let's do the bare minimum;
- * 0xD800 - 0xDBFF (high surrogate) are ok; low surrogates
- * can only follow high one
- */
- return (c <= 0xDBFF && c >= 0xD800);
- }
- // but then we'll just need to use the table...
- int ix = (int) c;
- return (sXml10StartChars[ix >> 5] & (1 << (ix & 31))) != 0;
- }
-
- public final static boolean is10NameChar(char c)
- {
- // First, let's deal with outliers
- if (c > 0x312C) { // Most valid chars are below this..
- if (c < 0xAC00) {
- return (c >= 0x4E00 && c <= 0x9FA5); // valid ideograms
- }
- if (c <= 0xD7A3) { // 0xAC00 - 0xD7A3, valid base chars
- return true;
- }
- /* As to surrogate pairs... let's do the bare minimum;
- * 0xD800 - 0xDFFF (high, low surrogate) are ok (need to
- * check pairing in future)
- */
- return (c >= 0xD800 && c <= 0xDFFF);
- }
- // but then we'll just need to use the table...
- int ix = (int) c;
- return (sXml10Chars[ix >> 5] & (1 << (ix & 31))) != 0;
- }
-
- public final static boolean is11NameStartChar(char c)
- {
- // Others are checked block-by-block:
- if (c <= 0x2FEF) {
- if (c < 0x300) {
- if (c < 0x00C0) { // 8-bit ctrl chars
- return false;
- }
- // most of the rest are fine...
- return (c != 0xD7 && c != 0xF7);
- }
- if (c >= 0x2C00) {
- // 0x2C00 - 0x2FEF are ok
- return true;
- }
- if (c < 0x370 || c > 0x218F) {
- // 0x300 - 0x36F, 0x2190 - 0x2BFF invalid
- return false;
- }
- if (c < 0x2000) {
- // 0x370 - 0x37D, 0x37F - 0x1FFF are ok
- return (c != 0x37E);
- }
- if (c >= 0x2070) {
- // 0x2070 - 0x218F are ok
- return (c <= 0x218F);
- }
- // And finally, 0x200C - 0x200D
- return (c == 0x200C || c == 0x200D);
- }
-
- // 0x3000 and above:
- if (c >= 0x3001) {
- /* Hmmh, let's allow high surrogates here, without checking
- * that they are properly followed... crude basic support,
- * I know, but allows valid combinations, just doesn't catch
- * invalid ones
- */
- if (c <= 0xDBFF) { // 0x3001 - 0xD7FF (chars),
- // 0xD800 - 0xDBFF (high surrogate) are ok (unlike DC00-DFFF)
- return true;
- }
- if (c >= 0xF900 && c <= 0xFFFD) {
- /* Check above removes low surrogate (since one can not
- * START an identifier), and byte-order markers..
- */
- return (c <= 0xFDCF || c >= 0xFDF0);
- }
- }
-
- return false;
- }
-
- public final static boolean is11NameChar(char c)
- {
- // Others are checked block-by-block:
- if (c <= 0x2FEF) {
- if (c < 0x2000) { // only 8-bit ctrl chars and 0x37E to filter out
- return (c >= 0x00C0 && c != 0x37E) || (c == 0xB7);
- }
- if (c >= 0x2C00) {
- // 0x100 - 0x1FFF, 0x2C00 - 0x2FEF are ok
- return true;
- }
- if (c < 0x200C || c > 0x218F) {
- // 0x2000 - 0x200B, 0x2190 - 0x2BFF invalid
- return false;
- }
- if (c >= 0x2070) {
- // 0x2070 - 0x218F are ok
- return true;
- }
- // And finally, 0x200C - 0x200D, 0x203F - 0x2040 are ok
- return (c == 0x200C || c == 0x200D
- || c == 0x203F || c == 0x2040);
- }
-
- // 0x3000 and above:
- if (c >= 0x3001) {
- /* Hmmh, let's allow surrogate heres, without checking that
- * they have proper ordering. For non-first name chars, both are
- * ok, for valid names. Crude basic support,
- * I know, but allows valid combinations, just doesn't catch
- * invalid ones
- */
- if (c <= 0xDFFF) { // 0x3001 - 0xD7FF (chars),
- // 0xD800 - 0xDFFF (high, low surrogate) are ok:
- return true;
- }
- if (c >= 0xF900 && c <= 0xFFFD) {
- /* Check above removes other invalid chars (below valid
- * range), and byte-order markers (0xFFFE, 0xFFFF).
- */
- return (c <= 0xFDCF || c >= 0xFDF0);
- }
- }
-
- return false;
- }
-
- private static void SETBITS(int[] array, int start, int end)
- {
- int bit1 = (start & 31);
- int bit2 = (end & 31);
- start >>= 5;
- end >>= 5;
-
- /* Ok; this is not perfectly optimal, but should be good enough...
- * we'll only do one-by-one at the ends.
- */
- if (start == end) {
- for (; bit1 <= bit2; ++bit1) {
- array[start] |= (1 << bit1);
- }
- } else {
- for (int bit = bit1; bit <= 31; ++bit) {
- array[start] |= (1 << bit);
- }
- while (++start < end) {
- array[start] = -1;
- }
- for (int bit = 0; bit <= bit2; ++bit) {
- array[end] |= (1 << bit);
- }
- }
- }
-
- private static void SETBITS(int[] array, int point) {
- int ix = (point >> 5);
- int bit = (point & 31);
-
- array[ix] |= (1 << bit);
- }
-}
diff -Nru libwoodstox-java-4.1.3/src/java/org/codehaus/stax2/ri/package.html libwoodstox-java-5.1.0/src/java/org/codehaus/stax2/ri/package.html
--- libwoodstox-java-4.1.3/src/java/org/codehaus/stax2/ri/package.html 2012-04-24 04:38:21.000000000 +0000
+++ libwoodstox-java-5.1.0/src/java/org/codehaus/stax2/ri/package.html 1970-01-01 00:00:00.000000000 +0000
@@ -1,5 +0,0 @@
-
-Package that contains a skeletal reference implementation of Stax2 API,
-as well as some utility/helper classes that can be useful in building
-one.
-
diff -Nru libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/api/CommonConfig.java libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/api/CommonConfig.java
--- libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/api/CommonConfig.java 1970-01-01 00:00:00.000000000 +0000
+++ libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/api/CommonConfig.java 2018-03-31 01:33:28.000000000 +0000
@@ -0,0 +1,282 @@
+package com.ctc.wstx.api;
+
+import java.util.*;
+
+import org.codehaus.stax2.XMLStreamProperties;
+
+import com.ctc.wstx.util.ArgUtil;
+
+/**
+ * Shared common base class for variour configuration container implementations
+ * for public factories Woodstox uses: implementations of
+ * {@link javax.xml.stream.XMLInputFactory},
+ * {@link javax.xml.stream.XMLOutputFactory} and
+ * {@link org.codehaus.stax2.validation.XMLValidationSchemaFactory}.
+ * Implements basic settings for some shared settings, defined by the
+ * shared property interface {@link XMLStreamProperties}.
+ */
+abstract class CommonConfig
+ implements XMLStreamProperties
+{
+ /*
+ ///////////////////////////////////////////////////////////////////////
+ // Implementation info
+ ///////////////////////////////////////////////////////////////////////
+ */
+
+ protected final static String IMPL_NAME = "woodstox";
+
+ /* !!! TBI: get from props file or so? Or build as part of Ant
+ * build process?
+ */
+ /**
+ * This is "major.minor" version used for purposes of determining
+ * the feature set. Patch level is not included, since those should
+ * not affect API or feature set. Using applications should be
+ * prepared to take additional levels, however, just not depend
+ * on those being available.
+ */
+ protected final static String IMPL_VERSION = "5.0";
+
+ /*
+ ///////////////////////////////////////////////////////////////////////
+ // Internal constants
+ ///////////////////////////////////////////////////////////////////////
+ */
+
+ final static int CPROP_IMPL_NAME = 1;
+ final static int CPROP_IMPL_VERSION = 2;
+
+ final static int CPROP_SUPPORTS_XML11 = 3;
+ final static int CPROP_SUPPORT_XMLID = 4;
+
+ final static int CPROP_RETURN_NULL_FOR_DEFAULT_NAMESPACE = 5;
+
+ /**
+ * Map to use for converting from String property ids to enumeration
+ * (ints). Used for faster dispatching.
+ */
+ final static HashMap sStdProperties = new HashMap(16);
+ static {
+ // Basic information about the implementation:
+ sStdProperties.put(XMLStreamProperties.XSP_IMPLEMENTATION_NAME, CPROP_IMPL_NAME);
+ sStdProperties.put(XMLStreamProperties.XSP_IMPLEMENTATION_VERSION, CPROP_IMPL_VERSION);
+
+ // XML version support:
+ sStdProperties.put(XMLStreamProperties.XSP_SUPPORTS_XML11, CPROP_SUPPORTS_XML11);
+
+ // Xml:id support:
+ sStdProperties.put(XMLStreamProperties.XSP_SUPPORT_XMLID, CPROP_SUPPORT_XMLID);
+
+ sStdProperties.put(WstxInputProperties.P_RETURN_NULL_FOR_DEFAULT_NAMESPACE,
+ CPROP_RETURN_NULL_FOR_DEFAULT_NAMESPACE);
+
+ /* 23-Apr-2008, tatus: Additional interoperability property,
+ * one that Sun implementation uses. Can map to Stax2
+ * property quite easily.
+ */
+ sStdProperties.put("http://java.sun.com/xml/stream/properties/implementation-name",
+ CPROP_IMPL_NAME);
+ }
+
+ /*
+ ///////////////////////////////////////////////////////////////////////
+ // Shared config
+ ///////////////////////////////////////////////////////////////////////
+ */
+
+ /**
+ * As per [WSTX-277], can specify whether prefix for the
+ * "default namespace" is return as null (true) or empty String (false)
+ */
+ protected boolean mReturnNullForDefaultNamespace;
+
+ /*
+ ///////////////////////////////////////////////////////////////////////
+ // Construction
+ ///////////////////////////////////////////////////////////////////////
+ */
+
+ /**
+ * Constructor used by sub-classes
+ *
+ * @param base Base instance to copy settings from, if any; null for
+ * 'root' configuration objects.
+ */
+ protected CommonConfig(CommonConfig base) {
+ mReturnNullForDefaultNamespace = (base == null)
+ /* 27-Mar-2018, tatu: What the hell... why does it take it from System properties?
+ * I should have done better code review; Woodstox should not do that.
+ * System properties are evil for shared libraries, not to be used.
+ */
+ ? Boolean.getBoolean(WstxInputProperties.P_RETURN_NULL_FOR_DEFAULT_NAMESPACE)
+ : base.mReturnNullForDefaultNamespace;
+ }
+
+ /*
+ ///////////////////////////////////////////////////////////////////////
+ // Public API, generic StAX config methods
+ ///////////////////////////////////////////////////////////////////////
+ */
+
+ public Object getProperty(String propName)
+ {
+ /* Related to [WSTX-243]; would be nice to not to have to throw an
+ * exception; but Stax spec suggests that we do need to indicate
+ * unrecognized property by exception.
+ */
+ int id = findPropertyId(propName);
+ if (id >= 0) {
+ return getProperty(id);
+ }
+ id = findStdPropertyId(propName);
+ if (id < 0) {
+ reportUnknownProperty(propName);
+ return null;
+ }
+ return getStdProperty(id);
+ }
+
+ public boolean isPropertySupported(String propName)
+ {
+ return (findPropertyId(propName) >= 0)
+ || (findStdPropertyId(propName) >= 0);
+ }
+
+ /**
+ * @return True, if the specified property was successfully
+ * set to specified value; false if its value was not changed
+ */
+ public boolean setProperty(String propName, Object value)
+ {
+ int id = findPropertyId(propName);
+ if (id >= 0) {
+ return setProperty(propName, id, value);
+ }
+ id = findStdPropertyId(propName);
+ if (id < 0) {
+ reportUnknownProperty(propName);
+ return false;
+ }
+ return setStdProperty(propName, id, value);
+ }
+
+ protected void reportUnknownProperty(String propName)
+ {
+ // see [WSTX-243] for discussion on whether to throw...
+ throw new IllegalArgumentException("Unrecognized property '"+propName+"'");
+ }
+
+ /*
+ ///////////////////////////////////////////////////////////////////////
+ // Additional methods used by Woodstox core
+ ///////////////////////////////////////////////////////////////////////
+ */
+
+ public final Object safeGetProperty(String propName)
+ {
+ int id = findPropertyId(propName);
+ if (id >= 0) {
+ return getProperty(id);
+ }
+ id = findStdPropertyId(propName);
+ if (id < 0) {
+ return null;
+ }
+ return getStdProperty(id);
+ }
+
+ /**
+ * Method used to figure out the official implementation name
+ * for input/output/validation factories.
+ */
+ public static String getImplName() { return IMPL_NAME; }
+
+ /**
+ * Method used to figure out the official implementation version
+ * for input/output/validation factories.
+ */
+ public static String getImplVersion() { return IMPL_VERSION; }
+
+ /*
+ ///////////////////////////////////////////////////////////////////////
+ // Interface sub-classes have to implement / can override
+ ///////////////////////////////////////////////////////////////////////
+ */
+
+ /**
+ * @return Internal enumerated int matching the String name
+ * of the property, if one found: -1 to indicate no match
+ * was found.
+ */
+ protected abstract int findPropertyId(String propName);
+
+ public boolean doesSupportXml11() {
+ /* Woodstox does support xml 1.1 ... but sub-classes can
+ * override it if/as necessary (validator factories might not
+ * support it?)
+ */
+ return true;
+ }
+
+ public boolean doesSupportXmlId() {
+ /* Woodstox does support Xml:id ... but sub-classes can
+ * override it if/as necessary.
+ */
+ return true;
+ }
+
+ public boolean returnNullForDefaultNamespace() {
+ return mReturnNullForDefaultNamespace;
+ }
+
+ protected abstract Object getProperty(int id);
+
+ protected abstract boolean setProperty(String propName, int id, Object value);
+
+ /*
+ ///////////////////////////////////////////////////////////////////////
+ // Internal methods
+ ///////////////////////////////////////////////////////////////////////
+ */
+
+ protected int findStdPropertyId(String propName)
+ {
+ Integer I = sStdProperties.get(propName);
+ return (I == null) ? -1 : I.intValue();
+ }
+
+ /**
+ * @param propName Name of standard property to set
+ * @param id Internal id matching the name
+ * @param value Value to set the standard property to
+ */
+ protected boolean setStdProperty(String propName, int id, Object value)
+ {
+ // Only one settable property...
+ switch (id) {
+ case CPROP_RETURN_NULL_FOR_DEFAULT_NAMESPACE:
+ mReturnNullForDefaultNamespace = ArgUtil.convertToBoolean(propName, value);
+ return true;
+ }
+ return false;
+ }
+
+ protected Object getStdProperty(int id)
+ {
+ switch (id) {
+ case CPROP_IMPL_NAME:
+ return IMPL_NAME;
+ case CPROP_IMPL_VERSION:
+ return IMPL_VERSION;
+ case CPROP_SUPPORTS_XML11:
+ return doesSupportXml11() ? Boolean.TRUE : Boolean.FALSE;
+ case CPROP_SUPPORT_XMLID:
+ return doesSupportXmlId() ? Boolean.TRUE : Boolean.FALSE;
+ case CPROP_RETURN_NULL_FOR_DEFAULT_NAMESPACE:
+ return returnNullForDefaultNamespace() ? Boolean.TRUE : Boolean.FALSE;
+ default: // sanity check, should never happen
+ throw new IllegalStateException("Internal error: no handler for property with internal id "+id+".");
+ }
+ }
+}
diff -Nru libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/api/EmptyElementHandler.java libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/api/EmptyElementHandler.java
--- libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/api/EmptyElementHandler.java 1970-01-01 00:00:00.000000000 +0000
+++ libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/api/EmptyElementHandler.java 2018-03-31 01:33:28.000000000 +0000
@@ -0,0 +1,82 @@
+package com.ctc.wstx.api;
+
+import java.util.Set;
+import java.util.TreeSet;
+
+/**
+ * Optional handler used to determine if a specific empty element (by name) should
+ * be allowed to use the self-closing syntax instead of having a separate end tag.
+ *
+ * @since 4.1
+ */
+public interface EmptyElementHandler
+{
+ /**
+ * @param prefix The element's namespace prefix, null if not set
+ * @param localName The element's local name
+ * @param nsURI The elements's namespace URI, null if not set
+ * @param allowEmpty The allow empty setting specified by the caller.
+ * @return True if the empty element can be self-closing. False if a separate end tag should be written.
+ */
+ public boolean allowEmptyElement(String prefix, String localName, String nsURI, boolean allowEmpty);
+
+ /**
+ * Handler that uses a Set of Strings. If the local part of the element's QName is contained
+ * in the Set the element is allowed to be empty.
+ *
+ * Users of this class are encouraged to use a {@link TreeSet} with the {@link String#CASE_INSENSITIVE_ORDER}
+ * comparator if case-insensitive comparison is needed (like when dealing with HTML tags).
+ */
+ public static class SetEmptyElementHandler
+ implements EmptyElementHandler
+ {
+ final protected Set mEmptyElements;
+
+ public SetEmptyElementHandler(Set emptyElements)
+ {
+ mEmptyElements = emptyElements;
+ }
+
+ @Override
+ public boolean allowEmptyElement(String prefix, String localName, String nsURI, boolean allowEmpty)
+ {
+ return mEmptyElements.contains(localName);
+ }
+ }
+
+ /**
+ * HTML specific empty element handler.
+ * Extends the {@link SetEmptyElementHandler} and configures
+ * the HTML elements that must be self-closing according to the W3C:
+ * http://www.w3.org/TR/html4/index/elements.html
+ *
+ * Note that element name comparison is case-insensitive as required
+ * by HTML specification.
+ */
+ public static class HtmlEmptyElementHandler
+ extends SetEmptyElementHandler
+ {
+ private final static HtmlEmptyElementHandler sInstance = new HtmlEmptyElementHandler();
+
+ public static HtmlEmptyElementHandler getInstance() { return sInstance; }
+
+ protected HtmlEmptyElementHandler()
+ {
+ super(new TreeSet(String.CASE_INSENSITIVE_ORDER));
+ mEmptyElements.add("area");
+ mEmptyElements.add("base");
+ mEmptyElements.add("basefont");
+ mEmptyElements.add("br");
+ mEmptyElements.add("col");
+ mEmptyElements.add("frame");
+ mEmptyElements.add("hr");
+ mEmptyElements.add("input");
+ mEmptyElements.add("img");
+ mEmptyElements.add("isindex");
+ mEmptyElements.add("link");
+ mEmptyElements.add("meta");
+ mEmptyElements.add("param");
+ }
+ }
+}
+
diff -Nru libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/api/InvalidCharHandler.java libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/api/InvalidCharHandler.java
--- libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/api/InvalidCharHandler.java 1970-01-01 00:00:00.000000000 +0000
+++ libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/api/InvalidCharHandler.java 2018-03-31 01:33:28.000000000 +0000
@@ -0,0 +1,91 @@
+package com.ctc.wstx.api;
+
+import java.io.IOException;
+
+/**
+ * Simple converter interface designed to be used with stream writer property
+ * {@link WstxOutputProperties#P_OUTPUT_INVALID_CHAR_HANDLER}.
+ * The idea is that it should be easy to have a way to convert invalid
+ * characters such as Ascii control characters into something that
+ * is legal to include in XML content. This only allows for simple
+ * char-by-char replacements, instead of something more advanced such
+ * as escaping. If escaping is needed, check out
+ * {@link org.codehaus.stax2.XMLOutputFactory2#P_TEXT_ESCAPER} instead.
+ *
+ * Note about exceptions: choice of only allowing throwing of
+ * {@link IOException}s is due to the way Woodstox stream writer
+ * backend works; XmlWriter
can only throw IOExceptions.
+ */
+public interface InvalidCharHandler
+{
+ public char convertInvalidChar(int invalidChar) throws IOException;
+
+ /**
+ * This handler implementation just throws an exception for
+ * all invalid characters encountered. It is the default handler
+ * used if nothing else has been specified.
+ */
+ public static class FailingHandler
+ implements InvalidCharHandler
+ {
+ public final static int SURR1_FIRST = 0xD800;
+ public final static int SURR1_LAST = 0xDBFF;
+ public final static int SURR2_FIRST = 0xDC00;
+ public final static int SURR2_LAST = 0xDFFF;
+
+ private final static FailingHandler sInstance = new FailingHandler();
+
+ protected FailingHandler() { }
+
+ public static FailingHandler getInstance() { return sInstance; }
+
+ @Override
+ public char convertInvalidChar(int c) throws IOException
+ {
+ /* 17-May-2006, TSa: Would really be useful if we could throw
+ * XMLStreamExceptions; esp. to indicate actual output location.
+ * However, this causes problem with methods that call us and
+ * can only throw IOExceptions (when invoked via Writer proxy).
+ * Need to figure out how to resolve this.
+ */
+ if (c == 0) {
+ throw new IOException("Invalid null character in text to output");
+ }
+ if (c < ' ' || (c >= 0x7F && c <= 0x9F)) {
+ String msg = "Invalid white space character (0x"+Integer.toHexString(c)+") in text to output (in xml 1.1, could output as a character entity)";
+ throw new IOException(msg);
+ }
+ if (c > 0x10FFFF) {
+ throw new IOException("Illegal unicode character point (0x"+Integer.toHexString(c)+") to output; max is 0x10FFFF as per RFC 3629");
+ }
+ /* Surrogate pair in non-quotable (not text or attribute value)
+ * content, and non-unicode encoding (ISO-8859-x, Ascii)?
+ */
+ if (c >= SURR1_FIRST && c <= SURR2_LAST) {
+ throw new IOException("Illegal surrogate pair -- can only be output via character entities, which are not allowed in this content");
+ }
+ throw new IOException("Invalid XML character (0x"+Integer.toHexString(c)+") in text to output");
+ }
+ }
+
+ /**
+ * Alternative to the default handler, this handler converts all invalid
+ * characters to the specified output character. That character will
+ * not be further verified or modified by the stream writer.
+ */
+ public static class ReplacingHandler
+ implements InvalidCharHandler
+ {
+ final char mReplacementChar;
+
+ public ReplacingHandler(char c) {
+ mReplacementChar = c;
+ }
+
+ @Override
+ public char convertInvalidChar(int c) throws IOException {
+ return mReplacementChar;
+ }
+ }
+}
+
diff -Nru libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/api/package.html libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/api/package.html
--- libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/api/package.html 1970-01-01 00:00:00.000000000 +0000
+++ libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/api/package.html 2018-03-31 01:33:28.000000000 +0000
@@ -0,0 +1,7 @@
+
+Package that contains subset of Woodstox classes that are considered to be
+its public API (in addition to regular Stax 1.0 -- javax.xml.stream.* -- and
+Stax2 -- org.codehaus.stax2.*). This means that application code can rely
+on these classes, and effort is made to keep them backwards compatible
+between releases.
+
diff -Nru libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/api/ReaderConfig.java libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/api/ReaderConfig.java
--- libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/api/ReaderConfig.java 1970-01-01 00:00:00.000000000 +0000
+++ libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/api/ReaderConfig.java 2018-03-31 01:33:28.000000000 +0000
@@ -0,0 +1,1696 @@
+package com.ctc.wstx.api;
+
+import java.lang.ref.SoftReference;
+import java.net.URL;
+import java.util.*;
+
+import javax.xml.stream.*;
+
+import org.codehaus.stax2.XMLInputFactory2; // for property consts
+import org.codehaus.stax2.XMLStreamProperties; // for property consts
+import org.codehaus.stax2.validation.DTDValidationSchema;
+
+import com.ctc.wstx.api.WstxInputProperties;
+import com.ctc.wstx.cfg.InputConfigFlags;
+import com.ctc.wstx.dtd.DTDEventListener;
+import com.ctc.wstx.ent.IntEntity;
+import com.ctc.wstx.ent.EntityDecl;
+import com.ctc.wstx.io.BufferRecycler;
+import com.ctc.wstx.util.ArgUtil;
+import com.ctc.wstx.util.DataUtil;
+import com.ctc.wstx.util.SymbolTable;
+
+/**
+ * Simple configuration container class; passed by reader factory to reader
+ * instance created.
+ *
+ * In addition to its main task as a configuration container, this class
+ * also acts as a wrapper around simple buffer recycling functionality.
+ * The reason is that while conceptually this is a separate concern,
+ * there are enough commonalities with the life-cycle of this object to
+ * make this a very convenience place to add that functionality...
+ * (that is: conceptually this is not right, but from pragmatic viewpoint
+ * it just makes sense)
+ */
+public final class ReaderConfig
+ extends CommonConfig
+ implements InputConfigFlags
+{
+ // Default limit values
+
+ public final static int DEFAULT_MAX_ATTRIBUTES_PER_ELEMENT = 1000;
+ public final static int DEFAULT_MAX_ATTRIBUTE_LENGTH = 65536 * 8;
+
+ public final static int DEFAULT_MAX_ELEMENT_DEPTH = 1000;
+
+ public final static int DEFAULT_MAX_ENTITY_DEPTH = 500;
+ public final static int DEFAULT_MAX_ENTITY_COUNT = 100 * 1000;
+
+ /*
+ ///////////////////////////////////////////////////////////////////////
+ // Constants for reader properties:
+ ///////////////////////////////////////////////////////////////////////
+ */
+
+ // // First, standard StAX properties:
+
+ // Simple flags:
+ final static int PROP_COALESCE_TEXT = 1;
+ final static int PROP_NAMESPACE_AWARE = 2;
+ final static int PROP_REPLACE_ENTITY_REFS = 3;
+ final static int PROP_SUPPORT_EXTERNAL_ENTITIES = 4;
+ final static int PROP_VALIDATE_AGAINST_DTD = 5;
+ final static int PROP_SUPPORT_DTD = 6;
+
+ // Object type properties
+ public final static int PROP_EVENT_ALLOCATOR = 7;
+ final static int PROP_WARNING_REPORTER = 8;
+ final static int PROP_XML_RESOLVER = 9;
+
+ // // Then StAX2 standard properties:
+
+ // Simple flags:
+ final static int PROP_INTERN_NS_URIS = 20;
+ final static int PROP_INTERN_NAMES = 21;
+ final static int PROP_REPORT_CDATA = 22;
+ final static int PROP_REPORT_PROLOG_WS = 23;
+ final static int PROP_PRESERVE_LOCATION = 24;
+ final static int PROP_AUTO_CLOSE_INPUT = 25;
+
+ // Enum / Object type properties:
+ final static int PROP_SUPPORT_XMLID = 26; // shared with WriterConfig
+ final static int PROP_DTD_OVERRIDE = 27;
+
+ // // // Constants for additional Wstx properties:
+
+ // Simple flags:
+
+ /**
+ * Note: this entry was deprecated for 4.0 versions up until
+ * and including 4.0.7; was brought back for 4.0.8 (and will
+ * be retained for 4.1)
+ */
+ final static int PROP_NORMALIZE_LFS = 40;
+
+ /* This entry was deprecated for 3.2 and removed in 4.0
+ * version. There are no plans to bring it back.
+ */
+ //final static int PROP_NORMALIZE_ATTR_VALUES = 41;
+
+ final static int PROP_CACHE_DTDS = 42;
+ final static int PROP_CACHE_DTDS_BY_PUBLIC_ID = 43;
+ final static int PROP_LAZY_PARSING = 44;
+ final static int PROP_SUPPORT_DTDPP = 45;
+ final static int PROP_TREAT_CHAR_REFS_AS_ENTS = 46;
+
+ // Object type properties:
+
+ final static int PROP_INPUT_BUFFER_LENGTH = 50;
+ //final static int PROP_TEXT_BUFFER_LENGTH = 51;
+ final static int PROP_MIN_TEXT_SEGMENT = 52;
+ final static int PROP_CUSTOM_INTERNAL_ENTITIES = 53;
+ final static int PROP_DTD_RESOLVER = 54;
+ final static int PROP_ENTITY_RESOLVER = 55;
+ final static int PROP_UNDECLARED_ENTITY_RESOLVER = 56;
+ final static int PROP_BASE_URL = 57;
+ final static int PROP_INPUT_PARSING_MODE = 58;
+
+ // Size limitation to prevent various DOS attacks
+ final static int PROP_MAX_ATTRIBUTES_PER_ELEMENT = 60;
+ final static int PROP_MAX_CHILDREN_PER_ELEMENT = 61;
+ final static int PROP_MAX_ELEMENT_COUNT = 62;
+ final static int PROP_MAX_ELEMENT_DEPTH = 63;
+ final static int PROP_MAX_CHARACTERS = 64;
+ final static int PROP_MAX_ATTRIBUTE_SIZE = 65;
+ final static int PROP_MAX_TEXT_LENGTH = 66;
+ final static int PROP_MAX_ENTITY_COUNT = 67;
+ final static int PROP_MAX_ENTITY_DEPTH = 68;
+
+ /*
+ ////////////////////////////////////////////////
+ // Limits for numeric properties
+ ////////////////////////////////////////////////
+ */
+
+ /**
+ * Need to set a minimum size, since there are some limitations to
+ * smallest consequtive block that can be used.
+ */
+ final static int MIN_INPUT_BUFFER_LENGTH = 8; // 16 bytes
+
+ /**
+ * Let's allow caching of just a dozen DTDs... shouldn't really
+ * matter, how many DTDs does one really use?
+ */
+ final static int DTD_CACHE_SIZE_J2SE = 12;
+
+ final static int DTD_CACHE_SIZE_J2ME = 5;
+
+ /*
+ ///////////////////////////////////////////////////////////////////////
+ // Default values for custom properties:
+ ///////////////////////////////////////////////////////////////////////
+ */
+
+ /**
+ * By default, let's require minimum of 64 chars to be delivered
+ * as shortest partial (piece of) text (CDATA, text) segment;
+ * same for both J2ME subset and full readers. Prevents tiniest
+ * runts from getting passed
+ */
+ final static int DEFAULT_SHORTEST_TEXT_SEGMENT = 64;
+
+ /**
+ * Default config flags are converted from individual settings,
+ * to conform to StAX 1.0 specifications.
+ */
+ final static int DEFAULT_FLAGS_FULL =
+ 0
+ // First, default settings StAX specs dictate:
+
+ | CFG_NAMESPACE_AWARE
+ // Coalescing to be disabled
+ //| CFG_COALESCE_TEXT
+ | CFG_REPLACE_ENTITY_REFS
+ | CFG_SUPPORT_EXTERNAL_ENTITIES
+ | CFG_SUPPORT_DTD
+
+ // and then custom setting defaults:
+
+ // and namespace URI interning
+ | CFG_INTERN_NAMES
+ | CFG_INTERN_NS_URIS
+
+ // we will also accurately report CDATA, by default
+ | CFG_REPORT_CDATA
+
+ /* 20-Jan-2006, TSa: As per discussions on stax-builders list
+ * (and input from xml experts), 4.0 will revert to "do not
+ * report SPACE events outside root element by default"
+ * settings. Conceptually this is what xml specification
+ * implies should be done: there is no content outside of
+ * the element tree, including any ignorable content, just
+ * processing instructions and comments.
+ */
+ //| CFG_REPORT_PROLOG_WS
+
+ /* but enable DTD caching (if they are handled):
+ * (... maybe J2ME subset shouldn't do it?)
+ */
+ | CFG_CACHE_DTDS
+ /* 29-Mar-2006, TSa: But note, no caching by public-id, due
+ * to problems with cases where public-id/system-id were
+ * inconsistently used, leading to problems.
+ */
+
+ /* by default, let's also allow lazy parsing, since it tends
+ * to improve performance
+ */
+ | CFG_LAZY_PARSING
+
+ /* and also make Event objects preserve location info...
+ * can be turned off for maximum performance
+ */
+ | CFG_PRESERVE_LOCATION
+
+ // As per Stax 1.0 specs, we can not enable this by default:
+ //| CFG_AUTO_CLOSE_INPUT);
+
+ /* Also, let's enable dtd++ support (shouldn't hurt with non-dtd++
+ * dtds)
+ */
+
+ | CFG_SUPPORT_DTDPP
+
+ /*
+ * Set this as a default, as this is required in xml;
+ */
+ | CFG_NORMALIZE_LFS
+
+ /* Regarding Xml:id, let's enabled typing by default, but not
+ * uniqueness validity checks: latter will be taken care of
+ * by DTD validation if enabled, otherwise needs to be explicitly
+ * enabled
+ */
+ | CFG_XMLID_TYPING
+ // | CFG_XMLID_UNIQ_CHECKS
+ ;
+
+ /**
+ * For now defaults for J2ME flags can be identical to 'full' set;
+ * differences are in buffer sizes.
+ */
+ final static int DEFAULT_FLAGS_J2ME = DEFAULT_FLAGS_FULL;
+
+ // // //
+
+ /**
+ * Map to use for converting from String property ids to ints
+ * described above; useful to allow use of switch later on.
+ */
+ final static HashMap sProperties = new HashMap(64); // we have about 40 entries
+ static {
+ // Standard ones; support for features
+ sProperties.put(XMLInputFactory.IS_COALESCING, PROP_COALESCE_TEXT);
+ sProperties.put(XMLInputFactory.IS_NAMESPACE_AWARE,
+ PROP_NAMESPACE_AWARE);
+ sProperties.put(XMLInputFactory.IS_REPLACING_ENTITY_REFERENCES,
+ PROP_REPLACE_ENTITY_REFS);
+ sProperties.put(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES,
+ PROP_SUPPORT_EXTERNAL_ENTITIES);
+ sProperties.put(XMLInputFactory.IS_VALIDATING,
+ PROP_VALIDATE_AGAINST_DTD);
+ sProperties.put(XMLInputFactory.SUPPORT_DTD,
+ PROP_SUPPORT_DTD);
+
+ // Standard ones; pluggable components
+ sProperties.put(XMLInputFactory.ALLOCATOR,
+ PROP_EVENT_ALLOCATOR);
+ sProperties.put(XMLInputFactory.REPORTER,
+ PROP_WARNING_REPORTER);
+ sProperties.put(XMLInputFactory.RESOLVER,
+ PROP_XML_RESOLVER);
+
+ // StAX2-introduced flags:
+ sProperties.put(XMLInputFactory2.P_INTERN_NAMES,
+ PROP_INTERN_NAMES);
+ sProperties.put(XMLInputFactory2.P_INTERN_NS_URIS,
+ PROP_INTERN_NS_URIS);
+ sProperties.put(XMLInputFactory2.P_REPORT_CDATA,
+ PROP_REPORT_CDATA);
+ sProperties.put(XMLInputFactory2.P_REPORT_PROLOG_WHITESPACE,
+ PROP_REPORT_PROLOG_WS);
+ sProperties.put(XMLInputFactory2.P_PRESERVE_LOCATION,
+ PROP_PRESERVE_LOCATION);
+ sProperties.put(XMLInputFactory2.P_AUTO_CLOSE_INPUT,
+ PROP_AUTO_CLOSE_INPUT);
+ sProperties.put(XMLInputFactory2.XSP_SUPPORT_XMLID,
+ PROP_SUPPORT_XMLID);
+ sProperties.put(XMLInputFactory2.P_DTD_OVERRIDE,
+ PROP_DTD_OVERRIDE);
+
+ // Non-standard ones, flags:
+
+ sProperties.put(WstxInputProperties.P_CACHE_DTDS, PROP_CACHE_DTDS);
+ sProperties.put(WstxInputProperties.P_CACHE_DTDS_BY_PUBLIC_ID,
+ PROP_CACHE_DTDS_BY_PUBLIC_ID);
+ sProperties.put(XMLInputFactory2.P_LAZY_PARSING, PROP_LAZY_PARSING);
+ /*
+ sProperties.put(WstxInputProperties.P_SUPPORT_DTDPP,
+ PROP_SUPPORT_DTDPP));
+ */
+ sProperties.put(WstxInputProperties.P_TREAT_CHAR_REFS_AS_ENTS,
+ PROP_TREAT_CHAR_REFS_AS_ENTS);
+ sProperties.put(WstxInputProperties.P_NORMALIZE_LFS, PROP_NORMALIZE_LFS);
+
+
+ // Non-standard ones, non-flags:
+
+ sProperties.put(WstxInputProperties.P_INPUT_BUFFER_LENGTH,
+ PROP_INPUT_BUFFER_LENGTH);
+ sProperties.put(WstxInputProperties.P_MIN_TEXT_SEGMENT,
+ PROP_MIN_TEXT_SEGMENT);
+ sProperties.put(WstxInputProperties.P_MAX_ATTRIBUTES_PER_ELEMENT,
+ PROP_MAX_ATTRIBUTES_PER_ELEMENT);
+ sProperties.put(WstxInputProperties.P_MAX_ATTRIBUTE_SIZE,
+ PROP_MAX_ATTRIBUTE_SIZE);
+ sProperties.put(WstxInputProperties.P_MAX_CHILDREN_PER_ELEMENT,
+ PROP_MAX_CHILDREN_PER_ELEMENT);
+ sProperties.put(WstxInputProperties.P_MAX_TEXT_LENGTH,
+ PROP_MAX_TEXT_LENGTH);
+ sProperties.put(WstxInputProperties.P_MAX_ELEMENT_COUNT,
+ PROP_MAX_ELEMENT_COUNT);
+ sProperties.put(WstxInputProperties.P_MAX_ELEMENT_DEPTH,
+ PROP_MAX_ELEMENT_DEPTH);
+ sProperties.put(WstxInputProperties.P_MAX_ENTITY_DEPTH,
+ PROP_MAX_ENTITY_DEPTH);
+ sProperties.put(WstxInputProperties.P_MAX_ENTITY_COUNT,
+ PROP_MAX_ENTITY_COUNT);
+ sProperties.put(WstxInputProperties.P_MAX_CHARACTERS, PROP_MAX_CHARACTERS);
+
+ {
+ @SuppressWarnings("deprecation")
+ String key = WstxInputProperties.P_CUSTOM_INTERNAL_ENTITIES;
+ sProperties.put(key, Integer.valueOf(PROP_CUSTOM_INTERNAL_ENTITIES));
+ }
+ sProperties.put(WstxInputProperties.P_DTD_RESOLVER,
+ PROP_DTD_RESOLVER);
+ sProperties.put(WstxInputProperties.P_ENTITY_RESOLVER,
+ PROP_ENTITY_RESOLVER);
+ sProperties.put(WstxInputProperties.P_UNDECLARED_ENTITY_RESOLVER,
+ PROP_UNDECLARED_ENTITY_RESOLVER);
+ sProperties.put(WstxInputProperties.P_BASE_URL,
+ PROP_BASE_URL);
+ sProperties.put(WstxInputProperties.P_INPUT_PARSING_MODE,
+ PROP_INPUT_PARSING_MODE);
+ }
+
+ /*
+ ///////////////////////////////////////////////////////////////////////
+ // Current config state:
+ ///////////////////////////////////////////////////////////////////////
+ */
+
+ final protected boolean mIsJ2MESubset;
+
+ final protected SymbolTable mSymbols;
+
+ /**
+ * Bitset that contains state of on/off properties; initialized
+ * to defaults, but can be set/cleared.
+ */
+ protected int mConfigFlags;
+
+ /**
+ * Bitset that indicates explicit changes to {@link #mConfigFlags}
+ * through calls; empty bit means that the corresponding property
+ * has its default value, set bit that an explicit call has been
+ * made.
+ */
+ protected int mConfigFlagMods;
+
+ /**
+ * 13-Nov-2008, tatus: Need to be able to keep track of whether
+ * name-interning has been explicitly enabled/disable or not
+ * (not if it's whatever defaults we have)
+ */
+ final static int PROP_INTERN_NAMES_EXPLICIT = 26;
+ final static int PROP_INTERN_NS_URIS_EXPLICIT = 27;
+
+ protected int mInputBufferLen;
+ protected int mMinTextSegmentLen;
+ protected int mMaxAttributesPerElement = DEFAULT_MAX_ATTRIBUTES_PER_ELEMENT;
+ protected int mMaxAttributeSize = DEFAULT_MAX_ATTRIBUTE_LENGTH;
+ protected int mMaxChildrenPerElement = Integer.MAX_VALUE;
+ protected int mMaxElementDepth = DEFAULT_MAX_ELEMENT_DEPTH;
+ protected long mMaxElementCount = Long.MAX_VALUE; // unlimited
+ protected long mMaxCharacters = Long.MAX_VALUE; // unlimited
+ protected int mMaxTextLength = Integer.MAX_VALUE; // unlimited
+
+ protected int mMaxEntityDepth = DEFAULT_MAX_ENTITY_DEPTH;
+ protected long mMaxEntityCount = DEFAULT_MAX_ENTITY_COUNT;
+
+ /**
+ * Base URL to use as the resolution context for relative entity
+ * references
+ */
+ protected URL mBaseURL;
+
+ /**
+ * Parsing mode can be changed from the default xml compliant
+ * behavior to one of alternate modes (fragment processing,
+ * multiple document processing).
+ */
+ protected WstxInputProperties.ParsingMode mParsingMode =
+ WstxInputProperties.PARSING_MODE_DOCUMENT;
+
+ /**
+ * This boolean flag is set if the input document requires
+ * xml 1.1 (or above) compliant processing: default is xml 1.0
+ * compliant. Note that unlike most other properties, this
+ * does not come from configuration settings, but from processed
+ * document itself.
+ */
+ protected boolean mXml11 = false;
+
+ /*
+ ///////////////////////////////////////////////////////////////////////
+ // Common configuration objects
+ ///////////////////////////////////////////////////////////////////////
+ */
+
+ XMLReporter mReporter;
+
+ XMLResolver mDtdResolver = null;
+ XMLResolver mEntityResolver = null;
+
+ /*
+ ///////////////////////////////////////////////////////////////////////
+ // More special(ized) configuration objects
+ ///////////////////////////////////////////////////////////////////////
+ */
+
+ //Map mCustomEntities;
+ //XMLResolver mUndeclaredEntityResolver;
+ //DTDEventListener mDTDEventListener;
+
+ Object[] mSpecialProperties = null;
+
+ private final static int SPEC_PROC_COUNT = 4;
+
+ private final static int SP_IX_CUSTOM_ENTITIES = 0;
+ private final static int SP_IX_UNDECL_ENT_RESOLVER = 1;
+ private final static int SP_IX_DTD_EVENT_LISTENER = 2;
+ private final static int SP_IX_DTD_OVERRIDE = 3;
+
+ /*
+ ///////////////////////////////////////////////////////////////////////
+ // Buffer recycling:
+ ///////////////////////////////////////////////////////////////////////
+ */
+
+ /**
+ * This ThreadLocal
contains a {@link SoftRerefence}
+ * to a {@link BufferRecycler} used to provide a low-cost
+ * buffer recycling between Reader instances.
+ */
+ final static ThreadLocal> mRecyclerRef = new ThreadLocal>();
+
+ /**
+ * This is the actually container of the recyclable buffers. It
+ * is obtained via ThreadLocal/SoftReference combination, if one
+ * exists, when Config instance is created. If one does not
+ * exist, it will created first time a buffer is returned.
+ */
+ BufferRecycler mCurrRecycler = null;
+
+ /*
+ ///////////////////////////////////////////////////////////////////////
+ // Life-cycle
+ ///////////////////////////////////////////////////////////////////////
+ */
+
+ private ReaderConfig(ReaderConfig base,
+ boolean j2meSubset, SymbolTable symbols,
+ int configFlags, int configFlagMods,
+ int inputBufLen,
+ int minTextSegmentLen)
+ {
+ super(base);
+ mIsJ2MESubset = j2meSubset;
+ mSymbols = symbols;
+
+ mConfigFlags = configFlags;
+ mConfigFlagMods = configFlagMods;
+
+ mInputBufferLen = inputBufLen;
+ mMinTextSegmentLen = minTextSegmentLen;
+ if (base != null) {
+ mMaxAttributesPerElement = base.mMaxAttributesPerElement;
+ mMaxAttributeSize = base.mMaxAttributeSize;
+ mMaxChildrenPerElement = base.mMaxChildrenPerElement;
+ mMaxElementCount = base.mMaxElementCount;
+ mMaxElementDepth = base.mMaxElementDepth;
+ mMaxCharacters = base.mMaxCharacters;
+ mMaxTextLength = base.mMaxTextLength;
+ mMaxEntityDepth = base.mMaxEntityDepth;
+ mMaxEntityCount = base.mMaxEntityCount;
+ }
+
+ /* Ok, let's then see if we can find a buffer recycler. Since they
+ * are lazily constructed, and since GC may just flush them out
+ * on its whims, it's possible we might not find one. That's ok;
+ * we can reconstruct one if and when we are to return one or more
+ * buffers.
+ */
+ SoftReference ref = mRecyclerRef.get();
+ if (ref != null) {
+ mCurrRecycler = ref.get();
+ }
+ }
+
+ public static ReaderConfig createJ2MEDefaults()
+ {
+ /* For J2ME we'll use slightly smaller buffer sizes by
+ * default, on assumption lower memory usage is desireable:
+ */
+ ReaderConfig rc = new ReaderConfig(null,
+ true, null, DEFAULT_FLAGS_J2ME, 0,
+ // 4k input buffer (2000 chars):
+ 2000,
+ DEFAULT_SHORTEST_TEXT_SEGMENT);
+ return rc;
+ }
+
+ public static ReaderConfig createFullDefaults()
+ {
+ /* For full version, can use bit larger buffers to achieve better
+ * overall performance.
+ */
+ ReaderConfig rc = new ReaderConfig(null,
+ false, null, DEFAULT_FLAGS_FULL, 0,
+ // 8k input buffer (4000 chars):
+ 4000,
+ DEFAULT_SHORTEST_TEXT_SEGMENT);
+ return rc;
+ }
+
+ public ReaderConfig createNonShared(SymbolTable sym)
+ {
+ // should we throw an exception?
+ //if (sym == null) { }
+ ReaderConfig rc = new ReaderConfig(this,
+ mIsJ2MESubset, sym,
+ mConfigFlags, mConfigFlagMods,
+ mInputBufferLen,
+ mMinTextSegmentLen);
+ rc.mReporter = mReporter;
+ rc.mDtdResolver = mDtdResolver;
+ rc.mEntityResolver = mEntityResolver;
+ rc.mBaseURL = mBaseURL;
+ rc.mParsingMode = mParsingMode;
+ rc.mMaxAttributesPerElement = mMaxAttributesPerElement;
+ rc.mMaxAttributeSize = mMaxAttributeSize;
+ rc.mMaxChildrenPerElement = mMaxChildrenPerElement;
+ rc.mMaxElementCount = mMaxElementCount;
+ rc.mMaxCharacters = mMaxCharacters;
+ rc.mMaxTextLength = mMaxTextLength;
+ rc.mMaxElementDepth = mMaxElementDepth;
+ rc.mMaxEntityDepth = mMaxEntityDepth;
+ rc.mMaxEntityCount = mMaxEntityCount;
+ if (mSpecialProperties != null) {
+ int len = mSpecialProperties.length;
+ Object[] specProps = new Object[len];
+ System.arraycopy(mSpecialProperties, 0, specProps, 0, len);
+ rc.mSpecialProperties = specProps;
+ }
+ return rc;
+ }
+
+ /**
+ * Unlike name suggests there is also some limited state information
+ * associated with the config object. If these objects are reused,
+ * that state needs to be reset between reuses, to avoid carrying
+ * over incorrect state.
+ */
+ public void resetState()
+ {
+ // Current, only xml 1.0 vs 1.1 state is stored here:
+ mXml11 = false;
+ }
+
+ /*
+ ///////////////////////////////////////////////////////////////////////
+ // Implementation of abstract methods
+ ///////////////////////////////////////////////////////////////////////
+ */
+
+ @Override
+ protected int findPropertyId(String propName)
+ {
+ Integer I = sProperties.get(propName);
+ return (I == null) ? -1 : I.intValue();
+ }
+
+ /*
+ ///////////////////////////////////////////////////////////////////////
+ // Public API, accessors
+ ///////////////////////////////////////////////////////////////////////
+ */
+
+ // // // Accessors for immutable configuration:
+
+ public SymbolTable getSymbols() { return mSymbols; }
+
+ /**
+ * In future this property could/should be made configurable?
+ */
+
+ public int getDtdCacheSize() {
+ return mIsJ2MESubset ? DTD_CACHE_SIZE_J2ME : DTD_CACHE_SIZE_J2SE;
+ }
+
+ // // // "Raw" accessors for on/off properties:
+
+ public int getConfigFlags() { return mConfigFlags; }
+
+ // // // Standard StAX on/off property accessors
+
+ public boolean willCoalesceText() {
+ return _hasConfigFlag(CFG_COALESCE_TEXT);
+ }
+
+ public boolean willSupportNamespaces() {
+ return _hasConfigFlag(CFG_NAMESPACE_AWARE);
+ }
+
+ public boolean willReplaceEntityRefs() {
+ return _hasConfigFlag(CFG_REPLACE_ENTITY_REFS);
+ }
+
+ public boolean willSupportExternalEntities() {
+ return _hasConfigFlag(CFG_SUPPORT_EXTERNAL_ENTITIES);
+ }
+
+ public boolean willSupportDTDs() {
+ return _hasConfigFlag(CFG_SUPPORT_DTD);
+ }
+
+ public boolean willValidateWithDTD() {
+ return _hasConfigFlag(CFG_VALIDATE_AGAINST_DTD);
+ }
+
+ // // // Stax2 on/off property accessors
+
+ public boolean willReportCData() {
+ return _hasConfigFlag(CFG_REPORT_CDATA);
+ }
+
+ public boolean willParseLazily() {
+ return _hasConfigFlag(CFG_LAZY_PARSING);
+ }
+
+ public boolean willInternNames() {
+ return _hasConfigFlag(CFG_INTERN_NAMES);
+ }
+
+ public boolean willInternNsURIs() {
+ return _hasConfigFlag(CFG_INTERN_NS_URIS);
+ }
+
+ public boolean willPreserveLocation() {
+ return _hasConfigFlag(CFG_PRESERVE_LOCATION);
+ }
+
+ public boolean willAutoCloseInput() {
+ return _hasConfigFlag(CFG_AUTO_CLOSE_INPUT);
+ }
+
+ // // // Woodstox on/off property accessors
+
+ public boolean willReportPrologWhitespace() {
+ return _hasConfigFlag(CFG_REPORT_PROLOG_WS);
+ }
+
+ public boolean willCacheDTDs() {
+ return _hasConfigFlag(CFG_CACHE_DTDS);
+ }
+
+ public boolean willCacheDTDsByPublicId() {
+ return _hasConfigFlag(CFG_CACHE_DTDS_BY_PUBLIC_ID);
+ }
+
+ public boolean willDoXmlIdTyping() {
+ return _hasConfigFlag(CFG_XMLID_TYPING);
+ }
+
+ public boolean willDoXmlIdUniqChecks() {
+ return _hasConfigFlag(CFG_XMLID_UNIQ_CHECKS);
+ }
+
+ public boolean willSupportDTDPP() {
+ return _hasConfigFlag(CFG_SUPPORT_DTDPP);
+ }
+
+ public boolean willNormalizeLFs() {
+ return _hasConfigFlag(CFG_NORMALIZE_LFS);
+ }
+
+ public boolean willTreatCharRefsAsEnts() {
+ return _hasConfigFlag(CFG_TREAT_CHAR_REFS_AS_ENTS);
+ }
+
+ public int getInputBufferLength() { return mInputBufferLen; }
+
+ public int getShortestReportedTextSegment() { return mMinTextSegmentLen; }
+
+ public int getMaxAttributesPerElement() { return mMaxAttributesPerElement; }
+ public int getMaxAttributeSize() { return mMaxAttributeSize; }
+ public int getMaxChildrenPerElement() { return mMaxChildrenPerElement; }
+
+ public int getMaxElementDepth() { return mMaxElementDepth; }
+ public long getMaxElementCount() { return mMaxElementCount; }
+
+ public int getMaxEntityDepth() { return mMaxEntityDepth; }
+ public long getMaxEntityCount() { return mMaxEntityCount; }
+
+ public long getMaxCharacters() { return mMaxCharacters; }
+ public long getMaxTextLength() { return mMaxTextLength; }
+
+ public Map getCustomInternalEntities()
+ {
+ @SuppressWarnings("unchecked")
+ Map custEnt = (Map) _getSpecialProperty(SP_IX_CUSTOM_ENTITIES);
+ if (custEnt == null) {
+ return Collections.emptyMap();
+ }
+ // Better be defensive and just return a copy...
+ int len = custEnt.size();
+ HashMap m = new HashMap(len + (len >> 2), 0.81f);
+ for (Map.Entry me : custEnt.entrySet()) {
+ m.put(me.getKey(), me.getValue());
+ }
+ return m;
+ }
+
+ public EntityDecl findCustomInternalEntity(String id)
+ {
+ @SuppressWarnings("unchecked")
+ Map custEnt = (Map) _getSpecialProperty(SP_IX_CUSTOM_ENTITIES);
+ if (custEnt == null) {
+ return null;
+ }
+ return custEnt.get(id);
+ }
+
+ public XMLReporter getXMLReporter() { return mReporter; }
+
+ public XMLResolver getXMLResolver() { return mEntityResolver; }
+
+ public XMLResolver getDtdResolver() { return mDtdResolver; }
+ public XMLResolver getEntityResolver() { return mEntityResolver; }
+ public XMLResolver getUndeclaredEntityResolver() {
+ return (XMLResolver) _getSpecialProperty(SP_IX_UNDECL_ENT_RESOLVER);
+ }
+
+ public URL getBaseURL() { return mBaseURL; }
+
+ public WstxInputProperties.ParsingMode getInputParsingMode() {
+ return mParsingMode;
+ }
+
+ public boolean inputParsingModeDocuments() {
+ return mParsingMode == WstxInputProperties.PARSING_MODE_DOCUMENTS;
+ }
+
+ public boolean inputParsingModeFragment() {
+ return mParsingMode == WstxInputProperties.PARSING_MODE_FRAGMENT;
+ }
+
+ /**
+ * @return True if the input well-formedness and validation checks
+ * should be done according to xml 1.1 specification; false if
+ * xml 1.0 specification.
+ */
+ public boolean isXml11() {
+ return mXml11;
+ }
+
+ public DTDEventListener getDTDEventListener() {
+ return (DTDEventListener) _getSpecialProperty(SP_IX_DTD_EVENT_LISTENER);
+ }
+
+ public DTDValidationSchema getDTDOverride() {
+ return (DTDValidationSchema) _getSpecialProperty(SP_IX_DTD_OVERRIDE);
+ }
+
+ /**
+ * Special accessor to use to verify whether name interning has
+ * explicitly been enabled; true if call was been made to set
+ * it to true; false otherwise (default, or set to false)
+ */
+ public boolean hasInternNamesBeenEnabled() {
+ return _hasExplicitConfigFlag(CFG_INTERN_NAMES);
+ }
+
+ public boolean hasInternNsURIsBeenEnabled() {
+ return _hasExplicitConfigFlag(CFG_INTERN_NS_URIS);
+ }
+
+ /*
+ ///////////////////////////////////////////////////////////////////////
+ // Simple mutators
+ ///////////////////////////////////////////////////////////////////////
+ */
+
+ public void setConfigFlag(int flag) {
+ mConfigFlags |= flag;
+ mConfigFlagMods |= flag;
+ }
+
+ public void clearConfigFlag(int flag) {
+ mConfigFlags &= ~flag;
+ mConfigFlagMods |= flag;
+ }
+
+ // // // Mutators for standard StAX properties
+
+ public void doCoalesceText(boolean state) {
+ setConfigFlag(CFG_COALESCE_TEXT, state);
+ }
+
+ public void doSupportNamespaces(boolean state) {
+ setConfigFlag(CFG_NAMESPACE_AWARE, state);
+ }
+
+ public void doReplaceEntityRefs(boolean state) {
+ setConfigFlag(CFG_REPLACE_ENTITY_REFS, state);
+ }
+
+ public void doSupportExternalEntities(boolean state) {
+ setConfigFlag(CFG_SUPPORT_EXTERNAL_ENTITIES, state);
+ }
+
+ public void doSupportDTDs(boolean state) {
+ setConfigFlag(CFG_SUPPORT_DTD, state);
+ }
+
+ public void doValidateWithDTD(boolean state) {
+ setConfigFlag(CFG_VALIDATE_AGAINST_DTD, state);
+ }
+
+ // // // Mutators for Woodstox-specific properties
+
+ public void doInternNames(boolean state) {
+ setConfigFlag(CFG_INTERN_NAMES, state);
+ }
+
+ public void doInternNsURIs(boolean state) {
+ setConfigFlag(CFG_INTERN_NS_URIS, state);
+ }
+
+ public void doReportPrologWhitespace(boolean state) {
+ setConfigFlag(CFG_REPORT_PROLOG_WS, state);
+ }
+
+ public void doReportCData(boolean state) {
+ setConfigFlag(CFG_REPORT_CDATA, state);
+ }
+
+ public void doCacheDTDs(boolean state) {
+ setConfigFlag(CFG_CACHE_DTDS, state);
+ }
+
+ public void doCacheDTDsByPublicId(boolean state) {
+ setConfigFlag(CFG_CACHE_DTDS_BY_PUBLIC_ID, state);
+ }
+
+ public void doParseLazily(boolean state) {
+ setConfigFlag(CFG_LAZY_PARSING, state);
+ }
+
+ public void doXmlIdTyping(boolean state) {
+ setConfigFlag(CFG_XMLID_TYPING, state);
+ }
+
+ public void doXmlIdUniqChecks(boolean state) {
+ setConfigFlag(CFG_XMLID_UNIQ_CHECKS, state);
+ }
+
+ public void doPreserveLocation(boolean state) {
+ setConfigFlag(CFG_PRESERVE_LOCATION, state);
+ }
+
+ public void doAutoCloseInput(boolean state) {
+ setConfigFlag(CFG_AUTO_CLOSE_INPUT, state);
+ }
+
+ public void doSupportDTDPP(boolean state) {
+ setConfigFlag(CFG_SUPPORT_DTDPP, state);
+ }
+
+ public void doTreatCharRefsAsEnts(final boolean state) {
+ setConfigFlag(CFG_TREAT_CHAR_REFS_AS_ENTS, state);
+ }
+
+ public void doNormalizeLFs(final boolean state) {
+ setConfigFlag(CFG_NORMALIZE_LFS, state);
+ }
+
+ public void setInputBufferLength(int value)
+ {
+ /* Let's enforce minimum here; necessary to allow longest
+ * consequtive text span to be available (xml decl, etc)
+ */
+ if (value < MIN_INPUT_BUFFER_LENGTH) {
+ value = MIN_INPUT_BUFFER_LENGTH;
+ }
+ mInputBufferLen = value;
+ }
+
+ public void setShortestReportedTextSegment(int value) {
+ mMinTextSegmentLen = value;
+ }
+ public void setMaxAttributesPerElement(int value) {
+ mMaxAttributesPerElement = value;
+ }
+ public void setMaxAttributeSize(int value) {
+ mMaxAttributeSize = value;
+ }
+ public void setMaxChildrenPerElement(int value) {
+ mMaxChildrenPerElement = value;
+ }
+ public void setMaxElementDepth(int value) {
+ mMaxElementDepth = value;
+ }
+ public void setMaxElementCount(long value) {
+ mMaxElementCount = value;
+ }
+ public void setMaxCharacters(long value) {
+ mMaxCharacters = value;
+ }
+ public void setMaxTextLength(int value) {
+ mMaxTextLength = value;
+ }
+ public void setMaxEntityDepth(int value) {
+ mMaxEntityDepth = value;
+ }
+ public void setMaxEntityCount(long value) {
+ mMaxEntityCount = value;
+ }
+
+ public void setCustomInternalEntities(Map m)
+ {
+ Map entMap;
+ if (m == null || m.size() < 1) {
+ entMap = Collections.emptyMap();
+ } else {
+ int len = m.size();
+ entMap = new HashMap(len + (len >> 1), 0.75f);
+ for (Map.Entry me : m.entrySet()) {
+ Object val = me.getValue();
+ char[] ch;
+ if (val == null) {
+ ch = DataUtil.getEmptyCharArray();
+ } else if (val instanceof char[]) {
+ ch = (char[]) val;
+ } else {
+ // Probably String, but let's just ensure that
+ String str = val.toString();
+ ch = str.toCharArray();
+ }
+ String name = me.getKey();
+ entMap.put(name, IntEntity.create(name, ch));
+ }
+ }
+ _setSpecialProperty(SP_IX_CUSTOM_ENTITIES, entMap);
+ }
+
+ public void setXMLReporter(XMLReporter r) {
+ mReporter = r;
+ }
+
+ /**
+ * Note: for better granularity, you should call {@link #setEntityResolver}
+ * and {@link #setDtdResolver} instead.
+ */
+ public void setXMLResolver(XMLResolver r) {
+ mEntityResolver = r;
+ mDtdResolver = r;
+ }
+
+ public void setDtdResolver(XMLResolver r) {
+ mDtdResolver = r;
+ }
+
+ public void setEntityResolver(XMLResolver r) {
+ mEntityResolver = r;
+ }
+
+ public void setUndeclaredEntityResolver(XMLResolver r) {
+ _setSpecialProperty(SP_IX_UNDECL_ENT_RESOLVER, r);
+ }
+
+ public void setBaseURL(URL baseURL) { mBaseURL = baseURL; }
+
+ public void setInputParsingMode(WstxInputProperties.ParsingMode mode) {
+ mParsingMode = mode;
+ }
+
+ /**
+ * Method called to enable or disable 1.1 compliant processing; if
+ * disabled, defaults to xml 1.0 compliant processing.
+ */
+ public void enableXml11(boolean state) {
+ mXml11 = state;
+ }
+
+ public void setDTDEventListener(DTDEventListener l) {
+ _setSpecialProperty(SP_IX_DTD_EVENT_LISTENER, l);
+ }
+
+ public void setDTDOverride(DTDValidationSchema schema) {
+ _setSpecialProperty(SP_IX_DTD_OVERRIDE, schema);
+ }
+
+ /*
+ ///////////////////////////////////////////////////////////////////////
+ // Profile mutators:
+ ///////////////////////////////////////////////////////////////////////
+ */
+
+ /**
+ * Method to call to make Reader created conform as closely to XML
+ * standard as possible, doing all checks and transformations mandated
+ * (linefeed conversions, attr value normalizations).
+ * See {@link XMLInputFactory2#configureForXmlConformance} for
+ * required settings for standard StAX/StAX properties.
+ *
+ * In addition to the standard settings, following Woodstox-specific
+ * settings are also done:
+ *
+ *
+ * Notes: Does NOT change 'performance' settings (buffer sizes,
+ * DTD caching, coalescing, interning, accurate location info).
+ */
+ public void configureForXmlConformance()
+ {
+ // // StAX 1.0 settings
+ doSupportNamespaces(true);
+ doSupportDTDs(true);
+ doSupportExternalEntities(true);
+ doReplaceEntityRefs(true);
+
+ // // Stax2 additional settings
+
+ // Better enable full xml:id checks:
+ doXmlIdTyping(true);
+ doXmlIdUniqChecks(true);
+
+ // Woodstox-specific ones:
+ }
+
+ /**
+ * 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.
+ * See {@link XMLInputFactory2#configureForConvenience} for
+ * required settings for standard StAX/StAX properties.
+ *
+ * In addition to the standard settings, following Woodstox-specific
+ * settings are also done:
+ *
+ * - Disable
XMLStreamFactory2.P_LAZY_PARSING
(to allow for synchronous
+ * error notification by forcing full XML events to be completely
+ * parsed when reader's next() is called)
+ *
+ *
+ */
+ public void configureForConvenience()
+ {
+ // StAX (1.0) settings:
+ doCoalesceText(true);
+ doReplaceEntityRefs(true);
+
+ // StAX2:
+ doReportCData(false);
+ doReportPrologWhitespace(false);
+ /* Also, knowing exact locations is nice esp. for error
+ * reporting purposes
+ */
+ doPreserveLocation(true);
+
+ // Woodstox-specific:
+
+ /* Also, we can force errors to be reported in timely manner:
+ * (once again, at potential expense of performance)
+ */
+ doParseLazily(false);
+ }
+
+ /**
+ * 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.
+ *
+ * See {@link XMLInputFactory2#configureForSpeed} for
+ * required settings for standard StAX/StAX properties.
+ *
+ * In addition to the standard settings, following Woodstox-specific
+ * settings are also done:
+ *
+ * - Enable
P_CACHE_DTDS
.
+ *
+ * - Enable
XMLStremaFactory2.P_LAZY_PARSING
(can improve performance
+ * especially when skipping text segments)
+ *
+ * - Disable Xml:id uniqueness checks (and leave typing as is)
+ *
+ * - Set lowish value for
P_MIN_TEXT_SEGMENT
, to allow
+ * reader to optimize segment length it uses (and possibly avoids
+ * one copy operation in the process)
+ *
+ * - Increase
P_INPUT_BUFFER_LENGTH
a bit from default,
+ * to allow for longer consequtive read operations; also reduces cases
+ * where partial text segments are on input buffer boundaries.
+ *
+ *
+ */
+ public void configureForSpeed()
+ {
+ // StAX (1.0):
+ doCoalesceText(false);
+
+ // StAX2:
+ doPreserveLocation(false);
+ doReportPrologWhitespace(false);
+ //doInternNames(true); // this is a NOP
+ doInternNsURIs(true);
+ doXmlIdUniqChecks(false);
+
+ // Woodstox-specific:
+ doCacheDTDs(true);
+ doParseLazily(true);
+
+ /* If we let Reader decide sizes of text segments, it should be
+ * able to optimize it better, thus low min value. This value
+ * is only used in cases where text is at buffer boundary, or
+ * where entity prevents using consequtive chars from input buffer:
+ */
+ setShortestReportedTextSegment(16);
+ setInputBufferLength(8000); // 16k input buffer
+ }
+
+ /**
+ * 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.
+ *
+ * See {@link XMLInputFactory2#configureForLowMemUsage} for
+ * required settings for standard StAX/StAX properties.
+ *
+ * In addition to the standard settings, following Woodstox-specific
+ * settings are also done:
+ *
+ * - Disable
P_CACHE_DTDS
+ *
+ * - Enable
P_PARSE_LAZILY
+ *
+ * - Resets
P_MIN_TEXT_SEGMENT
to the (somewhat low)
+ * default value.
+ * -
+ *
- Reduces
P_INPUT_BUFFER_LENGTH
a bit from the default
+ * -
+ *
+ */
+ public void configureForLowMemUsage()
+ {
+ // StAX (1.0)
+ doCoalesceText(false);
+
+ // StAX2:
+
+ doPreserveLocation(false); // can reduce temporary mem usage
+
+ // Woodstox-specific:
+ doCacheDTDs(false);
+ doParseLazily(true); // can reduce temporary mem usage
+ doXmlIdUniqChecks(false); // enabling would increase mem usage
+ setShortestReportedTextSegment(ReaderConfig.DEFAULT_SHORTEST_TEXT_SEGMENT);
+ setInputBufferLength(512); // 1k input buffer
+ // Text buffer need not be huge, as we do not coalesce
+ }
+
+ /**
+ * 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.
+ *
+ * See {@link XMLInputFactory2#configureForLowMemUsage} for
+ * required settings for standard StAX/StAX properties.
+ *
+ * In addition to the standard settings, following Woodstox-specific
+ * settings are also done:
+ *
+ * - Increases
P_MIN_TEXT_SEGMENT
to the maximum value so
+ * that all original text segment chunks are reported without
+ * segmentation (but without coalescing with adjacent CDATA segments)
+ * -
+ *
- Sets
P_TREAT_CHAR_REFS_AS_ENTS
to true, so the all the
+ * original character references are reported with their position,
+ * original text, and the replacement text.
+ *
+ *
+ */
+ public void configureForRoundTripping()
+ {
+ // StAX (1.0)
+ doCoalesceText(false);
+ doReplaceEntityRefs(false);
+
+ // StAX2:
+ doReportCData(true);
+ doReportPrologWhitespace(true);
+
+ // Woodstox specific settings
+ doTreatCharRefsAsEnts(true);
+ doNormalizeLFs(false);
+
+ // effectively prevents from reporting partial segments:
+ setShortestReportedTextSegment(Integer.MAX_VALUE);
+ }
+
+ /*
+ ///////////////////////////////////////////////////////////////////////
+ // Buffer recycling:
+ ///////////////////////////////////////////////////////////////////////
+ */
+
+ public char[] allocSmallCBuffer(int minSize)
+ {
+ if (mCurrRecycler != null) {
+ char[] result = mCurrRecycler.getSmallCBuffer(minSize);
+ if (result != null) {
+ return result;
+ }
+ }
+ // Nope; no recycler, or it has no suitable buffers, let's create:
+ return new char[minSize];
+ }
+
+ public void freeSmallCBuffer(char[] buffer)
+ {
+ // Need to create (and assign) the buffer?
+ if (mCurrRecycler == null) {
+ mCurrRecycler = createRecycler();
+ }
+ mCurrRecycler.returnSmallCBuffer(buffer);
+ }
+
+ public char[] allocMediumCBuffer(int minSize)
+ {
+ if (mCurrRecycler != null) {
+ char[] result = mCurrRecycler.getMediumCBuffer(minSize);
+ if (result != null) {
+ return result;
+ }
+ }
+ return new char[minSize];
+ }
+
+ public void freeMediumCBuffer(char[] buffer)
+ {
+ if (mCurrRecycler == null) {
+ mCurrRecycler = createRecycler();
+ }
+ mCurrRecycler.returnMediumCBuffer(buffer);
+ }
+
+ public char[] allocFullCBuffer(int minSize)
+ {
+ if (mCurrRecycler != null) {
+ char[] result = mCurrRecycler.getFullCBuffer(minSize);
+ if (result != null) {
+ return result;
+ }
+ }
+ return new char[minSize];
+ }
+
+ public void freeFullCBuffer(char[] buffer)
+ {
+ // Need to create (and assign) the buffer?
+ if (mCurrRecycler == null) {
+ mCurrRecycler = createRecycler();
+ }
+ mCurrRecycler.returnFullCBuffer(buffer);
+ }
+
+ public byte[] allocFullBBuffer(int minSize)
+ {
+ if (mCurrRecycler != null) {
+ byte[] result = mCurrRecycler.getFullBBuffer(minSize);
+ if (result != null) {
+ return result;
+ }
+ }
+ return new byte[minSize];
+ }
+
+ public void freeFullBBuffer(byte[] buffer)
+ {
+ // Need to create (and assign) the buffer?
+ if (mCurrRecycler == null) {
+ mCurrRecycler = createRecycler();
+ }
+ mCurrRecycler.returnFullBBuffer(buffer);
+ }
+
+ private BufferRecycler createRecycler()
+ {
+ BufferRecycler recycler = new BufferRecycler();
+ // No way to reuse/reset SoftReference, have to create new always:
+ mRecyclerRef.set(new SoftReference(recycler));
+ return recycler;
+ }
+
+ /*
+ ///////////////////////////////////////////////////////////////////////
+ // Internal methods:
+ ///////////////////////////////////////////////////////////////////////
+ */
+
+ private void setConfigFlag(int flag, boolean state)
+ {
+ if (state) {
+ mConfigFlags |= flag;
+ } else {
+ mConfigFlags &= ~flag;
+ }
+ mConfigFlagMods |= flag;
+ }
+
+ @Override
+ public Object getProperty(int id)
+ {
+ switch (id) {
+ // First, standard Stax 1.0 properties:
+
+ case PROP_COALESCE_TEXT:
+ return willCoalesceText() ? Boolean.TRUE : Boolean.FALSE;
+ case PROP_NAMESPACE_AWARE:
+ return willSupportNamespaces() ? Boolean.TRUE : Boolean.FALSE;
+ case PROP_REPLACE_ENTITY_REFS:
+ return willReplaceEntityRefs() ? Boolean.TRUE : Boolean.FALSE;
+ case PROP_SUPPORT_EXTERNAL_ENTITIES:
+ return willSupportExternalEntities() ? Boolean.TRUE : Boolean.FALSE;
+
+ case PROP_VALIDATE_AGAINST_DTD:
+ return willValidateWithDTD() ? Boolean.TRUE : Boolean.FALSE;
+ case PROP_SUPPORT_DTD:
+ return willSupportDTDs() ? Boolean.TRUE : Boolean.FALSE;
+ case PROP_WARNING_REPORTER:
+ return getXMLReporter();
+ case PROP_XML_RESOLVER:
+ return getXMLResolver();
+ case PROP_EVENT_ALLOCATOR:
+ /* 25-Mar-2006, TSa: Not really supported here, so let's
+ * return null
+ */
+ return null;
+
+ // Then Stax2 properties:
+
+ case PROP_REPORT_PROLOG_WS:
+ return willReportPrologWhitespace() ? Boolean.TRUE : Boolean.FALSE;
+ case PROP_REPORT_CDATA:
+ return willReportCData() ? Boolean.TRUE : Boolean.FALSE;
+
+ case PROP_INTERN_NAMES:
+ return willInternNames() ? Boolean.TRUE : Boolean.FALSE;
+ case PROP_INTERN_NS_URIS:
+ return willInternNsURIs() ? Boolean.TRUE : Boolean.FALSE;
+
+ case PROP_PRESERVE_LOCATION:
+ return willPreserveLocation() ? Boolean.TRUE : Boolean.FALSE;
+ case PROP_AUTO_CLOSE_INPUT:
+ return willAutoCloseInput() ? Boolean.TRUE : Boolean.FALSE;
+
+ case PROP_DTD_OVERRIDE:
+ return getDTDOverride();
+
+ // // // Then Woodstox custom properties:
+
+ // first, flags:
+ case PROP_CACHE_DTDS:
+ return willCacheDTDs() ? Boolean.TRUE : Boolean.FALSE;
+ case PROP_CACHE_DTDS_BY_PUBLIC_ID:
+ return willCacheDTDsByPublicId() ? Boolean.TRUE : Boolean.FALSE;
+ case PROP_LAZY_PARSING:
+ return willParseLazily() ? Boolean.TRUE : Boolean.FALSE;
+ case PROP_SUPPORT_XMLID:
+ {
+ if (!_hasConfigFlag(CFG_XMLID_TYPING)) {
+ return XMLStreamProperties.XSP_V_XMLID_NONE;
+ }
+ return _hasConfigFlag(CFG_XMLID_UNIQ_CHECKS) ?
+ XMLStreamProperties.XSP_V_XMLID_FULL :
+ XMLStreamProperties.XSP_V_XMLID_TYPING;
+ }
+
+ case PROP_TREAT_CHAR_REFS_AS_ENTS:
+ return willTreatCharRefsAsEnts() ? Boolean.TRUE : Boolean.FALSE;
+
+ case PROP_NORMALIZE_LFS:
+ return willNormalizeLFs() ? Boolean.TRUE : Boolean.FALSE;
+
+ // then object values:
+ case PROP_INPUT_BUFFER_LENGTH:
+ return getInputBufferLength();
+ case PROP_MAX_ATTRIBUTES_PER_ELEMENT:
+ return getMaxAttributesPerElement();
+ case PROP_MAX_ATTRIBUTE_SIZE:
+ return getMaxAttributeSize();
+ case PROP_MAX_CHILDREN_PER_ELEMENT:
+ return getMaxChildrenPerElement();
+ case PROP_MAX_ELEMENT_DEPTH:
+ return getMaxElementDepth();
+ case PROP_MAX_ELEMENT_COUNT:
+ return getMaxElementCount();
+ case PROP_MAX_CHARACTERS:
+ return getMaxCharacters();
+ case PROP_MAX_TEXT_LENGTH:
+ return getMaxTextLength();
+ case PROP_MAX_ENTITY_DEPTH:
+ return getMaxEntityDepth();
+ case PROP_MAX_ENTITY_COUNT:
+ return getMaxEntityCount();
+
+ case PROP_MIN_TEXT_SEGMENT:
+ return getShortestReportedTextSegment();
+ case PROP_CUSTOM_INTERNAL_ENTITIES:
+ return getCustomInternalEntities();
+ case PROP_DTD_RESOLVER:
+ return getDtdResolver();
+ case PROP_ENTITY_RESOLVER:
+ return getEntityResolver();
+ case PROP_UNDECLARED_ENTITY_RESOLVER:
+ return getUndeclaredEntityResolver();
+ case PROP_BASE_URL:
+ return getBaseURL();
+ case PROP_INPUT_PARSING_MODE:
+ return getInputParsingMode();
+
+ default: // sanity check, should never happen
+ throw new IllegalStateException("Internal error: no handler for property with internal id "+id+".");
+ }
+ }
+
+ @Override
+ public boolean setProperty(String propName, int id, Object value)
+ {
+ switch (id) {
+ // First, standard (Stax 1.0) properties:
+
+ case PROP_COALESCE_TEXT:
+ doCoalesceText(ArgUtil.convertToBoolean(propName, value));
+ break;
+
+ case PROP_NAMESPACE_AWARE:
+ doSupportNamespaces(ArgUtil.convertToBoolean(propName, value));
+ break;
+
+ case PROP_REPLACE_ENTITY_REFS:
+ doReplaceEntityRefs(ArgUtil.convertToBoolean(propName, value));
+ break;
+
+ case PROP_SUPPORT_EXTERNAL_ENTITIES:
+ doSupportExternalEntities(ArgUtil.convertToBoolean(propName, value));
+ break;
+
+ case PROP_SUPPORT_DTD:
+ doSupportDTDs(ArgUtil.convertToBoolean(propName, value));
+ break;
+
+ // // // Then ones that can be dispatched:
+
+ case PROP_VALIDATE_AGAINST_DTD:
+ doValidateWithDTD(ArgUtil.convertToBoolean(propName, value));
+ break;
+
+ case PROP_WARNING_REPORTER:
+ setXMLReporter((XMLReporter) value);
+ break;
+
+ case PROP_XML_RESOLVER:
+ setXMLResolver((XMLResolver) value);
+ break;
+
+ case PROP_EVENT_ALLOCATOR:
+ /* 25-Mar-2006, TSa: Not really supported here, so let's
+ * return false to let caller deal with it
+ */
+ return false;
+
+ // // // Then Stax2 properties, flags:
+
+ case PROP_INTERN_NS_URIS:
+ doInternNsURIs(ArgUtil.convertToBoolean(propName, value));
+ break;
+
+ case PROP_INTERN_NAMES:
+ doInternNames(ArgUtil.convertToBoolean(propName, value));
+ break;
+
+ case PROP_REPORT_CDATA:
+ doReportCData(ArgUtil.convertToBoolean(propName, value));
+ break;
+
+ case PROP_REPORT_PROLOG_WS:
+ doReportPrologWhitespace(ArgUtil.convertToBoolean(propName, value));
+ break;
+
+ case PROP_PRESERVE_LOCATION:
+ doPreserveLocation(ArgUtil.convertToBoolean(propName, value));
+ break;
+
+ case PROP_AUTO_CLOSE_INPUT:
+ doAutoCloseInput(ArgUtil.convertToBoolean(propName, value));
+ break;
+
+ // // // Then Stax2 properties, enum/object types:
+
+ case PROP_SUPPORT_XMLID:
+ {
+ boolean typing, uniq;
+
+ if (XMLStreamProperties.XSP_V_XMLID_NONE.equals(value)) {
+ typing = uniq = false;
+ } else if (XMLStreamProperties.XSP_V_XMLID_TYPING.equals(value)) {
+ typing = true;
+ uniq = false;
+ } else if (XMLStreamProperties.XSP_V_XMLID_FULL.equals(value)) {
+ typing = uniq = true;
+ } else {
+ throw new IllegalArgumentException
+ ("Illegal argument ('"+value+"') to set property "
++XMLStreamProperties.XSP_SUPPORT_XMLID+" to: has to be one of '"
++XMLStreamProperties.XSP_V_XMLID_NONE+"', '"+XMLStreamProperties.XSP_V_XMLID_TYPING+"' or '"+XMLStreamProperties.XSP_V_XMLID_FULL+"'"
+ );
+ }
+ setConfigFlag(CFG_XMLID_TYPING, typing);
+ setConfigFlag(CFG_XMLID_UNIQ_CHECKS, uniq);
+ }
+ break;
+
+ case PROP_DTD_OVERRIDE:
+ setDTDOverride((DTDValidationSchema) value);
+ break;
+
+ // // // And then Woodstox specific, flags
+
+ case PROP_CACHE_DTDS:
+ doCacheDTDs(ArgUtil.convertToBoolean(propName, value));
+ break;
+
+ case PROP_CACHE_DTDS_BY_PUBLIC_ID:
+ doCacheDTDsByPublicId(ArgUtil.convertToBoolean(propName, value));
+ break;
+
+ case PROP_LAZY_PARSING:
+ doParseLazily(ArgUtil.convertToBoolean(propName, value));
+ break;
+
+ case PROP_TREAT_CHAR_REFS_AS_ENTS:
+ doTreatCharRefsAsEnts(ArgUtil.convertToBoolean(propName, value));
+ break;
+
+ case PROP_NORMALIZE_LFS:
+ doNormalizeLFs(ArgUtil.convertToBoolean(propName, value));
+ break;
+
+ // // // And then Woodstox specific, enum/object:
+
+ case PROP_INPUT_BUFFER_LENGTH:
+ setInputBufferLength(ArgUtil.convertToInt(propName, value, 1));
+ break;
+
+ case PROP_MAX_ATTRIBUTES_PER_ELEMENT:
+ setMaxAttributesPerElement(ArgUtil.convertToInt(propName, value, 1));
+ break;
+ case PROP_MAX_ATTRIBUTE_SIZE:
+ setMaxAttributeSize(ArgUtil.convertToInt(propName, value, 1));
+ break;
+ case PROP_MAX_CHILDREN_PER_ELEMENT:
+ setMaxChildrenPerElement(ArgUtil.convertToInt(propName, value, 1));
+ break;
+ case PROP_MAX_ELEMENT_DEPTH:
+ setMaxElementDepth(ArgUtil.convertToInt(propName, value, 1));
+ break;
+ case PROP_MAX_ELEMENT_COUNT:
+ setMaxElementCount(ArgUtil.convertToLong(propName, value, 1));
+ break;
+ case PROP_MAX_CHARACTERS:
+ setMaxCharacters(ArgUtil.convertToLong(propName, value, 1));
+ break;
+ case PROP_MAX_TEXT_LENGTH:
+ setMaxTextLength(ArgUtil.convertToInt(propName, value, 1));
+ break;
+ case PROP_MAX_ENTITY_DEPTH:
+ setMaxEntityDepth(ArgUtil.convertToInt(propName, value, 1));
+ break;
+ case PROP_MAX_ENTITY_COUNT:
+ setMaxEntityCount(ArgUtil.convertToLong(propName, value, 1));
+ break;
+
+ case PROP_MIN_TEXT_SEGMENT:
+ setShortestReportedTextSegment(ArgUtil.convertToInt(propName, value, 1));
+ break;
+
+ case PROP_CUSTOM_INTERNAL_ENTITIES:
+ {
+ @SuppressWarnings("unchecked")
+ Map arg = (Map) value;
+ setCustomInternalEntities(arg);
+ }
+ break;
+
+ case PROP_DTD_RESOLVER:
+ setDtdResolver((XMLResolver) value);
+ break;
+
+ case PROP_ENTITY_RESOLVER:
+ setEntityResolver((XMLResolver) value);
+ break;
+
+ case PROP_UNDECLARED_ENTITY_RESOLVER:
+ setUndeclaredEntityResolver((XMLResolver) value);
+ break;
+
+ case PROP_BASE_URL:
+ /* 17-Nov-2008, TSa: Let's make it bit more versatile; if it's not
+ * a URL per se, let's assume it is something that we can convert
+ * to URL
+ */
+ {
+ URL u;
+ if (value == null) {
+ u = null;
+ } else if (value instanceof URL) {
+ u = (URL) value;
+ } else {
+ try {
+ u = new URL(value.toString());
+ } catch (Exception ioe) { // MalformedURLException actually...
+ throw new IllegalArgumentException(ioe.getMessage(), ioe);
+ }
+ }
+ setBaseURL(u);
+ }
+ break;
+
+ case PROP_INPUT_PARSING_MODE:
+ setInputParsingMode((WstxInputProperties.ParsingMode) value);
+ break;
+
+ default: // sanity check, should never happen
+ throw new IllegalStateException("Internal error: no handler for property with internal id "+id+".");
+ }
+
+ return true;
+ }
+
+ protected boolean _hasConfigFlag(int flag) {
+ return (mConfigFlags & flag) != 0;
+ }
+
+ /**
+ * Method similar to {@link #_hasConfigFlag}, but that will only
+ * return true if in addition to being set, flag has been explicitly
+ * modified (i.e. setProperty has been called to modify it)
+ */
+ protected boolean _hasExplicitConfigFlag(int flag) {
+ return _hasConfigFlag(flag) && (mConfigFlagMods & flag) != 0;
+ }
+
+ private final Object _getSpecialProperty(int ix)
+ {
+ if (mSpecialProperties == null) {
+ return null;
+ }
+ return mSpecialProperties[ix];
+ }
+
+ private final void _setSpecialProperty(int ix, Object value)
+ {
+ if (mSpecialProperties == null) {
+ mSpecialProperties = new Object[SPEC_PROC_COUNT];
+ }
+ mSpecialProperties[ix] = value;
+ }
+}
diff -Nru libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/api/ValidatorConfig.java libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/api/ValidatorConfig.java
--- libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/api/ValidatorConfig.java 1970-01-01 00:00:00.000000000 +0000
+++ libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/api/ValidatorConfig.java 2018-03-31 01:33:28.000000000 +0000
@@ -0,0 +1,42 @@
+package com.ctc.wstx.api;
+
+public final class ValidatorConfig
+ extends CommonConfig
+{
+ /**
+ * For now, since there are no mutable properties, we can share
+ * a singleton instance.
+ */
+ final static ValidatorConfig sInstance = new ValidatorConfig(null);
+
+ private ValidatorConfig(ValidatorConfig base) {
+ super(base);
+ }
+
+ public static ValidatorConfig createDefaults()
+ {
+ /* For now, since there are no mutable properties, we can share
+ * a singleton instance.
+ */
+ return sInstance;
+ }
+
+ @Override
+ protected int findPropertyId(String propName) {
+ // Nothing above and beyond default settings...
+ return -1;
+ }
+
+ @Override
+ protected Object getProperty(int id) {
+ // nothing to get:
+ return null;
+ }
+
+ @Override
+ protected boolean setProperty(String propName, int id, Object value) {
+ // nothing to set:
+ return false;
+ }
+}
+
diff -Nru libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/api/WriterConfig.java libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/api/WriterConfig.java
--- libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/api/WriterConfig.java 1970-01-01 00:00:00.000000000 +0000
+++ libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/api/WriterConfig.java 2018-03-31 01:33:28.000000000 +0000
@@ -0,0 +1,900 @@
+package com.ctc.wstx.api;
+
+import java.lang.ref.SoftReference;
+import java.util.HashMap;
+
+import javax.xml.stream.XMLOutputFactory;
+import javax.xml.stream.XMLReporter;
+
+import org.codehaus.stax2.XMLOutputFactory2;
+import org.codehaus.stax2.XMLStreamProperties;
+import org.codehaus.stax2.io.EscapingWriterFactory;
+
+import com.ctc.wstx.cfg.OutputConfigFlags;
+import com.ctc.wstx.io.BufferRecycler;
+import com.ctc.wstx.util.ArgUtil;
+import com.ctc.wstx.util.DataUtil;
+// for property consts
+
+/**
+ * Simple configuration container class; passed by writer factory to writer
+ * instance created.
+ */
+public final class WriterConfig
+ extends CommonConfig
+ implements OutputConfigFlags
+{
+ // // // Constants for standard Stax properties:
+
+ protected final static String DEFAULT_AUTOMATIC_NS_PREFIX = "wstxns";
+
+ // // // First, standard Stax writer properties
+
+ final static int PROP_AUTOMATIC_NS = 1; // standard property ("repairing")
+
+ // // // And then additional Stax2 properties:
+
+ // General output settings
+ final static int PROP_AUTOMATIC_EMPTY_ELEMENTS = 2;
+ final static int PROP_AUTO_CLOSE_OUTPUT = 3;
+ // Namespace settings:
+ final static int PROP_ENABLE_NS = 4;
+ final static int PROP_AUTOMATIC_NS_PREFIX = 5;
+ // Escaping text content/attr values:
+ final static int PROP_TEXT_ESCAPER = 6;
+ final static int PROP_ATTR_VALUE_ESCAPER = 7;
+ // Problem checking/reporting options
+ final static int PROP_PROBLEM_REPORTER = 8;
+
+ // // // And then custom Wstx properties:
+
+ // Output settings:
+ final static int PROP_USE_DOUBLE_QUOTES_IN_XML_DECL = 10;
+
+ final static int PROP_OUTPUT_CDATA_AS_TEXT = 11;
+
+ final static int PROP_COPY_DEFAULT_ATTRS = 12;
+
+ final static int PROP_ESCAPE_CR = 13;
+
+ final static int PROP_ADD_SPACE_AFTER_EMPTY_ELEM = 14;
+
+ final static int PROP_AUTOMATIC_END_ELEMENTS = 15;
+
+ // Validation flags:
+
+ final static int PROP_VALIDATE_STRUCTURE = 16;
+ final static int PROP_VALIDATE_CONTENT = 17;
+ final static int PROP_VALIDATE_ATTR = 18;
+ final static int PROP_VALIDATE_NAMES = 19;
+ final static int PROP_FIX_CONTENT = 20;
+
+ // Other:
+
+ final static int PROP_OUTPUT_INVALID_CHAR_HANDLER = 21;
+ final static int PROP_OUTPUT_EMPTY_ELEMENT_HANDLER = 22;
+
+ // Per-writer instance information
+
+ final static int PROP_UNDERLYING_STREAM = 30;
+ final static int PROP_UNDERLYING_WRITER = 31;
+
+ // // // Default settings for additional properties:
+
+ /* 18-May-2013, feature request WSTX-291
+ */
+ final static boolean DEFAULT_USE_DOUBLE_QUOTES_IN_XML_DECL = false;
+
+ final static boolean DEFAULT_OUTPUT_CDATA_AS_TEXT = false;
+ final static boolean DEFAULT_COPY_DEFAULT_ATTRS = false;
+
+ /* 26-Dec-2006, TSa: Since CRs have been auto-escaped so far, let's
+ * retain the defaults when adding new properties/features.
+ */
+ final static boolean DEFAULT_ESCAPE_CR = true;
+
+ /**
+ * 09-Aug-2007, TSa: Space has always been added after empty
+ * element (before closing "/>"), but now it is configurable.
+ * 31-Dec-2009, TSa: Intention was to leave it enabled for backwards
+ * compatibility: but due to a bug this was NOT the case... ugh.
+ */
+ final static boolean DEFAULT_ADD_SPACE_AFTER_EMPTY_ELEM = false;
+
+ /* How about validation? Let's turn them mostly off by default, since
+ * there are some performance hits when enabling them.
+ */
+
+ // Structural checks are easy, cheap and useful...
+ final static boolean DEFAULT_VALIDATE_STRUCTURE = true;
+
+ /* 17-May-2006, TSa: Since content validation is now much cheaper
+ * (due to integrated transcoders) than it used to be, let's
+ * just enable content validation too.
+ */
+ final static boolean DEFAULT_VALIDATE_CONTENT = true;
+ final static boolean DEFAULT_VALIDATE_ATTR = false;
+ final static boolean DEFAULT_VALIDATE_NAMES = false;
+
+ // This only matters if content validation is enabled...
+ /**
+ * As per [WSTX-120], default was changed to false,
+ * from true (default prior to wstx 4.0)
+ */
+ //final static boolean DEFAULT_FIX_CONTENT = true;
+ final static boolean DEFAULT_FIX_CONTENT = false;
+
+ /**
+ * Default config flags are converted from individual settings,
+ * to conform to Stax 1.0 specifications.
+ */
+ final static int DEFAULT_FLAGS_J2ME =
+ 0
+
+ // Stax 1.0 mandated:
+
+ // namespace-awareness assumed; repairing disabled by default:
+ // | CFG_AUTOMATIC_NS
+ | CFG_ENABLE_NS
+
+ // Usually it's good to allow writer to produce empty elems
+ // (note: default for woodstox 1.x was false)
+ | CFG_AUTOMATIC_EMPTY_ELEMENTS
+
+ | (DEFAULT_USE_DOUBLE_QUOTES_IN_XML_DECL ? CFG_USE_DOUBLE_QUOTES_IN_XML_DECL : 0)
+ | (DEFAULT_OUTPUT_CDATA_AS_TEXT ? CFG_OUTPUT_CDATA_AS_TEXT : 0)
+ | (DEFAULT_COPY_DEFAULT_ATTRS ? CFG_COPY_DEFAULT_ATTRS : 0)
+ | (DEFAULT_ESCAPE_CR ? CFG_ESCAPE_CR : 0)
+ | (DEFAULT_ADD_SPACE_AFTER_EMPTY_ELEM ? CFG_ADD_SPACE_AFTER_EMPTY_ELEM : 0)
+ | CFG_AUTOMATIC_END_ELEMENTS
+
+ | (DEFAULT_VALIDATE_STRUCTURE ? CFG_VALIDATE_STRUCTURE : 0)
+ | (DEFAULT_VALIDATE_CONTENT ? CFG_VALIDATE_CONTENT : 0)
+ | (DEFAULT_VALIDATE_ATTR ? CFG_VALIDATE_ATTR : 0)
+ | (DEFAULT_VALIDATE_NAMES ? CFG_VALIDATE_NAMES : 0)
+ | (DEFAULT_FIX_CONTENT ? CFG_FIX_CONTENT : 0)
+
+ // As per Stax 1.0 specs, we can not enable this by default:
+ //| CFG_AUTO_CLOSE_INPUT);
+ ;
+
+ /**
+ * For now, full instances start with same settings as J2ME subset
+ */
+ final static int DEFAULT_FLAGS_FULL = DEFAULT_FLAGS_J2ME;
+
+ // // //
+
+ /**
+ * Map to use for converting from String property ids to ints
+ * described above; useful to allow use of switch later on.
+ */
+ final static HashMap sProperties = new HashMap(8);
+ static {
+ // // Stax (1.0) standard ones:
+ sProperties.put(XMLOutputFactory.IS_REPAIRING_NAMESPACES,
+ DataUtil.Integer(PROP_AUTOMATIC_NS));
+
+ // // Stax2 standard ones:
+
+ // Namespace support
+ sProperties.put(XMLStreamProperties.XSP_NAMESPACE_AWARE,
+ DataUtil.Integer(PROP_ENABLE_NS));
+
+ // Generic output
+ sProperties.put(XMLOutputFactory2.P_AUTOMATIC_EMPTY_ELEMENTS,
+ DataUtil.Integer(PROP_AUTOMATIC_EMPTY_ELEMENTS));
+ sProperties.put(XMLOutputFactory2.P_AUTO_CLOSE_OUTPUT,
+ DataUtil.Integer(PROP_AUTO_CLOSE_OUTPUT));
+ // Namespace support
+ sProperties.put(XMLOutputFactory2.P_AUTOMATIC_NS_PREFIX,
+ DataUtil.Integer(PROP_AUTOMATIC_NS_PREFIX));
+ // Text/attr value escaping (customized escapers)
+ sProperties.put(XMLOutputFactory2.P_TEXT_ESCAPER,
+ DataUtil.Integer(PROP_TEXT_ESCAPER));
+ sProperties.put(XMLOutputFactory2.P_ATTR_VALUE_ESCAPER,
+ DataUtil.Integer(PROP_ATTR_VALUE_ESCAPER));
+ // Problem checking/reporting options
+ sProperties.put(XMLStreamProperties.XSP_PROBLEM_REPORTER,
+ DataUtil.Integer(PROP_PROBLEM_REPORTER));
+
+ // // Woodstox-specifics:
+
+ // Output conversions
+ sProperties.put(WstxOutputProperties.P_USE_DOUBLE_QUOTES_IN_XML_DECL,
+ DataUtil.Integer(PROP_USE_DOUBLE_QUOTES_IN_XML_DECL));
+ sProperties.put(WstxOutputProperties.P_OUTPUT_CDATA_AS_TEXT,
+ DataUtil.Integer(PROP_OUTPUT_CDATA_AS_TEXT));
+ sProperties.put(WstxOutputProperties.P_COPY_DEFAULT_ATTRS,
+ DataUtil.Integer(PROP_COPY_DEFAULT_ATTRS));
+ sProperties.put(WstxOutputProperties.P_OUTPUT_ESCAPE_CR,
+ DataUtil.Integer(PROP_ESCAPE_CR));
+ sProperties.put(WstxOutputProperties.P_ADD_SPACE_AFTER_EMPTY_ELEM,
+ DataUtil.Integer(PROP_ADD_SPACE_AFTER_EMPTY_ELEM));
+ sProperties.put(WstxOutputProperties.P_AUTOMATIC_END_ELEMENTS,
+ DataUtil.Integer(PROP_AUTOMATIC_END_ELEMENTS));
+ sProperties.put(WstxOutputProperties.P_OUTPUT_INVALID_CHAR_HANDLER,
+ DataUtil.Integer(PROP_OUTPUT_INVALID_CHAR_HANDLER));
+ sProperties.put(WstxOutputProperties.P_OUTPUT_EMPTY_ELEMENT_HANDLER,
+ DataUtil.Integer(PROP_OUTPUT_EMPTY_ELEMENT_HANDLER));
+
+ // Validation settings:
+ sProperties.put(WstxOutputProperties.P_OUTPUT_VALIDATE_STRUCTURE,
+ DataUtil.Integer(PROP_VALIDATE_STRUCTURE));
+ sProperties.put(WstxOutputProperties.P_OUTPUT_VALIDATE_CONTENT,
+ DataUtil.Integer(PROP_VALIDATE_CONTENT));
+ sProperties.put(WstxOutputProperties.P_OUTPUT_VALIDATE_ATTR,
+ DataUtil.Integer(PROP_VALIDATE_ATTR));
+ sProperties.put(WstxOutputProperties.P_OUTPUT_VALIDATE_NAMES,
+ DataUtil.Integer(PROP_VALIDATE_NAMES));
+ sProperties.put(WstxOutputProperties.P_OUTPUT_FIX_CONTENT,
+ DataUtil.Integer(PROP_FIX_CONTENT));
+
+ // Underlying stream/writer access
+ sProperties.put(WstxOutputProperties.P_OUTPUT_UNDERLYING_STREAM,
+ DataUtil.Integer(PROP_UNDERLYING_STREAM));
+ sProperties.put(WstxOutputProperties.P_OUTPUT_UNDERLYING_STREAM,
+ DataUtil.Integer(PROP_UNDERLYING_STREAM));
+ }
+
+ /*
+ //////////////////////////////////////////////////////////
+ // Current config state:
+ //////////////////////////////////////////////////////////
+ */
+
+ final boolean mIsJ2MESubset;
+
+ protected int mConfigFlags;
+
+ /*
+ //////////////////////////////////////////////////////////
+ // More special(ized) configuration objects
+ //////////////////////////////////////////////////////////
+ */
+
+ //protected String mAutoNsPrefix;
+ //protected EscapingWriterFactory mTextEscaperFactory = null;
+ //protected EscapingWriterFactory mAttrValueEscaperFactory = null;
+ //protected XMLReporter mProblemReporter = null;
+ //protected InvalidCharHandler mInvalidCharHandler = null;
+
+ Object[] mSpecialProperties = null;
+
+ private final static int SPEC_PROC_COUNT = 6;
+
+ private final static int SP_IX_AUTO_NS_PREFIX = 0;
+ private final static int SP_IX_TEXT_ESCAPER_FACTORY = 1;
+ private final static int SP_IX_ATTR_VALUE_ESCAPER_FACTORY = 2;
+ private final static int SP_IX_PROBLEM_REPORTER = 3;
+ private final static int SP_IX_INVALID_CHAR_HANDLER = 4;
+ private final static int SP_IX_EMPTY_ELEMENT_HANDLER = 5;
+
+ /*
+ //////////////////////////////////////////////////////////
+ // Buffer recycling:
+ //////////////////////////////////////////////////////////
+ */
+
+ /**
+ * This ThreadLocal
contains a {@link SoftRerefence}
+ * to a {@link BufferRecycler} used to provide a low-cost
+ * buffer recycling between Reader instances.
+ */
+ final static ThreadLocal> mRecyclerRef = new ThreadLocal>();
+
+ /**
+ * This is the actually container of the recyclable buffers. It
+ * is obtained via ThreadLocal/SoftReference combination, if one
+ * exists, when Config instance is created. If one does not
+ * exists, it will created first time a buffer is returned.
+ */
+ BufferRecycler mCurrRecycler = null;
+
+ /*
+ //////////////////////////////////////////////////////////
+ // Life-cycle:
+ //////////////////////////////////////////////////////////
+ */
+
+ private WriterConfig(WriterConfig base,
+ boolean j2meSubset, int flags, Object[] specProps)
+ {
+ super(base);
+ mIsJ2MESubset = j2meSubset;
+ mConfigFlags = flags;
+ mSpecialProperties = specProps;
+
+ /* Ok, let's then see if we can find a buffer recycler. Since they
+ * are lazily constructed, and since GC may just flush them out
+ * on its whims, it's possible we might not find one. That's ok;
+ * we can reconstruct one if and when we are to return one or more
+ * buffers.
+ */
+ SoftReference ref = mRecyclerRef.get();
+ if (ref != null) {
+ mCurrRecycler = ref.get();
+ }
+ }
+
+ public static WriterConfig createJ2MEDefaults()
+ {
+ return new WriterConfig(null, true, DEFAULT_FLAGS_J2ME, null);
+ }
+
+ public static WriterConfig createFullDefaults()
+ {
+ return new WriterConfig(null, false, DEFAULT_FLAGS_FULL, null);
+ }
+
+ public WriterConfig createNonShared()
+ {
+ Object[] specProps;
+
+ if (mSpecialProperties != null) {
+ int len = mSpecialProperties.length;
+ specProps = new Object[len];
+ System.arraycopy(mSpecialProperties, 0, specProps, 0, len);
+ } else {
+ specProps = null;
+ }
+ return new WriterConfig(this, mIsJ2MESubset, mConfigFlags, specProps);
+ }
+
+ /*
+ //////////////////////////////////////////////////////////
+ // Implementation of abstract methods
+ //////////////////////////////////////////////////////////
+ */
+
+ @Override
+ protected int findPropertyId(String propName)
+ {
+ Integer I = sProperties.get(propName);
+ return (I == null) ? -1 : I.intValue();
+ }
+
+ /*
+ //////////////////////////////////////////////////////////
+ // Public API
+ //////////////////////////////////////////////////////////
+ */
+
+ @Override
+ public Object getProperty(int id)
+ {
+ switch (id) {
+
+ // First, Stax 1.0 properties:
+
+ case PROP_AUTOMATIC_NS:
+ return automaticNamespacesEnabled() ? Boolean.TRUE : Boolean.FALSE;
+
+ // Then Stax2 properties:
+
+ // First, properties common to input/output factories:
+
+ case PROP_ENABLE_NS:
+ return willSupportNamespaces() ? Boolean.TRUE : Boolean.FALSE;
+ case PROP_PROBLEM_REPORTER:
+ return getProblemReporter();
+
+ // Then output-specific properties:
+ case PROP_AUTOMATIC_EMPTY_ELEMENTS:
+ return automaticEmptyElementsEnabled() ? Boolean.TRUE : Boolean.FALSE;
+ case PROP_AUTO_CLOSE_OUTPUT:
+ return willAutoCloseOutput() ? Boolean.TRUE : Boolean.FALSE;
+ case PROP_AUTOMATIC_NS_PREFIX:
+ return getAutomaticNsPrefix();
+ case PROP_TEXT_ESCAPER:
+ return getTextEscaperFactory();
+ case PROP_ATTR_VALUE_ESCAPER:
+ return getAttrValueEscaperFactory();
+
+ // // // Then Woodstox-specific properties:
+
+ case PROP_USE_DOUBLE_QUOTES_IN_XML_DECL:
+ return willUseDoubleQuotesInXmlDecl() ? Boolean.TRUE : Boolean.FALSE;
+ case PROP_OUTPUT_CDATA_AS_TEXT:
+ return willOutputCDataAsText() ? Boolean.TRUE : Boolean.FALSE;
+ case PROP_COPY_DEFAULT_ATTRS:
+ return willCopyDefaultAttrs() ? Boolean.TRUE : Boolean.FALSE;
+ case PROP_ESCAPE_CR:
+ return willEscapeCr() ? Boolean.TRUE : Boolean.FALSE;
+ case PROP_ADD_SPACE_AFTER_EMPTY_ELEM:
+ return willAddSpaceAfterEmptyElem() ? Boolean.TRUE : Boolean.FALSE;
+ case PROP_AUTOMATIC_END_ELEMENTS:
+ return automaticEndElementsEnabled() ? Boolean.TRUE : Boolean.FALSE;
+
+ case PROP_VALIDATE_STRUCTURE:
+ return willValidateStructure() ? Boolean.TRUE : Boolean.FALSE;
+ case PROP_VALIDATE_CONTENT:
+ return willValidateContent() ? Boolean.TRUE : Boolean.FALSE;
+ case PROP_VALIDATE_ATTR:
+ return willValidateAttributes() ? Boolean.TRUE : Boolean.FALSE;
+ case PROP_VALIDATE_NAMES:
+ return willValidateNames() ? Boolean.TRUE : Boolean.FALSE;
+ case PROP_FIX_CONTENT:
+ return willFixContent() ? Boolean.TRUE : Boolean.FALSE;
+ case PROP_OUTPUT_INVALID_CHAR_HANDLER:
+ return getInvalidCharHandler();
+ case PROP_OUTPUT_EMPTY_ELEMENT_HANDLER:
+ return getEmptyElementHandler();
+
+ // And then per-instance properties: not valid via config object
+ case PROP_UNDERLYING_STREAM:
+ case PROP_UNDERLYING_WRITER:
+ throw new IllegalStateException("Can not access per-stream-writer properties via factory");
+ }
+
+ throw new IllegalStateException("Internal error: no handler for property with internal id "+id+".");
+ }
+
+ /**
+ * @return True, if the specified property was succesfully
+ * set to specified value; false if its value was not changed
+ */
+ @Override
+ public boolean setProperty(String name, int id, Object value)
+ {
+ switch (id) {
+ // First, Stax 1.0 properties:
+
+ case PROP_AUTOMATIC_NS:
+ enableAutomaticNamespaces(ArgUtil.convertToBoolean(name, value));
+ break;
+
+ // // // Then Stax2 ones:
+
+ case PROP_ENABLE_NS:
+ doSupportNamespaces(ArgUtil.convertToBoolean(name, value));
+ break;
+ case PROP_PROBLEM_REPORTER:
+ setProblemReporter((XMLReporter) value);
+ break;
+
+ case PROP_AUTOMATIC_EMPTY_ELEMENTS:
+ enableAutomaticEmptyElements(ArgUtil.convertToBoolean(name, value));
+ break;
+
+ case PROP_AUTO_CLOSE_OUTPUT:
+ doAutoCloseOutput(ArgUtil.convertToBoolean(name, value));
+ break;
+
+ case PROP_AUTOMATIC_NS_PREFIX:
+ // value should be a String, but let's verify that:
+ setAutomaticNsPrefix(value.toString());
+ break;
+
+ case PROP_TEXT_ESCAPER:
+ setTextEscaperFactory((EscapingWriterFactory) value);
+ break;
+
+ case PROP_ATTR_VALUE_ESCAPER:
+ setAttrValueEscaperFactory((EscapingWriterFactory) value);
+ break;
+
+ // // // Then Woodstox-specific ones:
+
+ case PROP_USE_DOUBLE_QUOTES_IN_XML_DECL:
+ doUseDoubleQuotesInXmlDecl(ArgUtil.convertToBoolean(name, value));
+ break;
+ case PROP_OUTPUT_CDATA_AS_TEXT:
+ doOutputCDataAsText(ArgUtil.convertToBoolean(name, value));
+ break;
+ case PROP_COPY_DEFAULT_ATTRS:
+ doCopyDefaultAttrs(ArgUtil.convertToBoolean(name, value));
+ break;
+ case PROP_ESCAPE_CR:
+ doEscapeCr(ArgUtil.convertToBoolean(name, value));
+ break;
+ case PROP_ADD_SPACE_AFTER_EMPTY_ELEM:
+ doAddSpaceAfterEmptyElem(ArgUtil.convertToBoolean(name, value));
+ break;
+ case PROP_AUTOMATIC_END_ELEMENTS:
+ enableAutomaticEndElements(ArgUtil.convertToBoolean(name, value));
+ break;
+ case PROP_VALIDATE_STRUCTURE:
+ doValidateStructure(ArgUtil.convertToBoolean(name, value));
+ break;
+ case PROP_VALIDATE_CONTENT:
+ doValidateContent(ArgUtil.convertToBoolean(name, value));
+ break;
+ case PROP_VALIDATE_ATTR:
+ doValidateAttributes(ArgUtil.convertToBoolean(name, value));
+ break;
+ case PROP_VALIDATE_NAMES:
+ doValidateNames(ArgUtil.convertToBoolean(name, value));
+ break;
+ case PROP_FIX_CONTENT:
+ doFixContent(ArgUtil.convertToBoolean(name, value));
+ break;
+ case PROP_OUTPUT_INVALID_CHAR_HANDLER:
+ setInvalidCharHandler((InvalidCharHandler) value);
+ break;
+ case PROP_OUTPUT_EMPTY_ELEMENT_HANDLER:
+ setEmptyElementHandler((EmptyElementHandler) value);
+ break;
+
+ case PROP_UNDERLYING_STREAM:
+ case PROP_UNDERLYING_WRITER:
+ throw new IllegalStateException("Can not modify per-stream-writer properties via factory");
+
+ default:
+ throw new IllegalStateException("Internal error: no handler for property with internal id "+id+".");
+ }
+
+ return true;
+ }
+
+ /*
+ //////////////////////////////////////////////////////////
+ // Extended Woodstox API, accessors/modifiers
+ //////////////////////////////////////////////////////////
+ */
+
+ // // // "Raw" accessors for on/off properties:
+
+ public int getConfigFlags() { return mConfigFlags; }
+
+
+ // // // Accessors, standard properties:
+
+ public boolean automaticNamespacesEnabled() {
+ return hasConfigFlag(CFG_AUTOMATIC_NS);
+ }
+
+ // // // Accessors, Woodstox properties:
+
+ public boolean automaticEmptyElementsEnabled() {
+ return hasConfigFlag(CFG_AUTOMATIC_EMPTY_ELEMENTS);
+ }
+
+ public boolean willAutoCloseOutput() {
+ return hasConfigFlag(CFG_AUTO_CLOSE_OUTPUT);
+ }
+
+ public boolean willSupportNamespaces() {
+ return hasConfigFlag(CFG_ENABLE_NS);
+ }
+
+ /**
+ * @since 4.2.2
+ */
+ public boolean willUseDoubleQuotesInXmlDecl() {
+ return hasConfigFlag(CFG_USE_DOUBLE_QUOTES_IN_XML_DECL);
+ }
+
+ public boolean willOutputCDataAsText() {
+ return hasConfigFlag(CFG_OUTPUT_CDATA_AS_TEXT);
+ }
+
+ public boolean willCopyDefaultAttrs() {
+ return hasConfigFlag(CFG_COPY_DEFAULT_ATTRS);
+ }
+
+ public boolean willEscapeCr() {
+ return hasConfigFlag(CFG_ESCAPE_CR);
+ }
+
+ public boolean willAddSpaceAfterEmptyElem() {
+ return hasConfigFlag(CFG_ADD_SPACE_AFTER_EMPTY_ELEM);
+ }
+
+ public boolean automaticEndElementsEnabled() {
+ return hasConfigFlag(CFG_AUTOMATIC_END_ELEMENTS);
+ }
+
+ public boolean willValidateStructure() {
+ return hasConfigFlag(CFG_VALIDATE_STRUCTURE);
+ }
+
+ public boolean willValidateContent() {
+ return hasConfigFlag(CFG_VALIDATE_CONTENT);
+ }
+
+ public boolean willValidateAttributes() {
+ return hasConfigFlag(CFG_VALIDATE_ATTR);
+ }
+
+ public boolean willValidateNames() {
+ return hasConfigFlag(CFG_VALIDATE_NAMES);
+ }
+
+ public boolean willFixContent() {
+ return hasConfigFlag(CFG_FIX_CONTENT);
+ }
+
+ /**
+ * @return Prefix to use as the base for automatically generated
+ * namespace prefixes ("namespace prefix prefix", so to speak).
+ * Defaults to "wstxns".
+ */
+ public String getAutomaticNsPrefix() {
+ String prefix = (String) getSpecialProperty(SP_IX_AUTO_NS_PREFIX);
+ if (prefix == null) {
+ prefix = DEFAULT_AUTOMATIC_NS_PREFIX;
+ }
+ return prefix;
+ }
+
+ public EscapingWriterFactory getTextEscaperFactory() {
+ return (EscapingWriterFactory) getSpecialProperty(SP_IX_TEXT_ESCAPER_FACTORY);
+ }
+
+ public EscapingWriterFactory getAttrValueEscaperFactory() {
+ return (EscapingWriterFactory) getSpecialProperty(SP_IX_ATTR_VALUE_ESCAPER_FACTORY);
+ }
+
+ public XMLReporter getProblemReporter() {
+ return (XMLReporter) getSpecialProperty(SP_IX_PROBLEM_REPORTER);
+ }
+
+ public InvalidCharHandler getInvalidCharHandler() {
+ return (InvalidCharHandler) getSpecialProperty(SP_IX_INVALID_CHAR_HANDLER);
+ }
+
+ public EmptyElementHandler getEmptyElementHandler() {
+ return (EmptyElementHandler) getSpecialProperty(SP_IX_EMPTY_ELEMENT_HANDLER);
+ }
+
+ // // // Mutators:
+
+ // Standard properies:
+
+ public void enableAutomaticNamespaces(boolean state) {
+ setConfigFlag(CFG_AUTOMATIC_NS, state);
+ }
+
+ // Wstx properies:
+
+ public void enableAutomaticEmptyElements(boolean state) {
+ setConfigFlag(CFG_AUTOMATIC_EMPTY_ELEMENTS, state);
+ }
+
+ public void doAutoCloseOutput(boolean state) {
+ setConfigFlag(CFG_AUTO_CLOSE_OUTPUT, state);
+ }
+
+ public void doSupportNamespaces(boolean state) {
+ setConfigFlag(CFG_ENABLE_NS, state);
+ }
+
+ /**
+ * @since 4.2.2
+ */
+ public void doUseDoubleQuotesInXmlDecl(boolean state) {
+ setConfigFlag(CFG_USE_DOUBLE_QUOTES_IN_XML_DECL, state);
+ }
+
+ public void doOutputCDataAsText(boolean state) {
+ setConfigFlag(CFG_OUTPUT_CDATA_AS_TEXT, state);
+ }
+
+ public void doCopyDefaultAttrs(boolean state) {
+ setConfigFlag(CFG_COPY_DEFAULT_ATTRS, state);
+ }
+
+ public void doEscapeCr(boolean state) {
+ setConfigFlag(CFG_ESCAPE_CR, state);
+ }
+
+ public void doAddSpaceAfterEmptyElem(boolean state) {
+ setConfigFlag(CFG_ADD_SPACE_AFTER_EMPTY_ELEM, state);
+ }
+
+ public void enableAutomaticEndElements(boolean state) {
+ setConfigFlag(CFG_AUTOMATIC_END_ELEMENTS, state);
+ }
+
+ public void doValidateStructure(boolean state) {
+ setConfigFlag(CFG_VALIDATE_STRUCTURE, state);
+ }
+
+ public void doValidateContent(boolean state) {
+ setConfigFlag(CFG_VALIDATE_CONTENT, state);
+ }
+
+ public void doValidateAttributes(boolean state) {
+ setConfigFlag(CFG_VALIDATE_ATTR, state);
+ }
+
+ public void doValidateNames(boolean state) {
+ setConfigFlag(CFG_VALIDATE_NAMES, state);
+ }
+
+ public void doFixContent(boolean state) {
+ setConfigFlag(CFG_FIX_CONTENT, state);
+ }
+
+ /**
+ * @param prefix Prefix to use as the base for automatically generated
+ * namespace prefixes ("namespace prefix prefix", so to speak).
+ */
+ public void setAutomaticNsPrefix(String prefix) {
+ setSpecialProperty(SP_IX_AUTO_NS_PREFIX, prefix);
+ }
+
+ public void setTextEscaperFactory(EscapingWriterFactory f) {
+ setSpecialProperty(SP_IX_TEXT_ESCAPER_FACTORY, f);
+ }
+
+ public void setAttrValueEscaperFactory(EscapingWriterFactory f) {
+ setSpecialProperty(SP_IX_ATTR_VALUE_ESCAPER_FACTORY, f);
+ }
+
+ public void setProblemReporter(XMLReporter rep) {
+ setSpecialProperty(SP_IX_PROBLEM_REPORTER, rep);
+ }
+
+ public void setInvalidCharHandler(InvalidCharHandler h) {
+ setSpecialProperty(SP_IX_INVALID_CHAR_HANDLER, h);
+ }
+
+ public void setEmptyElementHandler(EmptyElementHandler h) {
+ setSpecialProperty(SP_IX_EMPTY_ELEMENT_HANDLER, h);
+ }
+
+ /*
+ //////////////////////////////////////////////////////////
+ // Extended Woodstox API, profiles
+ //////////////////////////////////////////////////////////
+ */
+
+ /**
+ * For Woodstox, this profile enables all basic well-formedness checks,
+ * including checking for name validity.
+ */
+ public void configureForXmlConformance()
+ {
+ doValidateAttributes(true);
+ doValidateContent(true);
+ doValidateStructure(true);
+ doValidateNames(true);
+ }
+
+ /**
+ * For Woodstox, this profile enables all basic well-formedness checks,
+ * including checking for name validity, and also enables all matching
+ * "fix-me" properties (currently only content-fixing property exists).
+ */
+ public void configureForRobustness()
+ {
+ doValidateAttributes(true);
+ doValidateStructure(true);
+ doValidateNames(true);
+
+ /* This the actual "meat": we do want to not only check if the
+ * content is ok, but also "fix" it if not, and if there's a way
+ * to fix it:
+ */
+ doValidateContent(true);
+ doFixContent(true);
+ }
+
+ /**
+ * For Woodstox, setting this profile disables most checks for validity;
+ * specifically anything that can have measurable performance impact.
+ *
+ */
+ public void configureForSpeed()
+ {
+ doValidateAttributes(false);
+ doValidateContent(false);
+ doValidateNames(false);
+
+ // Structural validation is cheap: can be left enabled (if already so)
+ //doValidateStructure(false);
+ }
+
+ /*
+ /////////////////////////////////////////////////////
+ // Buffer recycling:
+ /////////////////////////////////////////////////////
+ */
+
+ /**
+ * Method called to allocate intermediate recyclable copy buffers
+ */
+ public char[] allocMediumCBuffer(int minSize)
+ {
+ if (mCurrRecycler != null) {
+ char[] result = mCurrRecycler.getMediumCBuffer(minSize);
+ if (result != null) {
+ return result;
+ }
+ }
+ return new char[minSize];
+ }
+
+ public void freeMediumCBuffer(char[] buffer)
+ {
+ // Need to create (and assign) the buffer?
+ if (mCurrRecycler == null) {
+ mCurrRecycler = createRecycler();
+ }
+ mCurrRecycler.returnMediumCBuffer(buffer);
+ }
+
+ public char[] allocFullCBuffer(int minSize)
+ {
+ if (mCurrRecycler != null) {
+ char[] result = mCurrRecycler.getFullCBuffer(minSize);
+ if (result != null) {
+ return result;
+ }
+ }
+ return new char[minSize];
+ }
+
+ public void freeFullCBuffer(char[] buffer)
+ {
+ // Need to create (and assign) the buffer?
+ if (mCurrRecycler == null) {
+ mCurrRecycler = createRecycler();
+ }
+ mCurrRecycler.returnFullCBuffer(buffer);
+ }
+
+ public byte[] allocFullBBuffer(int minSize)
+ {
+ if (mCurrRecycler != null) {
+ byte[] result = mCurrRecycler.getFullBBuffer(minSize);
+ if (result != null) {
+ return result;
+ }
+ }
+ return new byte[minSize];
+ }
+
+ public void freeFullBBuffer(byte[] buffer)
+ {
+ // Need to create (and assign) the buffer?
+ if (mCurrRecycler == null) {
+ mCurrRecycler = createRecycler();
+ }
+ mCurrRecycler.returnFullBBuffer(buffer);
+ }
+
+ private BufferRecycler createRecycler()
+ {
+ BufferRecycler recycler = new BufferRecycler();
+ // No way to reuse/reset SoftReference, have to create new always:
+ mRecyclerRef.set(new SoftReference(recycler));
+ return recycler;
+ }
+
+ /*
+ //////////////////////////////////////////////////////////
+ // Internal methods
+ //////////////////////////////////////////////////////////
+ */
+
+ private void setConfigFlag(int flag, boolean state) {
+ if (state) {
+ mConfigFlags |= flag;
+ } else {
+ mConfigFlags &= ~flag;
+ }
+ }
+
+ private final boolean hasConfigFlag(int flag) {
+ return ((mConfigFlags & flag) == flag);
+ }
+
+ private final Object getSpecialProperty(int ix)
+ {
+ if (mSpecialProperties == null) {
+ return null;
+ }
+ return mSpecialProperties[ix];
+ }
+
+ private final void setSpecialProperty(int ix, Object value)
+ {
+ if (mSpecialProperties == null) {
+ mSpecialProperties = new Object[SPEC_PROC_COUNT];
+ }
+ mSpecialProperties[ix] = value;
+ }
+}
diff -Nru libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/api/WstxInputProperties.java libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/api/WstxInputProperties.java
--- libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/api/WstxInputProperties.java 1970-01-01 00:00:00.000000000 +0000
+++ libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/api/WstxInputProperties.java 2018-03-31 01:33:28.000000000 +0000
@@ -0,0 +1,336 @@
+package com.ctc.wstx.api;
+
+import javax.xml.stream.XMLResolver;
+
+import org.codehaus.stax2.XMLInputFactory2;
+
+/**
+ * Class that contains constant for property names used to configure
+ * cursor and event readers produced by Wstx implementation of
+ * {@link javax.xml.stream.XMLInputFactory}.
+ *
+ * TODO:
+ *
+ * - CHECK_CHAR_VALIDITY (separate for white spaces?)
+ * - CATALOG_RESOLVER? (or at least, ENABLE_CATALOGS)
+ */
+public final class WstxInputProperties
+{
+ /**
+ * Constants used when no DTD handling is done, and we do not know the
+ * 'real' type of an attribute. Seems like CDATA is the safe choice.
+ */
+ public final static String UNKNOWN_ATTR_TYPE = "CDATA";
+
+ /*
+ ///////////////////////////////////////////////////////////////////////
+ // Simple on/off settings:
+ ///////////////////////////////////////////////////////////////////////
+ */
+
+ // // // Normalization:
+
+ /**
+ * Feature that controls whether linefeeds are normalized into
+ * canonical linefeed as mandated by xml specification.
+ *
+ * Note that disabling this property (from its default enabled
+ * state) will result in non-conforming XML processing. It may
+ * be useful for use cases where changes to input content should
+ * be minimized.
+ *
+ * Note: this property was initially removed from Woodstox 4.0,
+ * but was reintroduced in 4.0.8 due to user request.
+ */
+ public final static String P_NORMALIZE_LFS = "com.ctc.wstx.normalizeLFs";
+
+ //public final static String P_NORMALIZE_ATTR_VALUES = "com.ctc.wstx.normalizeAttrValues";
+
+ // // // XML character validation:
+
+ /**
+ * Whether readers will verify that characters in text content are fully
+ * valid XML characters (not just Unicode). If true, will check
+ * that they are valid (including white space); if false, will not
+ * check.
+ *
+ * Note that this property will NOT have effect on all encoding problems,
+ * specifically:
+ *
+ * - UTF-8 decoder will still report invalid UTF-8 byte sequences (and same
+ * for other character encodings).
+ *
+ * - XML Name character rules follow separate validation which will not be affected
+ *
+ *
+ *
+ * Turning this option off may improve parsing performance; leaving
+ * it on guarantees compatibility with XML 1.0 specs regarding character
+ * validity rules.
+ */
+ public final static String P_VALIDATE_TEXT_CHARS = "com.ctc.wstx.validateTextChars";
+
+ // // // Caching:
+
+ /**
+ * Whether readers will try to cache parsed external DTD subsets or not.
+ */
+
+ public final static String P_CACHE_DTDS = "com.ctc.wstx.cacheDTDs";
+
+ /**
+ * Whether reader is to cache DTDs (when caching enabled) based on public id
+ * or not: if not, system id will be primarily used. Although theoretically
+ * public IDs should be unique, and should be good caching keys, sometimes
+ * broken documents use 'wrong' public IDs, and such by default caching keys
+ * are based on system id only.
+ */
+ public final static String P_CACHE_DTDS_BY_PUBLIC_ID = "com.ctc.wstx.cacheDTDsByPublicId";
+
+
+ // // // Enabling/disabling lazy/incomplete parsing
+
+ /**
+ * Whether stream readers are allowed to do lazy parsing, meaning
+ * to parse minimal part of the event when
+ * {@link javax.xml.stream.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 javax.xml.stream.XMLStreamReader#next} is called, but only when the
+ * rest of event are read or skipped.
+ *
+ * Default value for Woodstox is such that lazy parsing is
+ * enabled.
+ *
+ * @deprecated As of Woodstox 4.0 use
+ * {@link XMLInputFactory2#P_LAZY_PARSING} instead (from
+ * Stax2 extension API, v3.0)
+ */
+ @Deprecated
+ public final static String P_LAZY_PARSING = XMLInputFactory2.P_LAZY_PARSING;
+
+ // // // API behavior (for backwards compatibility)
+
+ /**
+ * This read-only property indicates whether null is returned for default name space prefix;
+ * Boolean.TRUE indicates it does, Boolean.FALSE that it does not.
+ *
+ * Default value for 4.1 is 'false'; this will most likely change for 5.0 since
+ * Stax API actually specifies null to be used.
+ *
+ * @since 4.1.2
+ */
+ public final static String P_RETURN_NULL_FOR_DEFAULT_NAMESPACE = "com.ctc.wstx.returnNullForDefaultNamespace";
+
+ // // // Enabling/disabling support for dtd++
+
+ /**
+ * Whether the Reader will recognized DTD++ extensions when parsing
+ * DTD subsets.
+ *
+ * Note: not implemented by Woodstox.
+ *
+ * @deprecated Never implement, let's phase this out (deprecated in 4.2)
+ */
+ @Deprecated
+ public final static String P_SUPPORT_DTDPP = "com.ctc.wstx.supportDTDPP";
+
+ /**
+ * Whether the Reader will treat character references as entities while parsing
+ * XML documents.
+ */
+ public static final String P_TREAT_CHAR_REFS_AS_ENTS = "com.ctc.wstx.treatCharRefsAsEnts";
+
+ // // // Enabling alternate mode for parsing XML fragments instead
+ // // // of full documents
+
+ // Automatic W3C Schema support?
+ /*
+ * Whether W3C Schema hint attributes are recognized within document,
+ * and used to locate Schema to use for validation.
+ */
+ //public final static String P_AUTOMATIC_W3C_SCHEMA = 0x00100000;
+
+ /*
+ ///////////////////////////////////////////////////////////////////////
+ // More complex settings
+ ///////////////////////////////////////////////////////////////////////
+ */
+
+ // // // Buffer sizes;
+
+ /**
+ * Size of input buffer (in chars), to use for reading XML content
+ * from input stream/reader.
+ */
+ public final static String P_INPUT_BUFFER_LENGTH = "com.ctc.wstx.inputBufferLength";
+
+ // // // Constraints on sizes of text segments parsed:
+
+
+ /**
+ * Property to specify shortest non-complete text segment (part of
+ * CDATA section or text content) that parser is allowed to return,
+ * if not required to coalesce text.
+ */
+ public final static String P_MIN_TEXT_SEGMENT = "com.ctc.wstx.minTextSegment";
+
+ // // // Other size constraints (4.2+)
+
+ /**
+ * Maximum number of attributes allowed for single XML element.
+ * @since 4.2
+ */
+ public final static String P_MAX_ATTRIBUTES_PER_ELEMENT = "com.ctc.wstx.maxAttributesPerElement";
+
+ /**
+ * Maximum length of of individual attribute values (in characters)
+ * @since 4.2
+ */
+ public final static String P_MAX_ATTRIBUTE_SIZE = "com.ctc.wstx.maxAttributeSize";
+
+ /**
+ * Maximum number of child elements for any given element.
+ * @since 4.2
+ */
+ public final static String P_MAX_CHILDREN_PER_ELEMENT = "com.ctc.wstx.maxChildrenPerElement";
+
+ /**
+ * Maximum number of all elements in a single document.
+ * @since 4.2
+ */
+ public final static String P_MAX_ELEMENT_COUNT = "com.ctc.wstx.maxElementCount";
+
+ /**
+ * Maximum level of nesting of XML elements, starting with root element.
+ * @since 4.2
+ */
+ public final static String P_MAX_ELEMENT_DEPTH = "com.ctc.wstx.maxElementDepth";
+
+ /**
+ * Maximum length of input document, in characters.
+ * @since 4.2
+ */
+ public final static String P_MAX_CHARACTERS = "com.ctc.wstx.maxCharacters";
+
+ /**
+ * Maximum length of individual text (cdata) segments in input, in characters.
+ * @since 4.2
+ */
+ public final static String P_MAX_TEXT_LENGTH = "com.ctc.wstx.maxTextLength";
+
+ // and more size constraints (4.3+)
+
+ /**
+ * Maximum number of total (general parsed) entity expansions within input.
+ *
+ * @since 4.3
+ */
+ public final static String P_MAX_ENTITY_COUNT = "com.ctc.wstx.maxEntityCount";
+
+ /**
+ * Maximum depth of nested (general parsed) entity expansions.
+ *
+ * @since 4.3
+ */
+ public final static String P_MAX_ENTITY_DEPTH = "com.ctc.wstx.maxEntityDepth";
+
+ // // // Entity handling
+
+ /**
+ * Property of type {@link java.util.Map}, that defines explicit set of
+ * internal (generic) entities that will define of override any entities
+ * defined in internal or external subsets; except for the 5 pre-defined
+ * entities (lt, gt, amp, apos, quot). Can be used to explicitly define
+ * entites that would normally come from a DTD.
+ *
+ * @deprecated This feature may be removed from future versions of
+ * Woodstox, since the same functionality can be achieved by using
+ * custom entity resolvers.
+ */
+ @Deprecated
+ public final static String P_CUSTOM_INTERNAL_ENTITIES = "com.ctc.wstx.customInternalEntities";
+
+ /**
+ * Property of type {@link XMLResolver}, that
+ * will allow overriding of default DTD and external parameter entity
+ * resolution.
+ */
+ public final static String P_DTD_RESOLVER = "com.ctc.wstx.dtdResolver";
+
+ /**
+ * Property of type {@link XMLResolver}, that
+ * will allow overriding of default external general entity
+ * resolution. Note that using this property overrides settings done
+ * using {@link javax.xml.stream.XMLInputFactory#RESOLVER} (and vice versa).
+ */
+ public final static String P_ENTITY_RESOLVER = "com.ctc.wstx.entityResolver";
+
+ /**
+ * Property of type {@link XMLResolver}, that
+ * will allow graceful handling of references to undeclared (general)
+ * entities.
+ */
+ public final static String P_UNDECLARED_ENTITY_RESOLVER = "com.ctc.wstx.undeclaredEntityResolver";
+
+ /**
+ * Property of type {@link java.net.URL}, that will allow specifying
+ * context URL to use when resolving relative references, for the
+ * main-level entities (external DTD subset, references from the internal
+ * DTD subset).
+ */
+ public final static String P_BASE_URL = "com.ctc.wstx.baseURL";
+
+ // // // Alternate parsing modes
+
+ /**
+ * Three-valued property (one of
+ * {@link #PARSING_MODE_DOCUMENT},
+ * {@link #PARSING_MODE_FRAGMENT} or
+ * {@link #PARSING_MODE_DOCUMENTS}; default being the document mode)
+ * that can be used to handle "non-standard" XML content. The default
+ * mode (PARSING_MODE_DOCUMENT
) allows parsing of only
+ * well-formed XML documents, but the other two modes allow more lenient
+ * parsing. Fragment mode allows parsing of XML content that does not
+ * have a single root element (can have zero or more), nor can have
+ * XML or DOCTYPE declarations: this may be useful if parsing a subset
+ * of a full XML document. Multi-document
+ * (PARSING_MODE_DOCUMENTS
) mode on the other hand allows
+ * parsing of a stream that contains multiple consequtive well-formed
+ * documents, with possibly multiple XML and DOCTYPE declarations.
+ *
+ * The main difference from the API perspective is that in first two
+ * modes, START_DOCUMENT and END_DOCUMENT are used as usual (as the first
+ * and last events returned), whereas the multi-document mode can return
+ * multiple pairs of these events: although it is still true that the
+ * first event (one cursor points to when reader is instantiated or
+ * returned by the event reader), there may be intervening pairs that
+ * signal boundary between two adjacent enclosed documents.
+ */
+ public final static String P_INPUT_PARSING_MODE = "com.ctc.wstx.fragmentMode";
+
+ // // // DTD defaulting, overriding
+
+ /*
+ ///////////////////////////////////////////////////////////////////////
+ // Helper classes, values enumerations
+ ///////////////////////////////////////////////////////////////////////
+ */
+
+ public final static ParsingMode PARSING_MODE_DOCUMENT = new ParsingMode();
+ public final static ParsingMode PARSING_MODE_FRAGMENT = new ParsingMode();
+ public final static ParsingMode PARSING_MODE_DOCUMENTS = new ParsingMode();
+
+ /**
+ * Inner class used for creating type-safe enumerations (prior to JDK 1.5).
+ */
+ public final static class ParsingMode
+ {
+ ParsingMode() { }
+ }
+}
diff -Nru libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/api/WstxOutputProperties.java libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/api/WstxOutputProperties.java
--- libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/api/WstxOutputProperties.java 1970-01-01 00:00:00.000000000 +0000
+++ libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/api/WstxOutputProperties.java 2018-03-31 01:33:28.000000000 +0000
@@ -0,0 +1,186 @@
+package com.ctc.wstx.api;
+
+/**
+ * Class that contains constant for property names used to configure
+ * cursor and event writers produced by Wstx implementation of
+ * {@link javax.xml.stream.XMLOutputFactory}.
+ *
+ */
+public final class WstxOutputProperties
+{
+ /**
+ * Default xml version number output, if none was specified by
+ * application. Version 1.0 is used
+ * to try to maximize compatibility (some older parsers
+ * may barf on 1.1 and later...)
+ */
+ public final static String DEFAULT_XML_VERSION = "1.0";
+
+ /**
+ * If no encoding is passed, we should just default to what xml
+ * in general expects (and can determine), UTF-8.
+ *
+ * Note: you can check out bug entry [WSTX-18] for more details
+ */
+ public final static String DEFAULT_OUTPUT_ENCODING = "UTF-8";
+
+ // // // Output options, simple on/off settings:
+
+ /**
+ * Whether writer should use double quotes in the XML declaration.
+ * The default is to use single quotes.
+ *
+ * @since 4.2.2
+ */
+ public final static String P_USE_DOUBLE_QUOTES_IN_XML_DECL = "com.ctc.wstx.useDoubleQuotesInXmlDecl";
+
+ /**
+ * Whether writer should just automatically convert all calls that
+ * would normally produce CDATA to produce (quoted) text.
+ */
+ public final static String P_OUTPUT_CDATA_AS_TEXT = "com.ctc.wstx.outputCDataAsText";
+
+ /**
+ * Whether writer should copy attributes that were initially expanded
+ * using default settings ("implicit" attributes) or not.
+ */
+ public final static String P_COPY_DEFAULT_ATTRS = "com.ctc.wstx.copyDefaultAttrs";
+
+ /**
+ * Whether writer is to add a single white space before closing "/>"
+ * of the empty element or not. It is sometimes useful to add to
+ * increase compatibility with HTML browsers, or to increase
+ * readability.
+ *
+ * The default value is 'false', up to Woodstox 4.x.
+ *
+ * NOTE: JavaDocs for versions 4.0.0 - 4.0.7 incorrectly state that
+ * default is 'true': this is NOT the case.
+ *
+ * Note: added to resolve Jira entry
+ * WSTX-125.
+ */
+ public final static String P_ADD_SPACE_AFTER_EMPTY_ELEM = "com.ctc.wstx.addSpaceAfterEmptyElem";
+
+ /**
+ * Whether stream writer is to automatically add end elements that are
+ * needed to properly close the output tree, when the stream is closed
+ * (either explicitly by a call to close
or
+ * closeCompletely
, or implicitly by a call
+ * to writeEndDocument
.
+ *
+ * The default value is 'true' as of Woodstox 4.x.
+ * Prior to 4.0, this feature was always enabled and there was no
+ * way to disable it)
+ *
+ * @since 3.2.8
+ */
+ public final static String P_AUTOMATIC_END_ELEMENTS = "com.ctc.wstx.automaticEndElements";
+
+ // // // Validation options:
+
+ /**
+ * Whether output classes should do basic verification that the output
+ * structure is well-formed (start and end elements match); that
+ * there is one and only one root, and that there is no textual content
+ * in prolog/epilog. If false, won't do any checking regarding structure.
+ */
+ public final static String P_OUTPUT_VALIDATE_STRUCTURE = "com.ctc.wstx.outputValidateStructure";
+
+ /**
+ * Whether output classes should do basic verification that the textual
+ * content output as part of nodes should be checked for validity,
+ * if there's a possibility of invalid content. Nodes that include
+ * such constraints are: comment/'--', cdata/']]>',
+ * proc. instr/'?>'.
+ */
+ public final static String P_OUTPUT_VALIDATE_CONTENT = "com.ctc.wstx.outputValidateContent";
+
+ /**
+ * Whether output classes should check uniqueness of attribute names,
+ * to prevent accidental output of duplicate attributes.
+ */
+ public final static String P_OUTPUT_VALIDATE_ATTR = "com.ctc.wstx.outputValidateAttr";
+
+ /**
+ * Whether output classes should check validity of names, ie that they
+ * only contain legal XML identifier characters.
+ */
+ public final static String P_OUTPUT_VALIDATE_NAMES = "com.ctc.wstx.outputValidateNames";
+
+ /**
+ * Property that further modifies handling of invalid content so
+ * that if {@link #P_OUTPUT_VALIDATE_CONTENT} is enabled, instead of
+ * reporting an error, writer will try to fix the problem.
+ * Invalid content in this context refers to comment
+ * content with "--", CDATA with "]]>" and proc. instr data with "?>".
+ * This can
+ * be done for some content (CDATA, possibly comment), by splitting
+ * content into separate
+ * segments; but not for others (proc. instr, since that might
+ * change the semantics in unintended ways).
+ */
+ public final static String P_OUTPUT_FIX_CONTENT = "com.ctc.wstx.outputFixContent";
+
+ /**
+ * Property that determines whether Carriage Return (\r) characters are
+ * to be escaped when output or not. If enabled, all instances of
+ * of character \r are escaped using a character entity (where possible,
+ * that is, within CHARACTERS events, and attribute values). Otherwise
+ * they are output as is. The main reason to enable this property is
+ * to ensure that carriage returns are preserved as is through parsing,
+ * since otherwise they will be converted to canonical xml linefeeds
+ * (\n), when occuring along or as part of \r\n pair.
+ */
+ public final static String P_OUTPUT_ESCAPE_CR = "com.ctc.wstx.outputEscapeCr";
+
+ /**
+ * Property that defines a {@link InvalidCharHandler} used to determine
+ * what to do with a Java character that app tries to output but which
+ * is not a valid xml character. Alternatives are converting it to
+ * another character or throw an exception: default implementations
+ * exist for both behaviors.
+ */
+ public final static String P_OUTPUT_INVALID_CHAR_HANDLER = "com.ctc.wstx.outputInvalidCharHandler";
+
+ /**
+ * Property that defines an {@link EmptyElementHandler} used to determine
+ * if the end tag for an empty element should be written or not.
+ *
+ * If specified {@link org.codehaus.stax2.XMLOutputFactory2#P_AUTOMATIC_EMPTY_ELEMENTS} is ignored.
+ */
+ public final static String P_OUTPUT_EMPTY_ELEMENT_HANDLER = "com.ctc.wstx.outputEmptyElementHandler";
+
+ // // // Per-instance access to underlying output objects
+
+ /**
+ * Property that can be used to find out the underlying
+ * {@link java.io.OutputStream} that an
+ * {@link javax.xml.stream.XMLStreamWriter} instance is using,
+ * if known (not known if constructed with a {@link java.io.Writer},
+ * or other non-stream destination). Null is returned, if not
+ * known.
+ *
+ * Note: in general it is dangerous to operate on returned stream
+ * (if any), due to buffering stream writer can do. As such, caller
+ * has to take care to know what he is doing, including properly
+ * flushing output.
+ */
+ public final static String P_OUTPUT_UNDERLYING_STREAM = "com.ctc.wstx.outputUnderlyingStream";
+
+ /**
+ * Property that can be used to find out the underlying
+ * {@link java.io.Writer} that an
+ * {@link javax.xml.stream.XMLStreamWriter} instance is using,
+ * if known (may not be known if constructed with a {@link java.io.OutputStream},
+ * or other non-Writer destination). Null is returned, if not
+ * known. Note that the Writer may be an internal wrapper over
+ * an output stream.
+ *
+ * Note: in general it is dangerous to operate on returned Writer
+ * (if any), due to buffering stream writer can do. As such, caller
+ * has to take care to know what he is doing, including properly
+ * flushing output.
+ */
+ public final static String P_OUTPUT_UNDERLYING_WRITER = "com.ctc.wstx.outputUnderlyingWriter";
+}
diff -Nru libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/cfg/ErrorConsts.java libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/cfg/ErrorConsts.java
--- libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/cfg/ErrorConsts.java 1970-01-01 00:00:00.000000000 +0000
+++ libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/cfg/ErrorConsts.java 2018-03-31 01:33:28.000000000 +0000
@@ -0,0 +1,193 @@
+package com.ctc.wstx.cfg;
+
+import javax.xml.XMLConstants;
+import javax.xml.stream.XMLStreamConstants;
+
+/**
+ * "Static" class that contains error message constants. Note that the
+ * error message constants are NOT made final; reason is that doing so
+ * would make compiler inline them in other classes. Doing so would increase
+ * class size (although not mem usage -- Strings do get interned), with
+ * minimal performance impact.
+ */
+public class ErrorConsts
+ implements XMLStreamConstants
+{
+ // // // Types of warnings we issue via XMLReporter
+
+ public static String WT_ENT_DECL = "entity declaration";
+ public static String WT_ELEM_DECL = "element declaration";
+ public static String WT_ATTR_DECL = "attribute declaration";
+ public static String WT_XML_DECL = "xml declaration";
+ public static String WT_DT_DECL = "doctype declaration";
+ public static String WT_NS_DECL = "namespace declaration";
+
+ /**
+ * This is the generic type for warnings based on XMLValidationProblem
+ * objects.
+ */
+ public static String WT_VALIDATION = "schema validation";
+
+ // // And then warning strings
+
+ public static String W_UNDEFINED_ELEM = "Undefined element \"{0}\"; referred to by attribute(s)";
+ public static String W_MIXED_ENCODINGS = "Inconsistent text encoding; declared as \"{0}\" in xml declaration, application had passed \"{1}\"";
+ public static String W_MISSING_DTD = "Missing DOCTYPE declaration in validating mode; can not validate elements or attributes";
+ public static String W_DTD_DUP_ATTR = "Attribute \"{0}\" (for element <{1}>) declared multiple times";
+ public static String W_DTD_ATTR_REDECL = "Attribute \"{0}\" already declared for element <{1}>; ignoring re-declaration";
+
+ // // // Generic errors:
+
+ public static String ERR_INTERNAL = "Internal error";
+ public static String ERR_NULL_ARG = "Illegal to pass null as argument";
+ public static String ERR_UNKNOWN_FEATURE = "Unrecognized feature \"{0}\"";
+
+ // // // Wrong reader state:
+
+ public static String ERR_STATE_NOT_STELEM = "Current event not START_ELEMENT";
+ public static String ERR_STATE_NOT_ELEM = "Current event not START_ELEMENT or END_ELEMENT";
+ public static String ERR_STATE_NOT_PI = "Current event not PROCESSING_INSTRUCTION";
+ public static String ERR_STATE_NOT_ELEM_OR_TEXT = "Current event ({0}) not START_ELEMENT, END_ELEMENT, CHARACTERS or CDATA";
+
+ // // // XML declaration related problems
+
+ public static String ERR_XML_10_VS_11 = "XML 1.0 document can not refer to XML 1.1 parsed external entities";
+
+ // // // Structural problems, prolog/epilog:
+
+ public static String ERR_DTD_IN_EPILOG = "Can not have DOCTYPE declaration in epilog";
+ public static String ERR_DTD_DUP = "Duplicate DOCTYPE declaration";
+ public static String ERR_CDATA_IN_EPILOG = " (CDATA not allowed in prolog/epilog)";
+
+ // // // Illegal input:
+
+ public static String ERR_HYPHENS_IN_COMMENT = "String '--' not allowed in comment (missing '>'?)";
+ public static String ERR_BRACKET_IN_TEXT = "String ']]>' not allowed in textual content, except as the end marker of CDATA section";
+
+ // // // Generic parsing errors:
+
+ public static String ERR_UNEXP_KEYWORD = "Unexpected keyword \"{0}\"; expected \"{1}\"";
+
+ public static String ERR_WF_PI_MISSING_TARGET = "Missing processing instruction target";
+ public static String ERR_WF_PI_XML_TARGET = "Illegal processing instruction target (\"{0}\"); 'xml' (case insensitive) is reserved by the specs.";
+ public static String ERR_WF_PI_XML_MISSING_SPACE = "excepted either space or \"?>\" after PI target";
+
+ // // // Entity problems:
+
+ public static String ERR_WF_ENTITY_EXT_DECLARED = "Entity \"{0}\" declared externally, but referenced from a document declared 'standalone=\"yes\"'";
+
+ public static String ERR_WF_GE_UNDECLARED = "Undeclared general entity \"{0}\"";
+
+ public static String ERR_WF_GE_UNDECLARED_SA = "Undeclared general entity \"{0}\" (document in stand-alone mode; perhaps declared externally?)";
+
+ // // // Namespace problems:
+
+ public static String ERR_NS_UNDECLARED = "Undeclared namespace prefix \"{0}\"";
+ public static String ERR_NS_UNDECLARED_FOR_ATTR = "Undeclared namespace prefix \"{0}\" (for attribute \"{1}\")";
+
+ public static String ERR_NS_REDECL_XML = "Trying to redeclare prefix 'xml' from its default URI '"
+ +XMLConstants.XML_NS_URI
+ +"' to \"{0}\"";
+
+ public static String ERR_NS_REDECL_XMLNS = "Trying to declare prefix 'xmlns' (illegal as per NS 1.1 #4)";
+
+ public static String ERR_NS_REDECL_XML_URI = "Trying to bind URI '"
+ +XMLConstants.XML_NS_URI+" to prefix \"{0}\" (can only bind to 'xml')";
+
+ public static String ERR_NS_REDECL_XMLNS_URI = "Trying to bind URI '"
+ +XMLConstants.XMLNS_ATTRIBUTE_NS_URI+" to prefix \"{0}\" (can not be explicitly bound)";
+
+ public static String ERR_NS_EMPTY =
+"Non-default namespace can not map to empty URI (as per Namespace 1.0 # 2) in XML 1.0 documents";
+
+
+ // // // DTD-specific:
+
+ public static String ERR_DTD_MAINLEVEL_KEYWORD = "; expected a keyword (ATTLIST, ELEMENT, ENTITY, NOTATION), comment, or conditional section";
+
+ public static String ERR_DTD_ATTR_TYPE = "; expected one of type (CDATA, ID, IDREF, IDREFS, ENTITY, ENTITIES NOTATION, NMTOKEN or NMTOKENS)";
+
+ public static String ERR_DTD_DEFAULT_TYPE = "; expected #REQUIRED, #IMPLIED or #FIXED";
+
+ public static String ERR_DTD_ELEM_REDEFD =
+ "Trying to redefine element \"{0}\" (originally defined at {1})";
+ public static String ERR_DTD_NOTATION_REDEFD =
+ "Trying to redefine notation \"{0}\" (originally defined at {1})";
+
+ public static String ERR_DTD_UNDECLARED_ENTITY =
+ "Undeclared {0} entity \"{1}\"";
+
+ public static String ERR_DTD_XML_SPACE = "Attribute xml:space has to be defined of type enumerated, and have 1 or 2 values, 'default' and/or 'preserve'";
+
+ public static String ERR_DTD_XML_ID = "Attribute xml:id has to have attribute type of ID, as per Xml:id specification";
+
+
+ // // // DTD-validation:
+
+ public static String ERR_VLD_UNKNOWN_ELEM = "Undefined element <{0}> encountered";
+
+ public static String ERR_VLD_EMPTY = "Element <{0}> has EMPTY content specification; can not contain {1}";
+ public static String ERR_VLD_NON_MIXED = "Element <{0}> has non-mixed content specification; can not contain non-white space text, or any CDATA sections";
+ public static String ERR_VLD_ANY = "Element <{0}> has ANY content specification; can not contain {1}";
+ public static String ERR_VLD_UNKNOWN_ATTR = "Element <{0}> has no attribute \"{1}\"";
+ public static String ERR_VLD_WRONG_ROOT = "Unexpected root element <{0}>; expected <{0}> as per DOCTYPE declaration";
+
+ // // // Output problems:
+
+ public static String WERR_PROLOG_CDATA =
+ "Trying to output a CDATA block outside main element tree (in prolog or epilog)";
+ public static String WERR_PROLOG_NONWS_TEXT =
+ "Trying to output non-whitespace characters outside main element tree (in prolog or epilog)";
+ public static String WERR_PROLOG_SECOND_ROOT =
+ "Trying to output second root, <{0}>";
+
+ public static String WERR_CDATA_CONTENT =
+ "Illegal input: CDATA block has embedded ']]>' in it (index {0})";
+ public static String WERR_COMMENT_CONTENT =
+ "Illegal input: comment content has embedded '--' in it (index {0})";
+
+ public static String WERR_ATTR_NO_ELEM =
+ "Trying to write an attribute when there is no open start element.";
+
+ public static String WERR_NAME_EMPTY = "Illegal to pass empty name";
+
+ public static String WERR_NAME_ILLEGAL_FIRST_CHAR = "Illegal first name character {0}";
+ public static String WERR_NAME_ILLEGAL_CHAR = "Illegal name character {0}";
+
+ /*
+ ////////////////////////////////////////////////////
+ // Utility methods
+ ////////////////////////////////////////////////////
+ */
+
+ public static String tokenTypeDesc(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+"]";
+ }
+}
diff -Nru libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/cfg/InputConfigFlags.java libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/cfg/InputConfigFlags.java
--- libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/cfg/InputConfigFlags.java 1970-01-01 00:00:00.000000000 +0000
+++ libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/cfg/InputConfigFlags.java 2018-03-31 01:33:28.000000000 +0000
@@ -0,0 +1,204 @@
+package com.ctc.wstx.cfg;
+
+/**
+ * Constant interface that contains configuration flag used by parser
+ * and parser factory, as well as some other input constants.
+ */
+public interface InputConfigFlags
+{
+ /*
+ //////////////////////////////////////////////////////
+ // Flags for standard StAX features:
+ //////////////////////////////////////////////////////
+ */
+
+ // // // Namespace handling:
+
+ /**
+ * If true, parser will handle namespaces according to XML specs; if
+ * false, will only pass them as part of element/attribute name value
+ * information.
+ */
+ final static int CFG_NAMESPACE_AWARE = 0x0001;
+
+
+ // // // Text normalization
+
+
+ /// Flag that indicates iterator should coalesce all text segments.
+ final static int CFG_COALESCE_TEXT = 0x0002;
+
+
+ // // // Entity handling
+
+ /**
+ * Flag that enables automatic replacement of internal entities
+ */
+ final static int CFG_REPLACE_ENTITY_REFS = 0x0004;
+
+ /**
+ * Flag that enables support for expanding external entities. Woodstox
+ * pretty much ignores the setting, since effectively it is irrelevant,
+ * as {@link #CFG_REPLACE_ENTITY_REFS} and {@link #CFG_SUPPORT_DTD}
+ * both need to be enabled for external entities to be supported.
+ */
+ final static int CFG_SUPPORT_EXTERNAL_ENTITIES = 0x0008;
+
+ // // // DTD handling
+
+ /**
+ * Whether DTD handling is enabled or disabled; disabling means both
+ * internal and external subsets will just be skipped unprocessed.
+ */
+ final static int CFG_SUPPORT_DTD = 0x0010;
+
+ /**
+ * Not yet (fully) supported; added as the placeholder
+ */
+ final static int CFG_VALIDATE_AGAINST_DTD = 0x0020;
+
+ // // Note: can add 2 more 'standard' flags here...
+
+ /*
+ //////////////////////////////////////////////////////
+ // Flags for StAX2 features
+ //////////////////////////////////////////////////////
+ */
+
+ /**
+ * If true, parser will report (ignorable) white space events in prolog
+ * and epilog; if false, it will silently ignore them.
+ */
+ final static int CFG_REPORT_PROLOG_WS = 0x0100;
+
+ // // // Type conversions:
+
+
+ /**
+ * If true, parser will accurately report CDATA event as such (unless
+ * coalescing); otherwise will always report them as CHARACTERS
+ * independent of coalescing settings.
+ */
+ final static int CFG_REPORT_CDATA = 0x0200;
+
+ // // // String interning:
+
+ /**
+ * If true, will guarantee that all names (attribute/element local names
+ * have been intern()ed. If false, this is not guaranteed although
+ * implementation may still choose to do it.
+ */
+ final static int CFG_INTERN_NAMES = 0x0400;
+
+ /**
+ * It true, will call intern() on all namespace URIs parsed; otherwise
+ * will just use 'regular' Strings created from parsed contents. Interning
+ * makes namespace-based access faster, but has initial overhead of
+ * intern() call.
+ */
+ final static int CFG_INTERN_NS_URIS = 0x0800;
+
+ // // // Lazy/incomplete parsing
+
+ /**
+ * Property that determines whether Event objects created will
+ * contain (accurate) {@link javax.xml.stream.Location} information or not. If not,
+ * Location may be null or a fixed location (beginning of main
+ * XML file).
+ *
+ * Note, however, that the underlying parser will still keep track
+ * of location information for error reporting purposes; it's only
+ * Event objects that are affected.
+ */
+ final static int CFG_PRESERVE_LOCATION = 0x1000;
+
+ // // // Input source handling
+
+ /**
+ * Property that enables/disables stream reader to close the underlying
+ * input source, either when it is asked to (.close() is called), or
+ * when it doesn't need it any more (reaching EOF, hitting an
+ * unrecoverable exception).
+ * As per Stax 1.0 specification, automatic closing is NOT enabled by
+ * default; except if the caller has no access to the target (i.e.
+ * when factory created it)
+ */
+ final static int CFG_AUTO_CLOSE_INPUT = 0x2000;
+
+ /*
+ //////////////////////////////////////////////////////
+ // Flags for Woodstox-specific features
+ //////////////////////////////////////////////////////
+ */
+
+ // // // Content normalization
+
+ // 20-Jan-2007, TSa: These properties removed from 4.0, deprecated:
+ final static int CFG_NORMALIZE_LFS = 0x4000;
+ //final static int CFG_NORMALIZE_ATTR_VALUES = 0x8000;
+
+ // // // Caching
+
+ /**
+ * If true, input factory is allowed cache parsed external DTD subsets,
+ * potentially speeding up things for which DTDs are needed for: entity
+ * substitution, attribute defaulting, and of course DTD-based validation.
+ */
+ final static int CFG_CACHE_DTDS = 0x00010000;
+
+ /**
+ * If true, key used for matching DTD subsets can be the public id,
+ * if false, only system id can be used.
+ */
+ final static int CFG_CACHE_DTDS_BY_PUBLIC_ID = 0x00020000;
+
+ // // // Lazy/incomplete parsing
+
+ /**
+ * If true, input factory can defer parsing of nodes until data is
+ * actually needed; if false, it has to read all the data in right
+ * away when next type is requested. Setting it to true is good for
+ * performance, in the cases where some of the nodes (like comments,
+ * processing instructions, or whole subtrees) are ignored. Otherwise
+ * setting will not make much of a difference. Downside is that error
+ * reporting is also done 'lazily'; not right away when getting the next
+ * even type but when either accessing data, or skipping it.
+ */
+ final static int CFG_LAZY_PARSING = 0x00040000;
+
+ // // // Validation support
+
+ // DTD++ support
+
+ /**
+ * If true, DTD-parser will recognize DTD++ features, and the validator
+ * will also use any such information found from DTD when DTD validation
+ * is enabled.
+ */
+ final static int CFG_SUPPORT_DTDPP = 0x00080000;
+
+ // Automatic W3C Schema support?
+ //final static int CFG_AUTOMATIC_W3C_SCHEMA = 0x00100000;
+
+ // // // Xml:id support
+
+ /**
+ * If true, xml:id attribute type assignment and matching checks will
+ * be done as per Xml:id specification. Needs to be enabled for xml:id
+ * uniqueness checks to function properly
+ */
+ final static int CFG_XMLID_TYPING = 0x00200000;
+
+ /**
+ * If true, xml:id attribute uniqueness constraints are enforced, even
+ * if not validating against DTD otherwise.
+ */
+ final static int CFG_XMLID_UNIQ_CHECKS = 0x00400000;
+
+ /**
+ * If true, the XML parser will treat character references as entities.
+ *
+ */
+ final static int CFG_TREAT_CHAR_REFS_AS_ENTS = 0x00800000;
+}
+
diff -Nru libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/cfg/OutputConfigFlags.java libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/cfg/OutputConfigFlags.java
--- libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/cfg/OutputConfigFlags.java 1970-01-01 00:00:00.000000000 +0000
+++ libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/cfg/OutputConfigFlags.java 2018-03-31 01:33:28.000000000 +0000
@@ -0,0 +1,112 @@
+package com.ctc.wstx.cfg;
+
+/**
+ * Constant interface that contains configuration flag used by output
+ * classes internally, for presenting on/off configuration options.
+ */
+public interface OutputConfigFlags
+{
+ /**
+ * Flag that indicates whether writer is namespace-aware or not; if not,
+ * only local part is ever used.
+ */
+ final static int CFG_ENABLE_NS = 0x0001;
+
+ /// Flag that indicates that output class should auto-generate namespace prefixes as necessary.
+ final static int CFG_AUTOMATIC_NS = 0x0002;
+
+ /// Flag that indicates we can output 'automatic' empty elements.
+ final static int CFG_AUTOMATIC_EMPTY_ELEMENTS = 0x0004;
+
+ /**
+ * Whether writer should just automatically convert all calls that
+ * would normally produce CDATA to produce (quoted) text.
+ */
+ final static int CFG_OUTPUT_CDATA_AS_TEXT = 0x0008;
+
+ /**
+ * Flag that indicates whether attributes expanded from default attribute
+ * values should be copied to output, when using copy methods.
+ */
+ final static int CFG_COPY_DEFAULT_ATTRS = 0x0010;
+
+ /**
+ * Flag that indicates whether CR (\r, ascii 13) characters occuring
+ * in text (CHARACTERS) and attribute values should be escaped using
+ * character entities or not. Escaping is needed to enable seamless
+ * round-tripping (preserving CR characters).
+ */
+ final static int CFG_ESCAPE_CR = 0x0020;
+
+ /**
+ * Flag that indicates
+ * whether writer is to add a single white space before closing "/>"
+ * of the empty element or not. It is sometimes useful to add to
+ * increase compatibility with HTML browsers, or to increase
+ * readability.
+ */
+ final static int CFG_ADD_SPACE_AFTER_EMPTY_ELEM = 0x0040;
+
+ /**
+ * Flag that indicates we can output 'automatic' empty elements;
+ * end elements needed to close the logical output tree when
+ * stream writer is closed (by closing it explicitly, or by writing
+ * end-document event)
+ *
+ * @since 3.2.8
+ */
+ final static int CFG_AUTOMATIC_END_ELEMENTS = 0x0080;
+
+ /// Flag that indicates we should check validity of output XML structure.
+ final static int CFG_VALIDATE_STRUCTURE = 0x0100;
+
+ /**
+ * Flag that indicates we should check validity of textual content of
+ * nodes that have constraints.
+ *
+ * Specifically: comments can not have '--', CDATA sections can not
+ * have ']]>' and processing instruction can not have '?<' character
+ * combinations in content passed in.
+ */
+ final static int CFG_VALIDATE_CONTENT = 0x0200;
+
+ /**
+ * Flag that indicates we should check validity of names (element and
+ * attribute names and prefixes; processing instruction names), that they
+ * contain only legal identifier characters.
+ */
+ final static int CFG_VALIDATE_NAMES = 0x0400;
+
+ /**
+ * Flag that indicates we should check uniqueness of attribute names,
+ * to prevent accidental output of duplicate attributes.
+ */
+ final static int CFG_VALIDATE_ATTR = 0x0800;
+
+ /**
+ * Flag that will enable writer that checks for validity of content
+ * to try to fix the problem, by splitting output segments as
+ * necessary. If disabled, validation will throw an exception; and
+ * without validation no problem is noticed by writer (but instead
+ * invalid output is created).
+ */
+ final static int CFG_FIX_CONTENT = 0x1000;
+
+ /**
+ * Property that enables/disables stream write to close the underlying
+ * output target, either when it is asked to (.close() is called), or
+ * when it doesn't need it any more (reaching EOF, hitting an
+ * unrecoverable exception).
+ * As per Stax 1.0 specification, automatic closing is NOT enabled by
+ * default; except if the caller has no access to the target (i.e.
+ * when factory created it)
+ */
+ final static int CFG_AUTO_CLOSE_OUTPUT = 0x2000;
+
+ /**
+ * Property that indicates if singe quotes or double quotes should be
+ * used in the XML declaration.
+ * The default is to use single quotes.
+ */
+ final static int CFG_USE_DOUBLE_QUOTES_IN_XML_DECL = 0x4000;
+}
diff -Nru libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/cfg/package.html libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/cfg/package.html
--- libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/cfg/package.html 1970-01-01 00:00:00.000000000 +0000
+++ libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/cfg/package.html 2018-03-31 01:33:28.000000000 +0000
@@ -0,0 +1,3 @@
+
+Package that contains internal configuration settings for Woodstox.
+
diff -Nru libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/cfg/ParsingErrorMsgs.java libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/cfg/ParsingErrorMsgs.java
--- libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/cfg/ParsingErrorMsgs.java 1970-01-01 00:00:00.000000000 +0000
+++ libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/cfg/ParsingErrorMsgs.java 2018-03-31 01:33:28.000000000 +0000
@@ -0,0 +1,26 @@
+package com.ctc.wstx.cfg;
+
+public interface ParsingErrorMsgs
+{
+ // // // EOF problems:
+
+ final static String SUFFIX_IN_ATTR_VALUE = " in attribute value";
+ final static String SUFFIX_IN_DEF_ATTR_VALUE = " in attribute default value";
+ final static String SUFFIX_IN_CDATA = " in CDATA section";
+ final static String SUFFIX_IN_CLOSE_ELEMENT = " in end tag";
+ final static String SUFFIX_IN_COMMENT = " in comment";
+ final static String SUFFIX_IN_DTD = " in DOCTYPE declaration";
+ final static String SUFFIX_IN_DTD_EXTERNAL = " in external DTD subset";
+ final static String SUFFIX_IN_DTD_INTERNAL = " in internal DTD subset";
+ final static String SUFFIX_IN_DOC = " in main document content";
+ final static String SUFFIX_IN_ELEMENT = " in start tag";
+ final static String SUFFIX_IN_ENTITY_REF = " in entity reference";
+ final static String SUFFIX_IN_EPILOG = " in epilog";
+ final static String SUFFIX_IN_NAME = " in name token";
+ final static String SUFFIX_IN_PROC_INSTR = " in processing instruction";
+ final static String SUFFIX_IN_PROLOG = " in prolog";
+ final static String SUFFIX_IN_TEXT = " in document text content";
+ final static String SUFFIX_IN_XML_DECL = " in xml declaration";
+
+ final static String SUFFIX_EOF_EXP_NAME = "; expected an identifier";
+}
diff -Nru libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/cfg/XmlConsts.java libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/cfg/XmlConsts.java
--- libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/cfg/XmlConsts.java 1970-01-01 00:00:00.000000000 +0000
+++ libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/cfg/XmlConsts.java 2018-03-31 01:33:28.000000000 +0000
@@ -0,0 +1,66 @@
+package com.ctc.wstx.cfg;
+
+/**
+ * Simple constant container interface, shared by input and output
+ * sides.
+ */
+public interface XmlConsts
+{
+ // // // Constants for XML declaration
+
+ public final static String XML_DECL_KW_ENCODING = "encoding";
+ public final static String XML_DECL_KW_VERSION = "version";
+ public final static String XML_DECL_KW_STANDALONE = "standalone";
+
+ public final static String XML_V_10_STR = "1.0";
+ public final static String XML_V_11_STR = "1.1";
+
+ /**
+ * This constants refers to cases where the version has not been
+ * declared explicitly; and needs to be considered to be 1.0.
+ */
+ public final static int XML_V_UNKNOWN = 0x0000;
+
+ public final static int XML_V_10 = 0x0100;
+ public final static int XML_V_11 = 0x0110;
+
+ public final static String XML_SA_YES = "yes";
+ public final static String XML_SA_NO = "no";
+
+ // // // Stax specs mandates some settings: but since exact
+ // // // definitions have been re-interpreted a few times,
+ // // // let's isolate them in a single place
+
+ /* 13-Mar-2008, TSa: As per latest reading of Stax specs,
+ * all of these are expected to be "", not null.
+ */
+
+ public final static String ELEM_NO_NS_URI = "";
+
+ public final static String ATTR_NO_NS_URI = "";
+
+ public final static String ELEM_NO_PREFIX = "";
+
+ public final static String ATTR_NO_PREFIX = "";
+
+ /**
+ * Top-most namespace URI assigned for root element, if not specifically
+ * defined (default namespace unbound).
+ *
+ * As per Stax specs, related clarifying discussion on
+ * the mailing list, and especially JDK 1.6 definitions
+ * in {@link javax.xml.XMLConstants} constants, empty String
+ * should be used instead of null.
+ */
+ public final static String DEFAULT_NAMESPACE_URI = ELEM_NO_NS_URI;
+
+ // // // Well, these are not strictly xml constants, but for
+ // // // now can live here
+
+ /**
+ * This constant defines the highest Unicode character allowed
+ * in XML content.
+ */
+ final static int MAX_UNICODE_CHAR = 0x10FFFF;
+
+}
diff -Nru libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/compat/package.html libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/compat/package.html
--- libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/compat/package.html 1970-01-01 00:00:00.000000000 +0000
+++ libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/compat/package.html 2018-03-31 01:33:28.000000000 +0000
@@ -0,0 +1,7 @@
+
+Package that contains classes that allow abstracting out the details of
+JDK platform version being used. Currently classes are used to implement
+"graceful degradation" of functionality, when certain JDK classes are only
+fully implemented as part of JDKs later than the minimum version
+Woodstox needs for running (for Woodstox versions up to 3.x it was JDK 1.2, for 4.x JDK 1.4).
+
diff -Nru libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/compat/QNameCreator.java libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/compat/QNameCreator.java
--- libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/compat/QNameCreator.java 1970-01-01 00:00:00.000000000 +0000
+++ libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/compat/QNameCreator.java 2018-03-31 01:33:28.000000000 +0000
@@ -0,0 +1,70 @@
+package com.ctc.wstx.compat;
+
+import java.util.logging.Logger;
+
+import javax.xml.namespace.QName;
+
+/**
+ * Helper class used to solve [WSTX-174]: some older AppServers were
+ * shipped with incompatible version of QName class, which is missing
+ * the 3 argument constructor. To address this, we'll use bit of
+ * ClassLoader hacker to gracefully (?) downgrade to using 2 arg
+ * alternatives if necessary.
+ *
+ * Note: choice of java.util.logging logging is only based on the
+ * fact that it is guaranteed to be present (we have JDK 1.4 baseline
+ * requirement) so that we do not add external dependencies.
+ * It is not a recommendation for using JUL per se; most users would
+ * do well to just use slf4j or log4j directly instead.
+ *
+ * @author Tatu Saloranta
+ *
+ * @since 3.2.8
+ */
+public final class QNameCreator
+{
+ /**
+ * Creator object that creates QNames using proper 3-arg constructor.
+ * If dynamic class loading fails
+ */
+ private final static Helper _helper;
+ static {
+ Helper h = null;
+ try {
+ // Not sure where it'll fail, constructor or create...
+ Helper h0 = new Helper();
+ /*QName n =*/ h0.create("elem", "http://dummy", "ns");
+ h = h0;
+ } catch (Throwable t) {
+ String msg = "Could not construct QNameCreator.Helper; assume 3-arg QName constructor not available and use 2-arg method instead. Problem: "+t.getMessage();
+ try {
+ Logger.getLogger("com.ctc.wstx.compat.QNameCreator").warning(msg);
+ } catch (Throwable t2) { // just in case JUL craps out...
+ System.err.println("ERROR: failed to log error using Logger (problem "+t.getMessage()+"), original problem: "+msg);
+ }
+ }
+ _helper = h;
+ }
+
+ public static QName create(String uri, String localName, String prefix)
+ {
+ if (_helper == null) { // can't use 3-arg constructor; but 2-arg will be there
+ return new QName(uri, localName);
+ }
+ return _helper.create(uri, localName, prefix);
+ }
+
+ /**
+ * Helper class used to encapsulate calls to the missing method.
+ */
+ private final static class Helper
+ {
+ public Helper() { }
+
+ public QName create(String localName, String nsURI, String prefix)
+ {
+ return new QName(localName, nsURI, prefix);
+ }
+ }
+}
+
diff -Nru libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/dom/DOMOutputElement.java libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/dom/DOMOutputElement.java
--- libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/dom/DOMOutputElement.java 1970-01-01 00:00:00.000000000 +0000
+++ libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/dom/DOMOutputElement.java 2018-03-31 01:33:28.000000000 +0000
@@ -0,0 +1,216 @@
+package com.ctc.wstx.dom;
+
+import javax.xml.namespace.NamespaceContext;
+
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+import com.ctc.wstx.sw.OutputElementBase;
+import com.ctc.wstx.util.BijectiveNsMap;
+
+/**
+ * Context object that holds information about an open element
+ * (one for which START_ELEMENT has been sent, but no END_ELEMENT)
+ */
+public final class DOMOutputElement
+ extends OutputElementBase
+{
+ /**
+ * Reference to the parent element, element enclosing this element.
+ * Null for root element.
+ * Non-final to allow temporary pooling
+ * (on per-writer basis, to keep these short-lived).
+ */
+ private DOMOutputElement mParent;
+
+ /**
+ * DOM node that is the root under which content is written, in case
+ * where there is no parent (mParent == null). If mParent is not null,
+ * this will be null.
+ * Value is of type
+ * {@link Document}, {@link DocumentFragment} or {@link Element}
+ */
+ private final Node mRootNode;
+
+ /**
+ * Actual DOM element for which this element object acts as a proxy.
+ */
+ private Element mElement;
+
+ private boolean mDefaultNsSet;
+
+ /**
+ * Constructor for the virtual root element
+ */
+ private DOMOutputElement(Node rootNode)
+ {
+ super();
+ mRootNode = rootNode;
+ mParent = null;
+ mElement = null;
+ mNsMapping = null;
+ mNsMapShared = false;
+ mDefaultNsURI = "";
+ mRootNsContext = null;
+ mDefaultNsSet = false;
+ }
+
+ private DOMOutputElement(DOMOutputElement parent, Element element, BijectiveNsMap ns)
+ {
+ super(parent, ns);
+ mRootNode = null;
+ mParent = parent;
+ mElement = element;
+ mNsMapping = ns;
+ mNsMapShared = (ns != null);
+ mDefaultNsURI = parent.mDefaultNsURI;
+ mRootNsContext = parent.mRootNsContext;
+ mDefaultNsSet = false;
+ }
+
+ /**
+ * Method called to reuse a pooled instance.
+ *
+ * @returns Chained pooled instance that should now be head of the
+ * reuse chain
+ */
+ private void relink(DOMOutputElement parent, Element element)
+ {
+ super.relink(parent);
+ mParent = parent;
+ mElement = element;
+ parent.appendNode(element);
+ mDefaultNsSet = false;
+ }
+
+ public static DOMOutputElement createRoot(Node rootNode)
+ {
+ return new DOMOutputElement(rootNode);
+ }
+
+ /**
+ * Simplest factory method, which gets called when a 1-argument
+ * element output method is called. It is, then, assumed to
+ * use the default namespace.
+ * Will both create the child element and attach it to parent element,
+ * or lacking own owner document.
+ */
+ protected DOMOutputElement createAndAttachChild(Element element)
+ {
+ if (mRootNode != null) {
+ mRootNode.appendChild(element);
+ } else {
+ mElement.appendChild(element);
+ }
+ return createChild(element);
+ }
+
+ protected DOMOutputElement createChild(Element element)
+ {
+ return new DOMOutputElement(this, element, mNsMapping);
+ }
+
+ /**
+ * @return New head of the recycle pool
+ */
+ protected DOMOutputElement reuseAsChild(DOMOutputElement parent, Element element)
+ {
+ DOMOutputElement poolHead = mParent;
+ relink(parent, element);
+ return poolHead;
+ }
+
+ /**
+ * Method called to temporarily link this instance to a pool, to
+ * allow reusing of instances with the same reader.
+ */
+ protected void addToPool(DOMOutputElement poolHead)
+ {
+ mParent = poolHead;
+ }
+
+ /*
+ ///////////////////////////////////////////////////////////////////////
+ // Public API, accessors
+ ///////////////////////////////////////////////////////////////////////
+ */
+
+ public DOMOutputElement getParent() {
+ return mParent;
+ }
+
+ @Override
+ public boolean isRoot() {
+ // (Virtual) Root element has no parent...
+ return (mParent == null);
+ }
+
+ /**
+ * @return String presentation of the fully-qualified name, in
+ * "prefix:localName" format (no URI). Useful for error and
+ * debugging messages.
+ */
+ @Override
+ public String getNameDesc() {
+ if(mElement != null) {
+ return mElement.getLocalName();
+ }
+ return "#error"; // unexpected case
+ }
+
+ /*
+ ///////////////////////////////////////////////////////////////////////
+ // Public API, mutators
+ ///////////////////////////////////////////////////////////////////////
+ */
+
+ @Override
+ public void setDefaultNsUri(String uri) {
+ mDefaultNsURI = uri;
+ mDefaultNsSet = true;
+ }
+
+ @Override
+ protected void setRootNsContext(NamespaceContext ctxt)
+ {
+ mRootNsContext = ctxt;
+ /* Let's also see if we have an active default ns mapping:
+ * (provided it hasn't yet explicitly been set for this element)
+ */
+ if (!mDefaultNsSet) {
+ String defURI = ctxt.getNamespaceURI("");
+ if (defURI != null && defURI.length() > 0) {
+ mDefaultNsURI = defURI;
+ }
+ }
+ }
+
+ /*
+ ///////////////////////////////////////////////////////////////////////
+ // Public API, DOM manipulation
+ ///////////////////////////////////////////////////////////////////////
+ */
+
+ protected void appendNode(Node n)
+ {
+ if (mRootNode != null) {
+ mRootNode.appendChild(n);
+ } else {
+ mElement.appendChild(n);
+ }
+ }
+
+ protected void addAttribute(String pname, String value)
+ {
+ mElement.setAttribute(pname, value);
+ }
+
+ protected void addAttribute(String uri, String qname, String value)
+ {
+ mElement.setAttributeNS(uri, qname, value);
+ }
+
+ public void appendChild(Node n) {
+ mElement.appendChild(n);
+ }
+}
diff -Nru libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/dom/WstxDOMWrappingReader.java libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/dom/WstxDOMWrappingReader.java
--- libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/dom/WstxDOMWrappingReader.java 1970-01-01 00:00:00.000000000 +0000
+++ libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/dom/WstxDOMWrappingReader.java 2018-03-31 01:33:28.000000000 +0000
@@ -0,0 +1,92 @@
+package com.ctc.wstx.dom;
+
+import java.util.Collections;
+
+import javax.xml.stream.*;
+import javax.xml.transform.dom.DOMSource;
+
+import org.codehaus.stax2.ri.dom.DOMWrappingReader;
+
+import com.ctc.wstx.api.ReaderConfig;
+import com.ctc.wstx.exc.WstxParsingException;
+
+public class WstxDOMWrappingReader
+ extends DOMWrappingReader
+{
+ protected final ReaderConfig mConfig;
+
+ /*
+ ///////////////////////////////////////////////////
+ // Life-cycle
+ ///////////////////////////////////////////////////
+ */
+
+ protected WstxDOMWrappingReader(DOMSource src, ReaderConfig cfg)
+ throws XMLStreamException
+ {
+ super(src, cfg.willSupportNamespaces(), cfg.willCoalesceText());
+ mConfig = cfg;
+ // [WSTX-162]: allow enabling/disabling name/ns intern()ing
+ if (cfg.hasInternNamesBeenEnabled()) {
+ setInternNames(true);
+ }
+ if (cfg.hasInternNsURIsBeenEnabled()) {
+ setInternNsURIs(true);
+ }
+ }
+
+ public static WstxDOMWrappingReader createFrom(DOMSource src, ReaderConfig cfg)
+ throws XMLStreamException
+ {
+ return new WstxDOMWrappingReader(src, cfg);
+ }
+
+ /*
+ ///////////////////////////////////////////////////
+ // Defined/Overridden config methods
+ ///////////////////////////////////////////////////
+ */
+
+ @Override
+ public boolean isPropertySupported(String name) {
+ // !!! TBI: not all these properties are really supported
+ return mConfig.isPropertySupported(name);
+ }
+
+ @Override
+ public Object getProperty(String name)
+ {
+ if (name.equals("javax.xml.stream.entities")) {
+ // !!! TBI
+ return Collections.EMPTY_LIST;
+ }
+ if (name.equals("javax.xml.stream.notations")) {
+ // !!! TBI
+ return Collections.EMPTY_LIST;
+ }
+ return mConfig.getProperty(name);
+ }
+
+ @Override
+ public boolean setProperty(String name, Object value)
+ {
+ // Basic config accessor works just fine...
+ return mConfig.setProperty(name, value);
+ }
+
+ /*
+ ///////////////////////////////////////////////////
+ // Defined/Overridden error reporting
+ ///////////////////////////////////////////////////
+ */
+
+ @Override
+ protected void throwStreamException(String msg, Location loc)
+ throws XMLStreamException
+ {
+ if (loc == null) {
+ throw new WstxParsingException(msg);
+ }
+ throw new WstxParsingException(msg, loc);
+ }
+}
diff -Nru libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/dom/WstxDOMWrappingWriter.java libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/dom/WstxDOMWrappingWriter.java
--- libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/dom/WstxDOMWrappingWriter.java 1970-01-01 00:00:00.000000000 +0000
+++ libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/dom/WstxDOMWrappingWriter.java 2018-03-31 01:33:28.000000000 +0000
@@ -0,0 +1,761 @@
+package com.ctc.wstx.dom;
+
+import java.util.*;
+
+import javax.xml.XMLConstants;
+import javax.xml.namespace.*;
+import javax.xml.stream.*;
+import javax.xml.transform.dom.DOMResult;
+
+import org.w3c.dom.*;
+
+import org.codehaus.stax2.ri.EmptyNamespaceContext;
+import org.codehaus.stax2.ri.dom.DOMWrappingWriter;
+
+import com.ctc.wstx.api.WriterConfig;
+import com.ctc.wstx.cfg.ErrorConsts;
+import com.ctc.wstx.sw.OutputElementBase;
+
+/* TODO:
+ *
+ * - validator interface implementation
+ */
+
+/**
+ * This is an adapter class that allows building a DOM tree using
+ * {@link XMLStreamWriter} interface.
+ *
+ * Note that the implementation is only to be used for use with
+ * javax.xml.transform.dom.DOMResult
.
+ *
+ * Some notes regarding missing/incomplete functionality:
+ *
+ * - Validation functionality not implemented
+ *
+ *
+ *
+ * @author Tatu Saloranta
+ * @author Dan Diephouse
+ */
+public class WstxDOMWrappingWriter
+ extends DOMWrappingWriter
+{
+ /*
+ ///////////////////////////////////////////////////////////
+ // Constants
+ ///////////////////////////////////////////////////////////
+ */
+
+ final protected static String ERR_NSDECL_WRONG_STATE =
+ "Trying to write a namespace declaration when there is no open start element.";
+
+ /*
+ ///////////////////////////////////////////////////////////
+ // Configuration
+ ///////////////////////////////////////////////////////////
+ */
+
+ protected final WriterConfig mConfig;
+
+ /*
+ ///////////////////////////////////////////////////////////
+ // State
+ ///////////////////////////////////////////////////////////
+ */
+
+ /**
+ * This element is the current context element, under which
+ * all other nodes are added, until matching end element
+ * is output. Null outside of the main element tree.
+ *
+ * Note: explicit empty element (written using
+ * writeEmptyElement
) will never become
+ * current element.
+ */
+ protected DOMOutputElement mCurrElem;
+
+ /**
+ * This element is non-null right after a call to
+ * either writeStartElement
and
+ * writeEmptyElement
, and can be used to
+ * add attributes and namespace declarations.
+ *
+ * Note: while this is often the same as {@link #mCurrElem},
+ * it's not always. Specifically, an empty element (written
+ * explicitly using writeEmptyElement
) will
+ * become open element but NOT current element. Conversely,
+ * regular elements will remain current element when
+ * non elements are written (text, comments, PI), but
+ * not the open element.
+ */
+ protected DOMOutputElement mOpenElement;
+
+ /**
+ * for NsRepairing mode
+ */
+ protected int[] mAutoNsSeq;
+ protected String mSuggestedDefNs = null;
+ protected String mAutomaticNsPrefix;
+
+ /**
+ * Map that contains URI-to-prefix entries that point out suggested
+ * prefixes for URIs. These are populated by calls to
+ * {@link #setPrefix}, and they are only used as hints for binding;
+ * if there are conflicts, repairing writer can just use some other
+ * prefix.
+ */
+ HashMap mSuggestedPrefixes = null;
+
+ /*
+ ///////////////////////////////////////////////////////////
+ // Life-cycle
+ ///////////////////////////////////////////////////////////
+ */
+
+ private WstxDOMWrappingWriter(WriterConfig cfg, Node treeRoot)
+ throws XMLStreamException
+ {
+ super(treeRoot, cfg.willSupportNamespaces(), cfg.automaticNamespacesEnabled());
+ mConfig = cfg;
+ mAutoNsSeq = null;
+ mAutomaticNsPrefix = mNsRepairing ? mConfig.getAutomaticNsPrefix() : null;
+
+ /* Ok; we need a document node; or an element node; or a document
+ * fragment node.
+ */
+ switch (treeRoot.getNodeType()) {
+ case Node.DOCUMENT_NODE:
+ case Node.DOCUMENT_FRAGMENT_NODE:
+ // both are ok, but no current element
+ mCurrElem = DOMOutputElement.createRoot(treeRoot);
+ mOpenElement = null;
+ break;
+
+ case Node.ELEMENT_NODE: // can make sub-tree... ok
+ {
+ // still need a virtual root node as parent
+ DOMOutputElement root = DOMOutputElement.createRoot(treeRoot);
+ Element elem = (Element) treeRoot;
+ mOpenElement = mCurrElem = root.createChild(elem);
+ }
+ break;
+
+ default: // other Nodes not usable
+ throw new XMLStreamException("Can not create an XMLStreamWriter for a DOM node of type "+treeRoot.getClass());
+ }
+ }
+
+ public static WstxDOMWrappingWriter createFrom(WriterConfig cfg, DOMResult dst)
+ throws XMLStreamException
+ {
+ Node rootNode = dst.getNode();
+ return new WstxDOMWrappingWriter(cfg, rootNode);
+ }
+
+ /*
+ ///////////////////////////////////////////////////////////
+ // XMLStreamWriter API (Stax 1.0)
+ ///////////////////////////////////////////////////////////
+ */
+
+ //public void close() { }
+ //public void flush() { }
+
+ @Override
+ public NamespaceContext getNamespaceContext()
+ {
+ if (!mNsAware) {
+ return EmptyNamespaceContext.getInstance();
+ }
+ return mCurrElem;
+ }
+
+ @Override
+ public String getPrefix(String uri)
+ {
+ if (!mNsAware) {
+ return null;
+ }
+ if (mNsContext != null) {
+ String prefix = mNsContext.getPrefix(uri);
+ if (prefix != null) {
+ return prefix;
+ }
+ }
+ return mCurrElem.getPrefix(uri);
+ }
+
+ @Override
+ public Object getProperty(String name) {
+ return mConfig.getProperty(name);
+ }
+
+ @Override
+ public void setDefaultNamespace(String uri) {
+ mSuggestedDefNs = (uri == null || uri.length() == 0) ? null : uri;
+ }
+
+ //public void setNamespaceContext(NamespaceContext context)
+
+ @Override
+ public void setPrefix(String prefix, String uri)
+ throws XMLStreamException
+ {
+ if (prefix == null) {
+ throw new NullPointerException("Can not pass null 'prefix' value");
+ }
+ // Are we actually trying to set the default namespace?
+ if (prefix.length() == 0) {
+ setDefaultNamespace(uri);
+ return;
+ }
+ if (uri == null) {
+ throw new NullPointerException("Can not pass null 'uri' value");
+ }
+
+ /* Let's verify that xml/xmlns are never (mis)declared; as
+ * mandated by XML NS specification
+ */
+ {
+ if (prefix.equals("xml")) {
+ if (!uri.equals(XMLConstants.XML_NS_URI)) {
+ throwOutputError(ErrorConsts.ERR_NS_REDECL_XML, uri);
+ }
+ } else if (prefix.equals("xmlns")) { // prefix "xmlns"
+ if (!uri.equals(XMLConstants.XMLNS_ATTRIBUTE_NS_URI)) {
+ throwOutputError(ErrorConsts.ERR_NS_REDECL_XMLNS, uri);
+ }
+ // At any rate; we are NOT to output it
+ return;
+ } else {
+ // Neither of prefixes.. but how about URIs?
+ if (uri.equals(XMLConstants.XML_NS_URI)) {
+ throwOutputError(ErrorConsts.ERR_NS_REDECL_XML_URI, prefix);
+ } else if (uri.equals(XMLConstants.XMLNS_ATTRIBUTE_NS_URI)) {
+ throwOutputError(ErrorConsts.ERR_NS_REDECL_XMLNS_URI, prefix);
+ }
+ }
+ }
+
+ if (mSuggestedPrefixes == null) {
+ mSuggestedPrefixes = new HashMap(16);
+ }
+ mSuggestedPrefixes.put(uri, prefix);
+
+ }
+
+ @Override
+ public void writeAttribute(String localName, String value)
+ throws XMLStreamException
+ {
+ outputAttribute(null, null, localName, value);
+ }
+
+ @Override
+ public void writeAttribute(String nsURI, String localName, String value)
+ throws XMLStreamException
+ {
+ outputAttribute(nsURI, null, localName, value);
+ }
+
+ @Override
+ public void writeAttribute(String prefix, String nsURI, String localName, String value)
+ throws XMLStreamException
+ {
+ outputAttribute(nsURI, prefix, localName, value);
+ }
+
+ //public void writeCData(String data)
+ //public void writeCharacters(char[] text, int start, int len)
+ //public void writeCharacters(String text)
+ //public void writeComment(String data)
+
+ @Override
+ public void writeDefaultNamespace(String nsURI)
+ {
+ if (mOpenElement == null) {
+ throw new IllegalStateException("No currently open START_ELEMENT, cannot write attribute");
+ }
+ setDefaultNamespace(nsURI);
+ mOpenElement.addAttribute(XMLConstants.XMLNS_ATTRIBUTE_NS_URI, "xmlns", nsURI);
+ }
+
+ //public void writeDTD(String dtd)
+
+ @Override
+ public void writeEmptyElement(String localName)
+ throws XMLStreamException
+ {
+ writeEmptyElement(null, localName);
+ }
+
+ @Override
+ public void writeEmptyElement(String nsURI, String localName)
+ throws XMLStreamException
+ {
+ // First things first: must
+
+ /* Note: can not just call writeStartElement(), since this
+ * element will only become the open elem, but not a parent elem
+ */
+ createStartElem(nsURI, null, localName, true);
+ }
+
+ @Override
+ public void writeEmptyElement(String prefix, String localName, String nsURI)
+ throws XMLStreamException
+ {
+ if (prefix == null) { // passing null would mean "dont care", if repairing
+ prefix = "";
+ }
+ createStartElem(nsURI, prefix, localName, true);
+ }
+
+ @Override
+ public void writeEndDocument()
+ {
+ mCurrElem = mOpenElement = null;
+ }
+
+ @Override
+ public void writeEndElement()
+ {
+ // Simple, just need to traverse up... if we can
+ if (mCurrElem == null || mCurrElem.isRoot()) {
+ throw new IllegalStateException("No open start element to close");
+ }
+ mOpenElement = null; // just in case it was open
+ mCurrElem = mCurrElem.getParent();
+ }
+
+ //public void writeEntityRef(String name)
+
+ @Override
+ public void writeNamespace(String prefix, String nsURI) throws XMLStreamException
+ {
+ if (prefix == null || prefix.length() == 0) {
+ writeDefaultNamespace(nsURI);
+ return;
+ }
+ if (!mNsAware) {
+ throwOutputError("Can not write namespaces with non-namespace writer.");
+ }
+ outputAttribute(XMLConstants.XMLNS_ATTRIBUTE_NS_URI, "xmlns", prefix, nsURI);
+ mCurrElem.addPrefix(prefix, nsURI);
+ }
+
+ //public void writeProcessingInstruction(String target)
+ //public void writeProcessingInstruction(String target, String data)
+
+ //public void writeStartDocument()
+ //public void writeStartDocument(String version)
+ //public void writeStartDocument(String encoding, String version)
+
+ @Override
+ public void writeStartElement(String localName)
+ throws XMLStreamException
+ {
+ writeStartElement(null, localName);
+ }
+
+ @Override
+ public void writeStartElement(String nsURI, String localName)
+ throws XMLStreamException
+ {
+ createStartElem(nsURI, null, localName, false);
+ }
+
+ @Override
+ public void writeStartElement(String prefix, String localName, String nsURI)
+ throws XMLStreamException
+ {
+ createStartElem(nsURI, prefix, localName, false);
+ }
+
+ /*
+ ///////////////////////////////////////////////////////////
+ // XMLStreamWriter2 API (Stax2 v3.0):
+ // additional accessors
+ ///////////////////////////////////////////////////////////
+ */
+
+ //public XMLStreamLocation2 getLocation()
+ //public String getEncoding()
+
+ @Override
+ public boolean isPropertySupported(String name)
+ {
+ // !!! TBI: not all these properties are really supported
+ return mConfig.isPropertySupported(name);
+ }
+
+ @Override
+ public boolean setProperty(String name, Object value)
+ {
+ /* Note: can not call local method, since it'll return false for
+ * recognized but non-mutable properties
+ */
+ return mConfig.setProperty(name, value);
+ }
+
+ /*
+ ///////////////////////////////////////////////////////////
+ // XMLStreamWriter2 API (Stax2 v2.0):
+ // extended write methods
+ ///////////////////////////////////////////////////////////
+ */
+
+ //public void writeCData(char[] text, int start, int len)
+
+ @Override
+ public void writeDTD(String rootName, String systemId, String publicId,
+ String internalSubset)
+ throws XMLStreamException
+ {
+ /* Alas: although we can create a DocumentType object, there
+ * doesn't seem to be a way to attach it in DOM-2!
+ */
+ if (mCurrElem != null) {
+ throw new IllegalStateException("Operation only allowed to the document before adding root element");
+ }
+ reportUnsupported("writeDTD()");
+ }
+
+ //public void writeFullEndElement() throws XMLStreamException
+
+ //public void writeSpace(char[] text, int start, int len)
+ //public void writeSpace(String text)
+
+
+ //public void writeStartDocument(String version, String encoding, boolean standAlone)
+
+ /*
+ ///////////////////////////////////////////////////////////
+ // XMLStreamWriter2 API (Stax2 v2.0): validation
+ ///////////////////////////////////////////////////////////
+ */
+
+ //public XMLValidator validateAgainst(XMLValidationSchema schema)
+ //public XMLValidator stopValidatingAgainst(XMLValidationSchema schema)
+ //public XMLValidator stopValidatingAgainst(XMLValidator validator)
+ //public ValidationProblemHandler setValidationProblemHandler(ValidationProblemHandler h)
+
+ /*
+ ///////////////////////////////////////////////////////////
+ // Impls of abstract methods from base class
+ ///////////////////////////////////////////////////////////
+ */
+
+ @Override
+ protected void appendLeaf(Node n)
+ throws IllegalStateException
+ {
+ mCurrElem.appendNode(n);
+ mOpenElement = null;
+ }
+
+ /*
+ ///////////////////////////////////////////////////////////
+ // Internal methods
+ ///////////////////////////////////////////////////////////
+ */
+
+ /* Note: copied from regular RepairingNsStreamWriter#writeStartOrEmpty
+ * (and its non-repairing counterpart).
+ */
+
+ /**
+ * Method called by all start element write methods.
+ *
+ * @param nsURI Namespace URI to use: null and empty String denote 'no namespace'
+ */
+ protected void createStartElem(String nsURI, String prefix, String localName, boolean isEmpty)
+ throws XMLStreamException
+ {
+ DOMOutputElement elem;
+
+ if (!mNsAware) {
+ if(nsURI != null && nsURI.length() > 0) {
+ throwOutputError("Can not specify non-empty uri/prefix in non-namespace mode");
+ }
+ elem = mCurrElem.createAndAttachChild(mDocument.createElement(localName));
+ } else {
+ if (mNsRepairing) {
+ String actPrefix = validateElemPrefix(prefix, nsURI, mCurrElem);
+ if (actPrefix != null) { // fine, an existing binding we can use:
+ if (actPrefix.length() != 0) {
+ elem = mCurrElem.createAndAttachChild(mDocument.createElementNS(nsURI, actPrefix+":"+localName));
+ } else {
+ elem = mCurrElem.createAndAttachChild(mDocument.createElementNS(nsURI, localName));
+ }
+ } else { // nah, need to create a new binding...
+ /* Need to ensure that we'll pass "" as prefix, not null,
+ * so it is understood as "I want to use the default NS",
+ * not as "whatever prefix, I don't care"
+ */
+ if (prefix == null) {
+ prefix = "";
+ }
+ actPrefix = generateElemPrefix(prefix, nsURI, mCurrElem);
+ boolean hasPrefix = (actPrefix.length() != 0);
+ if (hasPrefix) {
+ localName = actPrefix + ":" + localName;
+ }
+ elem = mCurrElem.createAndAttachChild(mDocument.createElementNS(nsURI, localName));
+ /* Hmmh. writeNamespace method requires open element
+ * to be defined. So we'll need to set it first
+ * (will be set again at a later point -- would be
+ * good to refactor this method into separate
+ * sub-classes or so)
+ */
+ mOpenElement = elem;
+ // Need to add new ns declaration as well
+ if (hasPrefix) {
+ writeNamespace(actPrefix, nsURI);
+ elem.addPrefix(actPrefix, nsURI);
+ } else {
+ writeDefaultNamespace(nsURI);
+ elem.setDefaultNsUri(nsURI);
+ }
+ }
+ } else {
+ /* Non-repairing; if non-null prefix (including "" to
+ * indicate "no prefix") passed, use as is, otherwise
+ * try to locate the prefix if got namespace.
+ */
+ if (prefix == null && nsURI != null && nsURI.length() > 0) {
+ prefix = (mSuggestedPrefixes == null) ? null : mSuggestedPrefixes.get(nsURI);
+ if (prefix == null) {
+ throwOutputError("Can not find prefix for namespace \""+nsURI+"\"");
+ }
+ }
+ if (prefix != null && prefix.length() != 0) {
+ localName = prefix + ":" +localName;
+ }
+ elem = mCurrElem.createAndAttachChild(mDocument.createElementNS(nsURI, localName));
+ }
+ }
+ /* Got the element; need to make it the open element, and
+ * if it's not an (explicit) empty element, current element as well
+ */
+ mOpenElement = elem;
+ if (!isEmpty) {
+ mCurrElem = elem;
+ }
+ }
+
+ protected void outputAttribute(String nsURI, String prefix, String localName, String value)
+ throws XMLStreamException
+ {
+ if (mOpenElement == null) {
+ throw new IllegalStateException("No currently open START_ELEMENT, cannot write attribute");
+ }
+
+ if (mNsAware) {
+ if (mNsRepairing) {
+ prefix = findOrCreateAttrPrefix(prefix, nsURI, mOpenElement);
+ }
+ if (prefix != null && prefix.length() > 0) {
+ localName = prefix + ":" + localName;
+ }
+ mOpenElement.addAttribute(nsURI, localName, value);
+ } else { // non-ns, simple
+ if (prefix != null && prefix.length() > 0) {
+ localName = prefix + ":" + localName;
+ }
+ mOpenElement.addAttribute(localName, value);
+ }
+ }
+
+ private final String validateElemPrefix(String prefix, String nsURI,
+ DOMOutputElement elem)
+ throws XMLStreamException
+ {
+ /* 06-Feb-2005, TSa: Special care needs to be taken for the
+ * "empty" (or missing) namespace:
+ * (see comments from findOrCreatePrefix())
+ */
+ if (nsURI == null || nsURI.length() == 0) {
+ String currURL = elem.getDefaultNsUri();
+ if (currURL == null || currURL.length() == 0) {
+ // Ok, good:
+ return "";
+ }
+ // Nope, needs to be re-bound:
+ return null;
+ }
+
+ int status = elem.isPrefixValid(prefix, nsURI, true);
+ if (status == DOMOutputElement.PREFIX_OK) {
+ return prefix;
+ }
+ return null;
+ }
+
+ /*
+ ///////////////////////////////////////////////////////////
+ // Internal methods
+ ///////////////////////////////////////////////////////////
+ */
+
+ /**
+ * Method called to find an existing prefix for the given namespace,
+ * if any exists in the scope. If one is found, it's returned (including
+ * "" for the current default namespace); if not, null is returned.
+ *
+ * @param nsURI URI of namespace for which we need a prefix
+ */
+ protected final String findElemPrefix(String nsURI, DOMOutputElement elem)
+ throws XMLStreamException
+ {
+ /* Special case: empty NS URI can only be bound to the empty
+ * prefix...
+ */
+ if (nsURI == null || nsURI.length() == 0) {
+ String currDefNsURI = elem.getDefaultNsUri();
+ if (currDefNsURI != null && currDefNsURI.length() > 0) {
+ // Nope; won't do... has to be re-bound, but not here:
+ return null;
+ }
+ return "";
+ }
+ return mCurrElem.getPrefix(nsURI);
+ }
+
+
+ /**
+ * Method called after {@link #findElemPrefix} has returned null,
+ * to create and bind a namespace mapping for specified namespace.
+ */
+ protected final String generateElemPrefix(String suggPrefix, String nsURI,
+ DOMOutputElement elem)
+ throws XMLStreamException
+ {
+ /* Ok... now, since we do not have an existing mapping, let's
+ * see if we have a preferred prefix to use.
+ */
+ /* Except if we need the empty namespace... that can only be
+ * bound to the empty prefix:
+ */
+ if (nsURI == null || nsURI.length() == 0) {
+ return "";
+ }
+
+ /* Ok; with elements this is easy: the preferred prefix can
+ * ALWAYS be used, since it can mask preceding bindings:
+ */
+ if (suggPrefix == null) {
+ // caller wants this URI to map as the default namespace?
+ if (mSuggestedDefNs != null && mSuggestedDefNs.equals(nsURI)) {
+ suggPrefix = "";
+ } else {
+ suggPrefix = (mSuggestedPrefixes == null) ? null: mSuggestedPrefixes.get(nsURI);
+ if (suggPrefix == null) {
+ /* 16-Oct-2005, TSa: We have 2 choices here, essentially;
+ * could make elements always try to override the def
+ * ns... or can just generate new one. Let's do latter
+ * for now.
+ */
+ if (mAutoNsSeq == null) {
+ mAutoNsSeq = new int[1];
+ mAutoNsSeq[0] = 1;
+ }
+ suggPrefix = elem.generateMapping(mAutomaticNsPrefix, nsURI,
+ mAutoNsSeq);
+ }
+ }
+ }
+
+ // Ok; let's let the caller deal with bindings
+ return suggPrefix;
+ }
+
+
+ /**
+ * Method called to somehow find a prefix for given namespace, to be
+ * used for a new start element; either use an existing one, or
+ * generate a new one. If a new mapping needs to be generated,
+ * it will also be automatically bound, and necessary namespace
+ * declaration output.
+ *
+ * @param suggPrefix Suggested prefix to bind, if any; may be null
+ * to indicate "no preference"
+ * @param nsURI URI of namespace for which we need a prefix
+ * @param elem Currently open start element, on which the attribute
+ * will be added.
+ */
+ protected final String findOrCreateAttrPrefix(String suggPrefix, String nsURI,
+ DOMOutputElement elem)
+ throws XMLStreamException
+ {
+ if (nsURI == null || nsURI.length() == 0) {
+ /* Attributes never use the default namespace; missing
+ * prefix always leads to the empty ns... so nothing
+ * special is needed here.
+ */
+ return null;
+ }
+ // Maybe the suggested prefix is properly bound?
+ if (suggPrefix != null) {
+ int status = elem.isPrefixValid(suggPrefix, nsURI, false);
+ if (status == OutputElementBase.PREFIX_OK) {
+ return suggPrefix;
+ }
+ /* Otherwise, if the prefix is unbound, let's just bind
+ * it -- if caller specified a prefix, it probably prefers
+ * binding that prefix even if another prefix already existed?
+ * The remaining case (already bound to another URI) we don't
+ * want to touch, at least not yet: it may or not be safe
+ * to change binding, so let's just not try it.
+ */
+ if (status == OutputElementBase.PREFIX_UNBOUND) {
+ elem.addPrefix(suggPrefix, nsURI);
+ writeNamespace(suggPrefix, nsURI);
+ return suggPrefix;
+ }
+ }
+
+ // If not, perhaps there's another existing binding available?
+ String prefix = elem.getExplicitPrefix(nsURI);
+ if (prefix != null) { // already had a mapping for the URI... cool.
+ return prefix;
+ }
+
+ /* Nope, need to create one. First, let's see if there's a
+ * preference...
+ */
+ if (suggPrefix != null) {
+ prefix = suggPrefix;
+ } else if (mSuggestedPrefixes != null) {
+ prefix = mSuggestedPrefixes.get(nsURI);
+ // note: def ns is never added to suggested prefix map
+ }
+
+ if (prefix != null) {
+ /* Can not use default namespace for attributes.
+ * Also, re-binding is tricky for attributes; can't
+ * re-bind anything that's bound on this scope... or
+ * used in this scope. So, to simplify life, let's not
+ * re-bind anything for attributes.
+ */
+ if (prefix.length() == 0
+ || (elem.getNamespaceURI(prefix) != null)) {
+ prefix = null;
+ }
+ }
+
+ if (prefix == null) {
+ if (mAutoNsSeq == null) {
+ mAutoNsSeq = new int[1];
+ mAutoNsSeq[0] = 1;
+ }
+ prefix = mCurrElem.generateMapping(mAutomaticNsPrefix, nsURI,
+ mAutoNsSeq);
+ }
+
+ // Ok; so far so good: let's now bind and output the namespace:
+ elem.addPrefix(prefix, nsURI);
+ writeNamespace(prefix, nsURI);
+ return prefix;
+ }
+}
diff -Nru libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/dtd/ChoiceContentSpec.java libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/dtd/ChoiceContentSpec.java
--- libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/dtd/ChoiceContentSpec.java 1970-01-01 00:00:00.000000000 +0000
+++ libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/dtd/ChoiceContentSpec.java 2018-03-31 01:33:28.000000000 +0000
@@ -0,0 +1,246 @@
+package com.ctc.wstx.dtd;
+
+import java.util.*;
+
+import com.ctc.wstx.util.ExceptionUtil;
+import com.ctc.wstx.util.PrefixedName;
+
+/**
+ * Content specification that defines content model that has
+ * multiple alternative elements; including mixed content model.
+ */
+public class ChoiceContentSpec
+ extends ContentSpec
+{
+ final boolean mNsAware;
+
+ /**
+ * Whether this is a mixed content model; mostly affects String
+ * representation
+ */
+ final boolean mHasMixed;
+
+ final ContentSpec[] mContentSpecs;
+
+ /*
+ ///////////////////////////////////////////////////
+ // Life-cycle
+ ///////////////////////////////////////////////////
+ */
+
+ private ChoiceContentSpec(boolean nsAware, char arity, boolean mixed,
+ ContentSpec[] specs)
+ {
+ super(arity);
+ mNsAware = nsAware;
+ mHasMixed = mixed;
+ mContentSpecs = specs;
+ }
+
+ private ChoiceContentSpec(boolean nsAware, char arity, boolean mixed, Collection specs)
+ {
+ super(arity);
+ mNsAware = nsAware;
+ mHasMixed = mixed;
+ mContentSpecs = new ContentSpec[specs.size()];
+ specs.toArray(mContentSpecs);
+ }
+
+ public static ChoiceContentSpec constructChoice(boolean nsAware, char arity,
+ Collection specs)
+ {
+ return new ChoiceContentSpec(nsAware, arity, false, specs);
+ }
+
+ public static ChoiceContentSpec constructMixed(boolean nsAware, Collection specs)
+ {
+ return new ChoiceContentSpec(nsAware, '*', true, specs);
+ }
+
+ /*
+ ///////////////////////////////////////////////////
+ // Public API
+ ///////////////////////////////////////////////////
+ */
+
+ @Override
+ public StructValidator getSimpleValidator()
+ {
+ /* Can we create a simple validator? Yes, if the sub-specs are
+ * all simple (leaves == element tokens with no arity modifier);
+ * this is always true for mixed.
+ */
+ ContentSpec[] specs = mContentSpecs;
+ int len = specs.length;
+ int i;
+
+ if (mHasMixed) {
+ i = len;
+ } else {
+ i = 0;
+ for (; i < len; ++i) {
+ if (!specs[i].isLeaf()) {
+ break;
+ }
+ }
+ }
+
+ if (i == len) { // all leaves, kewl
+ PrefixedNameSet keyset = namesetFromSpecs(mNsAware, specs);
+ return new Validator(mArity, keyset);
+ }
+
+ // Nah, need a DFA...
+ return null;
+ }
+
+ @Override
+ public ModelNode rewrite()
+ {
+ // First, need to convert sub-specs:
+ ContentSpec[] specs = mContentSpecs;
+ int len = specs.length;
+ ModelNode[] models = new ModelNode[len];
+ for (int i = 0; i < len; ++i) {
+ models[i] = specs[i].rewrite();
+ }
+ ChoiceModel model = new ChoiceModel(models);
+
+ // and then resolve arity modifiers, if necessary:
+ if (mArity == '*') {
+ return new StarModel(model);
+ }
+ if (mArity == '?') {
+ return new OptionalModel(model);
+ }
+ if (mArity == '+') {
+ return new ConcatModel(model,
+ new StarModel(model.cloneModel()));
+ }
+ return model;
+ }
+
+ @Override
+ public String toString()
+ {
+ StringBuilder sb = new StringBuilder();
+
+ if (mHasMixed) {
+ sb.append("(#PCDATA | ");
+ } else {
+ sb.append('(');
+ }
+ for (int i = 0; i < mContentSpecs.length; ++i) {
+ if (i > 0) {
+ sb.append(" | ");
+ }
+ sb.append(mContentSpecs[i].toString());
+ }
+ sb.append(')');
+
+ if (mArity != ' ') {
+ sb.append(mArity);
+ }
+ return sb.toString();
+ }
+
+ /*
+ ///////////////////////////////////////////////////
+ // Internal methods
+ ///////////////////////////////////////////////////
+ */
+
+ /*
+ ///////////////////////////////////////////////////
+ // Package methods
+ ///////////////////////////////////////////////////
+ */
+
+ protected static PrefixedNameSet namesetFromSpecs(boolean nsAware, ContentSpec[] specs)
+ {
+ int len = specs.length;
+ PrefixedName[] nameArray = new PrefixedName[len];
+ for (int i = 0; i < len; ++i) {
+ nameArray[i] = ((TokenContentSpec)specs[i]).getName();
+ }
+
+ if (len < 5) { // 4 or fewer elements -> small
+ return new SmallPrefixedNameSet(nsAware, nameArray);
+ }
+ return new LargePrefixedNameSet(nsAware, nameArray);
+ }
+
+ /*
+ ///////////////////////////////////////////////////
+ // Validator class that can be used for simple
+ // choices (including mixed content)
+ ///////////////////////////////////////////////////
+ */
+
+ final static class Validator
+ extends StructValidator
+ {
+ final char mArity;
+ final PrefixedNameSet mNames;
+
+ int mCount = 0;
+
+ public Validator(char arity, PrefixedNameSet names)
+ {
+ mArity = arity;
+ mNames = names;
+ }
+
+ /**
+ * Rules for reuse are simple: if we can have any number of
+ * repetitions, we can just use a shared root instance. Although
+ * its count variable will get updated this doesn't really
+ * matter as it won't be used. Otherwise a new instance has to
+ * be created always, to keep track of instance counts.
+ */
+ @Override
+ public StructValidator newInstance() {
+ return (mArity == '*') ? this : new Validator(mArity, mNames);
+ }
+
+ @Override
+ public String tryToValidate(PrefixedName elemName)
+ {
+ if (!mNames.contains(elemName)) {
+ if (mNames.hasMultiple()) {
+ return "Expected one of ("+mNames.toString(" | ")+")";
+ }
+ return "Expected <"+mNames.toString("")+">";
+ }
+ if (++mCount > 1 && (mArity == '?' || mArity == ' ')) {
+ if (mNames.hasMultiple()) {
+ return "Expected $END (already had one of ["
+ +mNames.toString(" | ")+"]";
+ }
+ return "Expected $END (already had one <"
+ +mNames.toString("")+">]";
+ }
+ return null;
+ }
+
+ @Override
+ public String fullyValid()
+ {
+ switch (mArity) {
+ case '*':
+ case '?':
+ return null;
+ case '+': // need at least one (and multiples checked earlier)
+ case ' ':
+ if (mCount > 0) {
+ return null;
+ }
+ return "Expected "+(mArity == '+' ? "at least" : "")
+ +" one of elements ("+mNames+")";
+ }
+ // should never happen:
+ ExceptionUtil.throwGenericInternal();
+ return null;
+ }
+ }
+}
diff -Nru libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/dtd/ChoiceModel.java libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/dtd/ChoiceModel.java
--- libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/dtd/ChoiceModel.java 1970-01-01 00:00:00.000000000 +0000
+++ libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/dtd/ChoiceModel.java 2018-03-31 01:33:28.000000000 +0000
@@ -0,0 +1,117 @@
+package com.ctc.wstx.dtd;
+
+import java.util.*;
+
+/**
+ * Model class that encapsulates set of sub-models, of which one (and only
+ * one) needs to be matched.
+ */
+public class ChoiceModel
+ extends ModelNode
+{
+ final ModelNode[] mSubModels;
+
+ boolean mNullable = false;
+
+ BitSet mFirstPos, mLastPos;
+
+ /*
+ ///////////////////////////////////////////////////
+ // Life-cycle
+ ///////////////////////////////////////////////////
+ */
+
+ protected ChoiceModel(ModelNode[] subModels)
+ {
+ super();
+ mSubModels = subModels;
+ boolean nullable = false;
+ for (int i = 0, len = subModels.length; i < len; ++i) {
+ if (subModels[i].isNullable()) {
+ nullable = true;
+ break;
+ }
+ }
+ mNullable = nullable;
+ }
+
+ /*
+ ///////////////////////////////////////////////////
+ // Public API
+ ///////////////////////////////////////////////////
+ */
+
+ @Override
+ public String toString()
+ {
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < mSubModels.length; ++i) {
+ if (i > 0) {
+ sb.append(" | ");
+ }
+ sb.append(mSubModels[i].toString());
+ }
+ sb.append(')');
+ return sb.toString();
+ }
+
+ /**
+ * Method that has to create a deep copy of the model, without
+ * sharing any of existing Objects.
+ */
+ @Override
+ public ModelNode cloneModel()
+ {
+ int len = mSubModels.length;
+ ModelNode[] newModels = new ModelNode[len];
+ for (int i = 0; i < len; ++i) {
+ newModels[i] = mSubModels[i].cloneModel();
+ }
+ return new ChoiceModel(newModels);
+ }
+
+ @Override
+ public boolean isNullable() {
+ return mNullable;
+ }
+
+ @Override
+ public void indexTokens(List tokens)
+ {
+ // First, let's ask sub-models to calc their settings
+ for (int i = 0, len = mSubModels.length; i < len; ++i) {
+ mSubModels[i].indexTokens(tokens);
+ }
+ }
+
+ @Override
+ public void addFirstPos(BitSet firstPos) {
+ if (mFirstPos == null) {
+ mFirstPos = new BitSet();
+ for (int i = 0, len = mSubModels.length; i < len; ++i) {
+ mSubModels[i].addFirstPos(mFirstPos);
+ }
+ }
+ firstPos.or(mFirstPos);
+ }
+
+ @Override
+ public void addLastPos(BitSet lastPos) {
+ if (mLastPos == null) {
+ mLastPos = new BitSet();
+ for (int i = 0, len = mSubModels.length; i < len; ++i) {
+ mSubModels[i].addLastPos(mLastPos);
+ }
+ }
+ lastPos.or(mLastPos);
+ }
+
+ @Override
+ public void calcFollowPos(BitSet[] followPosSets)
+ {
+ // need to let child models do their stuff:
+ for (int i = 0, len = mSubModels.length; i < len; ++i) {
+ mSubModels[i].calcFollowPos(followPosSets);
+ }
+ }
+}
diff -Nru libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/dtd/ConcatModel.java libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/dtd/ConcatModel.java
--- libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/dtd/ConcatModel.java 1970-01-01 00:00:00.000000000 +0000
+++ libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/dtd/ConcatModel.java 2018-03-31 01:33:28.000000000 +0000
@@ -0,0 +1,119 @@
+package com.ctc.wstx.dtd;
+
+import java.util.*;
+
+/**
+ * Model class that represents sequence of 2 sub-models, needed to be
+ * matched in the order.
+ */
+public class ConcatModel
+ extends ModelNode
+{
+ ModelNode mLeftModel;
+ ModelNode mRightModel;
+
+ final boolean mNullable;
+
+ BitSet mFirstPos, mLastPos;
+
+ /*
+ ///////////////////////////////////////////////////
+ // Life-cycle
+ ///////////////////////////////////////////////////
+ */
+
+ public ConcatModel(ModelNode left, ModelNode right)
+ {
+ super();
+ mLeftModel = left;
+ mRightModel = right;
+ mNullable = mLeftModel.isNullable() && mRightModel.isNullable();
+ }
+
+ /*
+ ///////////////////////////////////////////////////
+ // Public API
+ ///////////////////////////////////////////////////
+ */
+
+ /**
+ * Method that has to create a deep copy of the model, without
+ * sharing any of existing Objects.
+ */
+ @Override
+ public ModelNode cloneModel() {
+ return new ConcatModel(mLeftModel.cloneModel(), mRightModel.cloneModel());
+ }
+
+ @Override
+ public boolean isNullable() {
+ return mNullable;
+ }
+
+ @Override
+ public void indexTokens(List tokens)
+ {
+ mLeftModel.indexTokens(tokens);
+ mRightModel.indexTokens(tokens);
+ }
+
+ @Override
+ public void addFirstPos(BitSet pos) {
+ if (mFirstPos == null) {
+ mFirstPos = new BitSet();
+ mLeftModel.addFirstPos(mFirstPos);
+ if (mLeftModel.isNullable()) {
+ mRightModel.addFirstPos(mFirstPos);
+ }
+ }
+ pos.or(mFirstPos);
+ }
+
+ @Override
+ public void addLastPos(BitSet pos) {
+ if (mLastPos == null) {
+ mLastPos = new BitSet();
+ mRightModel.addLastPos(mLastPos);
+ if (mRightModel.isNullable()) {
+ mLeftModel.addLastPos(mLastPos);
+ }
+ }
+ pos.or(mLastPos);
+ }
+
+ @Override
+ public void calcFollowPos(BitSet[] followPosSets)
+ {
+ // Let's let sub-models do what they need to do
+ mLeftModel.calcFollowPos(followPosSets);
+ mRightModel.calcFollowPos(followPosSets);
+
+ /* And then we can calculate follower sets between left and
+ * right sub models; so that left model's last position entries
+ * have right model's first position entries included
+ */
+ BitSet foll = new BitSet();
+ mRightModel.addFirstPos(foll);
+
+ BitSet toAddTo = new BitSet();
+ mLeftModel.addLastPos(toAddTo);
+
+ int ix = 0; // need to/can skip the null entry (index 0)
+ while ((ix = toAddTo.nextSetBit(ix+1)) >= 0) {
+ // Ok; so token at this index needs to have follow positions added...
+ followPosSets[ix].or(foll);
+ }
+ }
+
+ @Override
+ public String toString()
+ {
+ StringBuilder sb = new StringBuilder();
+ sb.append('(');
+ sb.append(mLeftModel.toString());
+ sb.append(", ");
+ sb.append(mRightModel.toString());
+ sb.append(')');
+ return sb.toString();
+ }
+}
diff -Nru libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/dtd/ContentSpec.java libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/dtd/ContentSpec.java
--- libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/dtd/ContentSpec.java 1970-01-01 00:00:00.000000000 +0000
+++ libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/dtd/ContentSpec.java 2018-03-31 01:33:28.000000000 +0000
@@ -0,0 +1,68 @@
+/* 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 com.ctc.wstx.dtd;
+
+/**
+ * Abstract base class for classes that contain parts of a content
+ * specification of an element defined in DTD. They are created
+ * by {@link FullDTDReader} when parsing an DTD subset, and they
+ * will be used for constructing actual validators for the element
+ * content.
+ */
+public abstract class ContentSpec
+{
+ protected char mArity;
+
+ /*
+ ///////////////////////////////////////////////////
+ // Life-cycle
+ ///////////////////////////////////////////////////
+ */
+
+ public ContentSpec(char arity) {
+ mArity = arity;
+ }
+
+ /*
+ ///////////////////////////////////////////////////
+ // Public API
+ ///////////////////////////////////////////////////
+ */
+
+ public final char getArity() { return mArity; }
+
+ public final void setArity(char c) { mArity = c; }
+
+ public boolean isLeaf() { return false; }
+
+ /**
+ * Method called by input element stack to get validator for
+ * this content specification, if this specification is simple
+ * enough not to need full DFA-based validator.
+ *
+ * @return Simple content model validator, if one can be directly
+ * constructed, or null to indicate that a DFA needs to be
+ * created.
+ */
+ public abstract StructValidator getSimpleValidator();
+
+ /**
+ * Method called as the first part of DFA construction, if necessary;
+ * will usually create simpler {@link ModelNode} instances that will
+ * match definition this instance contains.
+ */
+ public abstract ModelNode rewrite();
+}
diff -Nru libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/dtd/DefaultAttrValue.java libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/dtd/DefaultAttrValue.java
--- libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/dtd/DefaultAttrValue.java 1970-01-01 00:00:00.000000000 +0000
+++ libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/dtd/DefaultAttrValue.java 2018-03-31 01:33:28.000000000 +0000
@@ -0,0 +1,218 @@
+/* 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 com.ctc.wstx.dtd;
+
+import java.text.MessageFormat;
+
+import javax.xml.stream.Location;
+import javax.xml.stream.XMLStreamException;
+
+import org.codehaus.stax2.validation.ValidationContext;
+import org.codehaus.stax2.validation.XMLValidationProblem;
+import org.codehaus.stax2.validation.XMLValidator;
+
+import com.ctc.wstx.cfg.ErrorConsts;
+
+/**
+ * Simple container class used to contain information about the default
+ * value for an attribute. Although for most use cases a simple String
+ * would suffice, there are cases where additional information is needed
+ * (especially status of 'broken' default values, which only need to be
+ * reported should the default value be needed).
+ */
+public final class DefaultAttrValue
+{
+ /*
+ ////////////////////////////////////////////////////
+ // Constants
+ ////////////////////////////////////////////////////
+ */
+
+ // // // Default value types
+
+ public final static int DEF_DEFAULT = 1;
+ public final static int DEF_IMPLIED = 2;
+ public final static int DEF_REQUIRED = 3;
+ public final static int DEF_FIXED = 4;
+
+ /*
+ ////////////////////////////////////////////////////
+ // Singleton instances
+ ////////////////////////////////////////////////////
+ */
+
+ final static DefaultAttrValue sImplied = new DefaultAttrValue(DEF_IMPLIED);
+
+ final static DefaultAttrValue sRequired = new DefaultAttrValue(DEF_REQUIRED);
+
+ /*
+ ////////////////////////////////////////////////////
+ // State
+ ////////////////////////////////////////////////////
+ */
+
+ final int mDefValueType;
+
+ /**
+ * Actual expanded textual content of the default attribute value;
+ * normalized if appropriate in this mode.
+ * Note that all entities have been expanded: if a GE/PE was undefined,
+ * and no fatal errors were reported (non-validating mode), the
+ * references were just silently removed, and matching entries added
+ * to mUndeclaredEntity
+ */
+ private String mValue = null;
+
+ /**
+ * For now, let's only keep track of the first undeclared entity:
+ * can be extended if necessary.
+ */
+ private UndeclaredEntity mUndeclaredEntity = null;
+
+ /*
+ ////////////////////////////////////////////////////
+ // Life-cycle (creation, configuration)
+ ////////////////////////////////////////////////////
+ */
+
+ private DefaultAttrValue(int defValueType)
+ {
+ mDefValueType = defValueType;
+ }
+
+ public static DefaultAttrValue constructImplied() { return sImplied; }
+ public static DefaultAttrValue constructRequired() { return sRequired; }
+
+ public static DefaultAttrValue constructFixed() {
+ return new DefaultAttrValue(DEF_FIXED);
+ }
+
+ public static DefaultAttrValue constructOptional() {
+ return new DefaultAttrValue(DEF_DEFAULT);
+ }
+
+ public void setValue(String v) {
+ mValue = v;
+ }
+
+ public void addUndeclaredPE(String name, Location loc)
+ {
+ addUndeclaredEntity(name, loc, true);
+ }
+
+ public void addUndeclaredGE(String name, Location loc)
+ {
+ addUndeclaredEntity(name, loc, false);
+ }
+
+ public void reportUndeclared(ValidationContext ctxt, XMLValidator dtd)
+ throws XMLStreamException
+ {
+ mUndeclaredEntity.reportUndeclared(ctxt, dtd);
+ }
+
+ /*
+ ////////////////////////////////////////////////////
+ // Accessors:
+ ////////////////////////////////////////////////////
+ */
+
+ public boolean hasUndeclaredEntities() {
+ return (mUndeclaredEntity != null);
+ }
+
+ public String getValue() {
+ return mValue;
+ }
+
+ /**
+ * @return Expanded default value String, if there were no problems
+ * (no undeclared entities), or null to indicate there were problems.
+ * In latter case, caller is to figure out exact type of the problem
+ * and report this appropriately to the application.
+ */
+ public String getValueIfOk()
+ {
+ return (mUndeclaredEntity == null) ? mValue : null;
+ }
+
+ public boolean isRequired() {
+ return (this == sRequired);
+ }
+
+ public boolean isFixed() {
+ return (mDefValueType == DEF_FIXED);
+ }
+
+ public boolean hasDefaultValue() {
+ return (mDefValueType == DEF_DEFAULT)
+ || (mDefValueType == DEF_FIXED);
+ }
+
+ /**
+ * Method used by the element to figure out if attribute needs "special"
+ * checking; basically if it's required, and/or has a default value.
+ * In both cases missing the attribute has specific consequences, either
+ * exception or addition of a default value.
+ */
+ public boolean isSpecial() {
+ // Only non-special if #IMPLIED
+ return (this != sImplied);
+ }
+
+ /*
+ ////////////////////////////////////////////////////
+ // Internal methods
+ ////////////////////////////////////////////////////
+ */
+
+ private void addUndeclaredEntity(String name, Location loc, boolean isPe)
+ {
+ if (mUndeclaredEntity == null) {
+ mUndeclaredEntity = new UndeclaredEntity(name, loc, isPe);
+ }
+ }
+
+ /*
+ ////////////////////////////////////////////////////
+ // Helper class(es):
+ ////////////////////////////////////////////////////
+ */
+
+ final static class UndeclaredEntity
+ {
+ final String mName;
+ final boolean mIsPe;
+ final Location mLocation;
+
+ UndeclaredEntity(String name, Location loc, boolean isPe)
+ {
+ mName = name;
+ mIsPe = isPe;
+ mLocation = loc;
+ }
+
+ public void reportUndeclared(ValidationContext ctxt, XMLValidator dtd)
+ throws XMLStreamException
+ {
+ String msg = MessageFormat.format(ErrorConsts.ERR_DTD_UNDECLARED_ENTITY, new Object[] { (mIsPe ? "parsed" : "general"), mName });
+ XMLValidationProblem prob = new XMLValidationProblem
+ (mLocation, msg, XMLValidationProblem.SEVERITY_FATAL);
+ prob.setReporter(dtd);
+ ctxt.reportProblem(prob);
+ }
+ }
+}
diff -Nru libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/dtd/DFAState.java libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/dtd/DFAState.java
--- libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/dtd/DFAState.java 1970-01-01 00:00:00.000000000 +0000
+++ libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/dtd/DFAState.java 2018-03-31 01:33:28.000000000 +0000
@@ -0,0 +1,204 @@
+/* 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 com.ctc.wstx.dtd;
+
+import java.util.*;
+
+import com.ctc.wstx.util.PrefixedName;
+
+/**
+ * Class that represents a state in DFA used for validating complex
+ * DTD content models.
+ */
+public final class DFAState
+{
+ final int mIndex;
+ final boolean mAccepting;
+
+ BitSet mTokenSet;
+
+ HashMap mNext = new HashMap();
+
+ /*
+ ///////////////////////////////////////////////
+ // Life-cycle:
+ ///////////////////////////////////////////////
+ */
+
+ public DFAState(int index, BitSet tokenSet)
+ {
+ mIndex = index;
+ // If we have a transition to state 0, it is an accepting state...
+ mAccepting = tokenSet.get(0);
+ mTokenSet = tokenSet;
+ }
+
+ public static DFAState constructDFA(ContentSpec rootSpec)
+ {
+ // Let's first create the real model tree:
+ ModelNode modelRoot = rootSpec.rewrite();
+
+ /* Then we need to add the dummy end token, and concat node
+ * to contain it:
+ */
+ TokenModel eofToken = TokenModel.getNullToken();
+ ConcatModel dummyRoot = new ConcatModel(modelRoot, eofToken);
+
+ /* then need to allocate index numbers for tokens
+ * (which will also calculate nullability)
+ */
+ ArrayList tokens = new ArrayList();
+ tokens.add(eofToken); // has to be added first, explicitly
+ dummyRoot.indexTokens(tokens);
+
+ /* And then we can request calculation of follow pos; this will
+ * also recursively calculate first/last pos as needed:
+ */
+ int flen = tokens.size();
+ BitSet[] followPos = new BitSet[flen];
+ PrefixedName[] tokenNames = new PrefixedName[flen];
+ for (int i = 0; i < flen; ++i) {
+ followPos[i] = new BitSet(flen);
+ tokenNames[i] = tokens.get(i).getName();
+ }
+ dummyRoot.calcFollowPos(followPos);
+
+ /* And then we can calculate DFA stuff. First step is to get
+ * firstpos set for the root node, for creating the first
+ * state:
+ */
+ BitSet initial = new BitSet(flen);
+ dummyRoot.addFirstPos(initial);
+ DFAState firstState = new DFAState(0, initial);
+ ArrayList stateList = new ArrayList();
+ stateList.add(firstState);
+ HashMap stateMap = new HashMap();
+ stateMap.put(initial, firstState);
+
+ int i = 0;
+ while (i < stateList.size()) {
+ DFAState curr = stateList.get(i++);
+ curr.calcNext(tokenNames, followPos, stateList, stateMap);
+ }
+
+ // DEBUG:
+ /*
+ for (i = 0; i < stateList.size(); ++i) {
+ //System.out.println(stateList.get(i));
+ }
+ */
+
+ // And there we have it!
+ return firstState;
+ }
+
+ /*
+ ///////////////////////////////////////////////
+ // Public API, accessors:
+ ///////////////////////////////////////////////
+ */
+
+ public boolean isAcceptingState() {
+ return mAccepting;
+ }
+
+ public int getIndex() {
+ return mIndex;
+ }
+
+ public DFAState findNext(PrefixedName elemName) {
+ return mNext.get(elemName);
+ }
+
+ public TreeSet getNextNames() {
+ // Let's order them alphabetically
+ TreeSet names = new TreeSet();
+ for (PrefixedName n : mNext.keySet()) {
+ names.add(n);
+ }
+ return names;
+ }
+
+ public void calcNext(PrefixedName[] tokenNames, BitSet[] tokenFPs,
+ List stateList, Map stateMap)
+ {
+ /* Need to loop over all included tokens, and find groups
+ * of said tokens
+ */
+ int first = -1;
+
+ /* Need to clone; can not modify in place, since the BitSet
+ * is also used as the key...
+ */
+ BitSet tokenSet = (BitSet) mTokenSet.clone();
+ // No need to keep the reference to it, though:
+ mTokenSet = null;
+
+ while ((first = tokenSet.nextSetBit(first+1)) >= 0) {
+ PrefixedName tokenName = tokenNames[first];
+
+ /* Special case; the dummy end token has null as name;
+ * we can skip that one:
+ */
+ if (tokenName == null) {
+ continue;
+ }
+
+ BitSet nextGroup = (BitSet) tokenFPs[first].clone();
+ int second = first;
+
+ while ((second = tokenSet.nextSetBit(second+1)) > 0) {
+ if (tokenNames[second] == tokenName) {
+ // Let's clear it, too, so we won't match it again:
+ tokenSet.clear(second);
+ nextGroup.or(tokenFPs[second]);
+ }
+ }
+
+ // Ok; is it a new group?
+ DFAState next = stateMap.get(nextGroup);
+ if (next == null) { // yup!
+ next = new DFAState(stateList.size(), nextGroup);
+ stateList.add(next);
+ stateMap.put(nextGroup, next);
+ }
+ mNext.put(tokenName, next);
+ }
+ }
+
+ /*
+ ///////////////////////////////////////////////
+ // Other methods
+ ///////////////////////////////////////////////
+ */
+
+ @Override
+ public String toString()
+ {
+ StringBuilder sb = new StringBuilder();
+ sb.append("State #"+mIndex+":\n");
+ sb.append(" Accepting: "+mAccepting);
+ sb.append("\n Next states:\n");
+ for (Map.Entry en : mNext.entrySet()) {
+ sb.append(en.getKey());
+ sb.append(" -> ");
+ DFAState next = en.getValue();
+ sb.append(next.getIndex());
+ sb.append("\n");
+ }
+ return sb.toString();
+ }
+}
diff -Nru libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/dtd/DFAValidator.java libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/dtd/DFAValidator.java
--- libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/dtd/DFAValidator.java 1970-01-01 00:00:00.000000000 +0000
+++ libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/dtd/DFAValidator.java 2018-03-31 01:33:28.000000000 +0000
@@ -0,0 +1,80 @@
+/* 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 com.ctc.wstx.dtd;
+
+import java.util.*;
+
+import com.ctc.wstx.util.PrefixedName;
+import com.ctc.wstx.util.StringUtil;
+
+/**
+ * Validator class that is based on a DFA constructed from DTD content
+ * specification.
+ */
+public final class DFAValidator
+ extends StructValidator
+{
+ /**
+ * For root validator instance, the start state of DFA; for other
+ * instances, current state.
+ */
+ DFAState mState;
+
+ public DFAValidator(DFAState initialState) {
+ mState = initialState;
+ }
+
+ @Override
+ public StructValidator newInstance() {
+ return new DFAValidator(mState);
+ }
+
+ @Override
+ public String tryToValidate(PrefixedName elemName)
+ {
+ // Do we have a follow state with that key?
+ DFAState next = mState.findNext(elemName);
+
+ if (next == null) {
+ // Nope; let's show what we'd have expected instead...
+ TreeSet names = mState.getNextNames();
+ if (names.size() == 0) { // expected end tag?
+ return "Expected $END";
+ }
+
+ // Either end tag, or another tag?
+ if (mState.isAcceptingState()) {
+ return "Expected <"+StringUtil.concatEntries(names, ">, <", null)+"> or $END";
+ }
+ return "Expected <"+StringUtil.concatEntries(names,
+ ">, <", "> or <")+">";
+ }
+
+ mState = next;
+ return null;
+ }
+
+ @Override
+ public String fullyValid()
+ {
+ if (mState.isAcceptingState()) {
+ return null;
+ }
+ TreeSet names = mState.getNextNames();
+ return "Expected <"+StringUtil.concatEntries(names,
+ ">, <", "> or <")+">";
+ }
+}
diff -Nru libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/dtd/DTDAttribute.java libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/dtd/DTDAttribute.java
--- libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/dtd/DTDAttribute.java 1970-01-01 00:00:00.000000000 +0000
+++ libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/dtd/DTDAttribute.java 2018-03-31 01:33:28.000000000 +0000
@@ -0,0 +1,511 @@
+/* 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 com.ctc.wstx.dtd;
+
+import java.util.Map;
+
+import javax.xml.stream.XMLStreamException;
+
+import org.codehaus.stax2.validation.ValidationContext;
+import org.codehaus.stax2.validation.XMLValidator;
+
+import com.ctc.wstx.ent.EntityDecl;
+import com.ctc.wstx.io.WstxInputData;
+import com.ctc.wstx.sr.InputProblemReporter;
+import com.ctc.wstx.util.PrefixedName;
+import com.ctc.wstx.util.StringUtil;
+import com.ctc.wstx.util.WordResolver;
+
+/**
+ * Base class for objects that contain attribute definitions from DTD.
+ * Sub-classes exists for specific typed attributes (enumeration-valued,
+ * non-CDATA ones); base class itself is used for attributes of type
+ * CDATA.
+ */
+public abstract class DTDAttribute
+{
+ final static char CHAR_SPACE = (char) 0x0020;
+
+ /*
+ ///////////////////////////////////////////////////
+ // Type constants
+ ///////////////////////////////////////////////////
+ */
+
+ // // // Value types
+
+ public final static int TYPE_CDATA = 0; // default...
+ public final static int TYPE_ENUMERATED = 1;
+
+ public final static int TYPE_ID = 2;
+ public final static int TYPE_IDREF = 3;
+ public final static int TYPE_IDREFS = 4;
+
+ public final static int TYPE_ENTITY = 5;
+ public final static int TYPE_ENTITIES = 6;
+
+ public final static int TYPE_NOTATION = 7;
+ public final static int TYPE_NMTOKEN = 8;
+ public final static int TYPE_NMTOKENS = 9;
+
+ /**
+ * Array that has String constants matching above mentioned
+ * value types
+ */
+ final static String[] sTypes = new String[] {
+ "CDATA",
+ /* 05-Feb-2006, TSa: Hmmh. Apparently SAX specs indicate that
+ * enumerated type should be listed as "NMTOKEN"... but most
+ * SAX parsers use ENUMERATED, plus this way application can
+ * distinguish real NMTOKEN from enumerated type.
+ */
+ /* 26-Nov-2006, TSa: Either way, we can change type to SAX
+ * compatible within SAX classes, not here.
+ */
+ //"NMTOKEN"
+ "ENUMERATED",
+ "ID",
+ "IDREF",
+ "IDREFS",
+ "ENTITY",
+ "ENTITIES",
+ "NOTATION",
+ "NMTOKEN",
+ "NMTOKENS",
+ };
+
+ /*
+ ///////////////////////////////////////////////////
+ // Information about the attribute itself
+ ///////////////////////////////////////////////////
+ */
+
+ protected final PrefixedName mName;
+
+ /**
+ * Index number amongst "special" attributes (required ones, attributes
+ * that have default values), if attribute is one: -1 if not.
+ */
+ protected final int mSpecialIndex;
+
+ protected final DefaultAttrValue mDefValue;
+
+ protected final boolean mCfgNsAware;
+ protected final boolean mCfgXml11;
+
+ /*
+ ///////////////////////////////////////////////////
+ // Life-cycle
+ ///////////////////////////////////////////////////
+ */
+
+ public DTDAttribute(PrefixedName name, DefaultAttrValue defValue, int specIndex,
+ boolean nsAware, boolean xml11)
+ {
+ mName = name;
+ mDefValue = defValue;
+ mSpecialIndex = specIndex;
+ mCfgNsAware = nsAware;
+ mCfgXml11 = xml11;
+ }
+
+ public abstract DTDAttribute cloneWith(int specIndex);
+
+ /*
+ ///////////////////////////////////////////////////
+ // Public API, accessors
+ ///////////////////////////////////////////////////
+ */
+
+ public final PrefixedName getName() { return mName; }
+
+ @Override
+ public final String toString() {
+ return mName.toString();
+ }
+
+ public final String getDefaultValue(ValidationContext ctxt, XMLValidator dtd)
+ throws XMLStreamException
+ {
+ String val = mDefValue.getValueIfOk();
+ if (val == null) {
+ mDefValue.reportUndeclared(ctxt, dtd);
+ /* should never get here, but just to be safe, let's use
+ * the 'raw' value (one that does not have undeclared entities
+ * included, most likely)
+ */
+ val = mDefValue.getValue();
+ }
+ return val;
+ }
+
+ public final int getSpecialIndex() {
+ return mSpecialIndex;
+ }
+
+ public final boolean needsValidation() {
+ return (getValueType() != TYPE_CDATA);
+ }
+
+ public final boolean isFixed() {
+ return mDefValue.isFixed();
+ }
+
+ public final boolean isRequired() {
+ return mDefValue.isRequired();
+ }
+
+ /**
+ * Method used by the element to figure out if attribute needs "special"
+ * checking; basically if it's required, and/or has a default value.
+ * In both cases missing the attribute has specific consequences, either
+ * exception or addition of a default value.
+ */
+ public final boolean isSpecial() {
+ return mDefValue.isSpecial();
+ }
+
+ public final boolean hasDefaultValue() {
+ return mDefValue.hasDefaultValue();
+ }
+
+ /**
+ * Returns the value type of this attribute as an enumerated int
+ * to match type (CDATA, ...)
+ *
+ * Note:
+ */
+ public int getValueType() {
+ return TYPE_CDATA;
+ }
+
+ public String getValueTypeString()
+ {
+ return sTypes[getValueType()];
+ }
+
+ public boolean typeIsId() {
+ return false;
+ }
+
+ public boolean typeIsNotation() {
+ return false;
+ }
+
+ /*
+ ///////////////////////////////////////////////////
+ // Public API, validation
+ ///////////////////////////////////////////////////
+ */
+
+ public abstract String validate(DTDValidatorBase v, char[] cbuf, int start, int end, boolean normalize)
+ throws XMLStreamException;
+
+ /**
+ *
+ * Note: the default implementation is not optimized, as it does
+ * a potentially unnecessary copy of the contents. It is expected that
+ * this method is seldom called (Woodstox never directly calls it; it
+ * only gets called for chained validators when one validator normalizes
+ * the value, and then following validators are passed a String, not
+ * char array)
+ */
+ public String validate(DTDValidatorBase v, String value, boolean normalize)
+ throws XMLStreamException
+ {
+ int len = value.length();
+ /* Temporary buffer has to come from the validator itself, since
+ * attribute objects are stateless and shared...
+ */
+ char[] cbuf = v.getTempAttrValueBuffer(value.length());
+ if (len > 0) {
+ value.getChars(0, len, cbuf, 0);
+ }
+ return validate(v, cbuf, 0, len, normalize);
+ }
+
+ /**
+ * Method called by the {@link DTDValidator}
+ * to ask attribute to verify that the default it has (if any) is
+ * valid for such type.
+ */
+ public abstract void validateDefault(InputProblemReporter rep, boolean normalize)
+ throws XMLStreamException;
+
+ /**
+ * Method called when no validation is to be done, but value is still
+ * to be normalized as much as it can. What this usually means is that
+ * all regular space (parser earlier on converts other white space to
+ * spaces, except for specific character entities; and these special
+ * cases are NOT to be normalized).
+ *
+ * The only exception is that CDATA will not do any normalization. But
+ * for now, let's implement basic functionality that CDTA instance will
+ * override
+ *
+ * @param v Validator that invoked normalization
+ *
+ * @return Normalized value as a String, if any changes were done;
+ * null if input was normalized
+ */
+ public String normalize(DTDValidatorBase v, char[] cbuf, int start, int end)
+ {
+ return StringUtil.normalizeSpaces(cbuf, start, end);
+ }
+
+ /**
+ * Method called to do initial normalization of the default attribute
+ * value, without trying to verify its validity. Thus, it's
+ * called independent of whether we are fully validating the document.
+ */
+ public void normalizeDefault()
+ {
+ String val = mDefValue.getValue();
+ if (val.length() > 0) {
+ char[] cbuf = val.toCharArray();
+ String str = StringUtil.normalizeSpaces(cbuf, 0, cbuf.length);
+ if (str != null) {
+ mDefValue.setValue(str);
+ }
+ }
+ }
+
+ /*
+ ///////////////////////////////////////////////////
+ // Package methods, validation helper methods
+ ///////////////////////////////////////////////////
+ */
+
+ protected String validateDefaultName(InputProblemReporter rep, boolean normalize)
+ throws XMLStreamException
+ {
+ String origDefValue = mDefValue.getValue();
+ String defValue = origDefValue.trim();
+
+ if (defValue.length() == 0) {
+ reportValidationProblem(rep, "Invalid default value '"+defValue
+ +"'; empty String is not a valid name");
+ }
+
+ // Ok, needs to be a valid XML name:
+ int illegalIx = WstxInputData.findIllegalNameChar(defValue, mCfgNsAware, mCfgXml11);
+ if (illegalIx >= 0) {
+ if (illegalIx == 0) {
+ reportValidationProblem(rep, "Invalid default value '"+defValue+"'; character "
+ +WstxInputData.getCharDesc(defValue.charAt(0))
+ +") not valid first character of a name");
+ } else {
+ reportValidationProblem(rep, "Invalid default value '"+defValue+"'; character #"+illegalIx+" ("
+ +WstxInputData.getCharDesc(defValue.charAt(illegalIx))
+ +") not valid name character");
+ }
+ }
+
+ // Ok, cool it's ok...
+ return normalize ? defValue : origDefValue;
+ }
+
+ protected String validateDefaultNames(InputProblemReporter rep, boolean normalize)
+ throws XMLStreamException
+ {
+ String defValue = mDefValue.getValue().trim();
+ int len = defValue.length();
+
+ // Then code similar to actual value validation:
+ StringBuilder sb = null;
+ int count = 0;
+ int start = 0;
+
+ main_loop:
+ while (start < len) {
+ char c = defValue.charAt(start);
+
+ // Ok, any white space to skip?
+ while (true) {
+ if (!WstxInputData.isSpaceChar(c)) {
+ break;
+ }
+ if (++start >= len) {
+ break main_loop;
+ }
+ c = defValue.charAt(start);
+ }
+
+ // Then need to find the token itself:
+ int i = start+1;
+
+ for (; i < len; ++i) {
+ if (WstxInputData.isSpaceChar(defValue.charAt(i))) {
+ break;
+ }
+ }
+ String token = defValue.substring(start, i);
+ int illegalIx = WstxInputData.findIllegalNameChar(token, mCfgNsAware, mCfgXml11);
+ if (illegalIx >= 0) {
+ if (illegalIx == 0) {
+ reportValidationProblem(rep, "Invalid default value '"+defValue
+ +"'; character "
+ +WstxInputData.getCharDesc(defValue.charAt(start))
+ +") not valid first character of a name token");
+ } else {
+ reportValidationProblem(rep, "Invalid default value '"+defValue
+ +"'; character "
+ +WstxInputData.getCharDesc(c)
+ +") not a valid name character");
+ }
+ }
+ ++count;
+ if (normalize) {
+ if (sb == null) {
+ sb = new StringBuilder(i - start + 32);
+ } else {
+ sb.append(' ');
+ }
+ sb.append(token);
+ }
+ start = i+1;
+ }
+
+ if (count == 0) {
+ reportValidationProblem(rep, "Invalid default value '"+defValue
+ +"'; empty String is not a valid name value");
+ }
+
+ return normalize ? sb.toString() : defValue;
+ }
+
+ protected String validateDefaultNmToken(InputProblemReporter rep, boolean normalize)
+ throws XMLStreamException
+ {
+ String origDefValue = mDefValue.getValue();
+ String defValue = origDefValue.trim();
+
+ if (defValue.length() == 0) {
+ reportValidationProblem(rep, "Invalid default value '"+defValue+"'; empty String is not a valid NMTOKEN");
+ }
+ int illegalIx = WstxInputData.findIllegalNmtokenChar(defValue, mCfgNsAware, mCfgXml11);
+ if (illegalIx >= 0) {
+ reportValidationProblem(rep, "Invalid default value '"+defValue
+ +"'; character #"+illegalIx+" ("
+ +WstxInputData.getCharDesc(defValue.charAt(illegalIx))
+ +") not valid NMTOKEN character");
+ }
+ // Ok, cool it's ok...
+ return normalize ? defValue : origDefValue;
+ }
+
+ /**
+ * Method called by validation/normalization code for enumeration-valued
+ * attributes, to trim
+ * specified attribute value (full normalization not needed -- called
+ * for values that CAN NOT have spaces inside; such values can not
+ * be legal), and then check whether it is included
+ * in set of words (tokens) passed in. If actual value was included,
+ * will return the normalized word (as well as store shared String
+ * locally); otherwise will return null.
+ */
+ public String validateEnumValue(char[] cbuf, int start, int end,
+ boolean normalize,
+ WordResolver res)
+ {
+ /* Better NOT to build temporary Strings quite yet; can resolve
+ * matches via resolver more efficiently.
+ */
+ // Note: at this point, should only have real spaces...
+ if (normalize) {
+ while (start < end && cbuf[start] <= CHAR_SPACE) {
+ ++start;
+ }
+ while (--end > start && cbuf[end] <= CHAR_SPACE) {
+ ;
+ }
+ ++end; // so it'll point to the first char (or beyond end of buffer)
+ }
+
+ // Empty String is never legal for enums:
+ if (start >= end) {
+ return null;
+ }
+ return res.find(cbuf, start, end);
+ }
+
+ protected EntityDecl findEntityDecl(DTDValidatorBase v,
+ char[] ch, int start, int len /*, int hash*/)
+ throws XMLStreamException
+ {
+ Map entMap = v.getEntityMap();
+ /* !!! 13-Nov-2005, TSa: If this was to become a bottle-neck, we
+ * could use/share a symbol table. Or at least reuse Strings...
+ */
+ String id = new String(ch, start, len);
+ EntityDecl ent = entMap.get(id);
+
+ if (ent == null) {
+ reportValidationProblem(v, "Referenced entity '"+id+"' not defined");
+ } else if (ent.isParsed()) {
+ reportValidationProblem(v, "Referenced entity '"+id+"' is not an unparsed entity");
+ }
+ return ent;
+ }
+
+ /* Too bad this method can not be combined with previous segment --
+ * the reason is that DTDValidator does not implement
+ * InputProblemReporter...
+ */
+
+ protected void checkEntity(InputProblemReporter rep, String id, EntityDecl ent)
+ throws XMLStreamException
+ {
+ if (ent == null) {
+ rep.reportValidationProblem("Referenced entity '"+id+"' not defined");
+ } else if (ent.isParsed()) {
+ rep.reportValidationProblem("Referenced entity '"+id+"' is not an unparsed entity");
+ }
+ }
+
+ /*
+ ///////////////////////////////////////////////////
+ // Package methods, error reporting
+ ///////////////////////////////////////////////////
+ */
+
+ protected String reportInvalidChar(DTDValidatorBase v, char c, String msg)
+ throws XMLStreamException
+ {
+ reportValidationProblem(v, "Invalid character "+WstxInputData.getCharDesc(c)+": "+msg);
+ return null;
+ }
+
+ protected String reportValidationProblem(DTDValidatorBase v, String msg)
+ throws XMLStreamException
+ {
+ v.reportValidationProblem("Attribute '"+mName+"': "+msg);
+ return null;
+ }
+
+ /**
+ * Method called during parsing of DTD schema, to report a problem.
+ * Note that unlike during actual validation, we have no option of
+ * just gracefully listing problems and ignoring them; an exception
+ * is always thrown.
+ */
+ protected String reportValidationProblem(InputProblemReporter rep, String msg)
+ throws XMLStreamException
+ {
+ rep.reportValidationProblem("Attribute definition '"+mName+"': "+msg);
+ return null;
+ }
+}
diff -Nru libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/dtd/DTDCdataAttr.java libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/dtd/DTDCdataAttr.java
--- libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/dtd/DTDCdataAttr.java 1970-01-01 00:00:00.000000000 +0000
+++ libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/dtd/DTDCdataAttr.java 2018-03-31 01:33:28.000000000 +0000
@@ -0,0 +1,61 @@
+package com.ctc.wstx.dtd;
+
+import org.codehaus.stax2.validation.XMLValidationException;
+
+import com.ctc.wstx.sr.InputProblemReporter;
+import com.ctc.wstx.util.PrefixedName;
+
+/**
+ * Simple {@link DTDAttribute} sub-class used for plain vanilla CDATA
+ * valued attributes. Although base class implements most of the methods,
+ * it's better designwise to keep that base class abstract and have
+ * separate CDATA type as well.
+ */
+public final class DTDCdataAttr
+ extends DTDAttribute
+{
+ public DTDCdataAttr(PrefixedName name, DefaultAttrValue defValue, int specIndex,
+ boolean nsAware, boolean xml11)
+ {
+ super(name, defValue, specIndex, nsAware, xml11);
+ }
+
+ @Override
+ public DTDAttribute cloneWith(int specIndex) {
+ return new DTDCdataAttr(mName, mDefValue, specIndex, mCfgNsAware, mCfgXml11);
+ }
+
+ /*
+ ///////////////////////////////////////////////////
+ // Public API, validation
+ ///////////////////////////////////////////////////
+ */
+
+ @Override
+ public String validate(DTDValidatorBase v, char[] cbuf, int start, int end, boolean normalize)
+ throws XMLValidationException
+ {
+ // Nothing to do for pure CDATA attributes...
+ return null;
+ }
+
+ @Override
+ public void validateDefault(InputProblemReporter rep, boolean normalize)
+ throws javax.xml.stream.XMLStreamException
+ {
+ // Nothing to do for CDATA; all values are fine
+ }
+
+ @Override
+ public String normalize(DTDValidatorBase v, char[] cbuf, int start, int end)
+ {
+ // Nothing to do for pure CDATA attributes...
+ return null;
+ }
+
+ @Override
+ public void normalizeDefault()
+ {
+ // Nothing to do for pure CDATA attributes...
+ }
+}
diff -Nru libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/dtd/DTDElement.java libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/dtd/DTDElement.java
--- libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/dtd/DTDElement.java 1970-01-01 00:00:00.000000000 +0000
+++ libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/dtd/DTDElement.java 2018-03-31 01:33:28.000000000 +0000
@@ -0,0 +1,577 @@
+/* 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 com.ctc.wstx.dtd;
+
+import java.util.*;
+
+import javax.xml.stream.Location;
+import javax.xml.stream.XMLStreamException;
+
+import org.codehaus.stax2.validation.XMLValidator;
+
+import com.ctc.wstx.api.ReaderConfig;
+import com.ctc.wstx.cfg.ErrorConsts;
+import com.ctc.wstx.sr.InputProblemReporter;
+import com.ctc.wstx.util.ExceptionUtil;
+import com.ctc.wstx.util.PrefixedName;
+import com.ctc.wstx.util.WordResolver;
+
+/**
+ * Class that contains element definitions from DTD.
+ *
+ * Notes about thread-safety: this class is not thread-safe, since it does
+ * not have to be, in general case. That is, the only instances that can
+ * be shared are external subset instances, and those are used in read-only
+ * manner (with the exception of temporary arrays constructed on-demand).
+ */
+public final class DTDElement
+{
+
+ /*
+ ///////////////////////////////////////////////////
+ // Information about the element itself
+ ///////////////////////////////////////////////////
+ */
+
+ final PrefixedName mName;
+
+ /**
+ * Location of the (real) definition of the element; may be null for
+ * placeholder elements created to hold ATTLIST definitions
+ */
+ final Location mLocation;
+
+ /**
+ * Base validator object for validating content model of this element;
+ * may be null for some simple content models (ANY, EMPTY).
+ */
+ StructValidator mValidator;
+
+ int mAllowedContent;
+
+ /**
+ * True if the DTD was parsed (and is to be used) in namespace-aware
+ * mode.
+ * Affects (name) validation amongst other things.
+ */
+ final boolean mNsAware;
+
+ /**
+ * True if the DTD was parsed in xml1.1 compliant mode (referenced to
+ * from an xml 1.1 document).
+ * Affects (name) validation amongst other things.
+ */
+ final boolean mXml11;
+
+ /*
+ ///////////////////////////////////////////////////
+ // Attribute info
+ ///////////////////////////////////////////////////
+ */
+
+ HashMap mAttrMap = null;
+
+ /**
+ * Ordered list of attributes that have 'special' properties (attribute
+ * is required, has a default value [regular or fixed]); these attributes
+ * have to be specifically checked after actual values have been resolved.
+ */
+ ArrayList mSpecAttrList = null;
+
+ boolean mAnyFixed = false;
+
+ /**
+ * Flag set to true if there are any attributes that have either
+ * basic default value, or #FIXED default value.
+ */
+ boolean mAnyDefaults = false;
+
+ /**
+ * Flag that is set to true if there is at least one attribute that
+ * has type that requires normalization and/or validation; that is,
+ * is of some other type than CDATA.
+ */
+ boolean mValidateAttrs = false;
+
+ /**
+ * Id attribute instance, if one already declared for this element;
+ * can only have up to one such attribute per element.
+ */
+ DTDAttribute mIdAttr;
+
+ /**
+ * Notation attribute instance, if one already declared for this element;
+ * can only have up to one such attribute per element.
+ */
+ DTDAttribute mNotationAttr;
+
+ // // // !! If you add new attributes, make sure they get copied
+ // // // in #define() method !!
+
+ /*
+ ///////////////////////////////////////////////////
+ // Namespace declaration defaulting...
+ ///////////////////////////////////////////////////
+ */
+
+ /**
+ * Set of namespace declarations with default values, if any
+ * (regular ns pseudo-attr declarations are just ignored)
+ */
+ HashMap mNsDefaults = null;
+
+ /*
+ ///////////////////////////////////////////////////
+ // Life-cycle
+ ///////////////////////////////////////////////////
+ */
+
+ private DTDElement(Location loc, PrefixedName name,
+ StructValidator val, int allowedContent,
+ boolean nsAware, boolean xml11)
+ {
+ mName = name;
+ mLocation = loc;
+ mValidator = val;
+ mAllowedContent = allowedContent;
+ mNsAware = nsAware;
+ mXml11 = xml11;
+ }
+
+ /**
+ * Method called to create an actual element definition, matching
+ * an ELEMENT directive in a DTD subset.
+ */
+ public static DTDElement createDefined(ReaderConfig cfg, Location loc, PrefixedName name,
+ StructValidator val, int allowedContent)
+ {
+ if (allowedContent == XMLValidator.CONTENT_ALLOW_UNDEFINED) { // sanity check
+ ExceptionUtil.throwInternal("trying to use XMLValidator.CONTENT_ALLOW_UNDEFINED via createDefined()");
+ }
+ return new DTDElement(loc, name, val, allowedContent,
+ cfg.willSupportNamespaces(), cfg.isXml11());
+ }
+
+ /**
+ * Method called to create a "placeholder" element definition, needed to
+ * contain attribute definitions.
+ */
+ public static DTDElement createPlaceholder(ReaderConfig cfg, Location loc, PrefixedName name)
+ {
+ return new DTDElement(loc, name, null, XMLValidator.CONTENT_ALLOW_UNDEFINED,
+ cfg.willSupportNamespaces(), cfg.isXml11());
+ }
+
+ /**
+ * Method called on placeholder element, to create a real instance that
+ * has all attribute definitions placeholder had (it'll always have at
+ * least one -- otherwise no placeholder was needed).
+ */
+ public DTDElement define(Location loc, StructValidator val,
+ int allowedContent)
+ {
+ verifyUndefined();
+ if (allowedContent == XMLValidator.CONTENT_ALLOW_UNDEFINED) { // sanity check
+ ExceptionUtil.throwInternal("trying to use CONTENT_ALLOW_UNDEFINED via define()");
+ }
+
+ DTDElement elem = new DTDElement(loc, mName, val, allowedContent,
+ mNsAware, mXml11);
+
+ // Ok, need to copy state collected so far:
+ elem.mAttrMap = mAttrMap;
+ elem.mSpecAttrList = mSpecAttrList;
+ elem.mAnyFixed = mAnyFixed;
+ elem.mValidateAttrs = mValidateAttrs;
+ elem.mAnyDefaults = mAnyDefaults;
+ elem.mIdAttr = mIdAttr;
+ elem.mNotationAttr = mNotationAttr;
+ elem.mNsDefaults = mNsDefaults;
+
+ return elem;
+ }
+
+ /**
+ * Method called to "upgrade" a placeholder using a defined element,
+ * including adding attributes.
+ */
+ public void defineFrom(InputProblemReporter rep, DTDElement definedElem,
+ boolean fullyValidate)
+ throws XMLStreamException
+ {
+ if (fullyValidate) {
+ verifyUndefined();
+ }
+ mValidator = definedElem.mValidator;
+ mAllowedContent = definedElem.mAllowedContent;
+ mergeMissingAttributesFrom(rep, definedElem, fullyValidate);
+ }
+
+ private void verifyUndefined()
+ {
+ if (mAllowedContent != XMLValidator.CONTENT_ALLOW_UNDEFINED) { // sanity check
+ ExceptionUtil.throwInternal("redefining defined element spec");
+ }
+ }
+
+ /**
+ * Method called by DTD parser when it has read information about
+ * an attribute that belong to this element
+ *
+ * @return Newly created attribute Object if the attribute definition was
+ * added (hadn't been declared yet); null if it's a duplicate, in which
+ * case original definition sticks.
+ */
+ public DTDAttribute addAttribute(InputProblemReporter rep,
+ PrefixedName attrName, int valueType,
+ DefaultAttrValue defValue, WordResolver enumValues,
+ boolean fullyValidate)
+ throws XMLStreamException
+ {
+ HashMap m = mAttrMap;
+ if (m == null) {
+ mAttrMap = m = new HashMap();
+ }
+
+ List specList = defValue.isSpecial() ? getSpecialList() : null;
+
+ DTDAttribute attr;
+ int specIndex = (specList == null) ? -1 : specList.size();
+
+ switch (valueType) {
+ case DTDAttribute.TYPE_CDATA:
+ attr = new DTDCdataAttr(attrName, defValue, specIndex, mNsAware, mXml11);
+ break;
+
+ case DTDAttribute.TYPE_ENUMERATED:
+ attr = new DTDEnumAttr(attrName, defValue, specIndex, mNsAware, mXml11, enumValues);
+ break;
+
+ case DTDAttribute.TYPE_ID:
+ /* note: although ID attributes are not to have default value,
+ * this is 'only' a validity constraint, and in dtd-aware-but-
+ * not-validating mode it is apparently 'legal' to add default
+ * values. Bleech.
+ */
+ attr = new DTDIdAttr(attrName, defValue, specIndex, mNsAware, mXml11);
+ break;
+
+ case DTDAttribute.TYPE_IDREF:
+ attr = new DTDIdRefAttr(attrName, defValue, specIndex, mNsAware, mXml11);
+ break;
+
+ case DTDAttribute.TYPE_IDREFS:
+ attr = new DTDIdRefsAttr(attrName, defValue, specIndex, mNsAware, mXml11);
+ break;
+
+ case DTDAttribute.TYPE_ENTITY:
+ attr = new DTDEntityAttr(attrName, defValue, specIndex, mNsAware, mXml11);
+ break;
+
+ case DTDAttribute.TYPE_ENTITIES:
+ attr = new DTDEntitiesAttr(attrName, defValue, specIndex, mNsAware, mXml11);
+ break;
+
+ case DTDAttribute.TYPE_NOTATION:
+ attr = new DTDNotationAttr(attrName, defValue, specIndex, mNsAware, mXml11, enumValues);
+ break;
+
+ case DTDAttribute.TYPE_NMTOKEN:
+ attr = new DTDNmTokenAttr(attrName, defValue, specIndex, mNsAware, mXml11);
+ break;
+
+ case DTDAttribute.TYPE_NMTOKENS:
+ attr = new DTDNmTokensAttr(attrName, defValue, specIndex, mNsAware, mXml11);
+ break;
+
+ default:
+ // 18-Jan-2006, TSa: should never get here...
+ ExceptionUtil.throwGenericInternal();
+ attr = null; // unreachable, but compiler wants it
+ }
+
+ DTDAttribute old = doAddAttribute(m, rep, attr, specList, fullyValidate);
+ return (old == null) ? attr : null;
+ }
+
+ /**
+ * Method called to add a definition of a namespace-declaration
+ * pseudo-attribute with a default value.
+ *
+ * @param rep Reporter to use to report non-fatal problems
+ * @param fullyValidate Whether this is being invoked for actual DTD validation,
+ * or just the "typing non-validator"
+ *
+ * @return Attribute that acts as the placeholder, if the declaration
+ * was added; null to indicate it
+ * was a dup (there was an earlier declaration)
+ */
+ public DTDAttribute addNsDefault
+ (InputProblemReporter rep, PrefixedName attrName, int valueType,
+ DefaultAttrValue defValue, boolean fullyValidate)
+ throws XMLStreamException
+ {
+ /* Let's simplify handling a bit: although theoretically all
+ * combinations of value can be used, let's really only differentiate
+ * between CDATA and 'other' (for which let's use NMTOKEN)
+ */
+ DTDAttribute nsAttr;
+
+ switch (valueType) {
+ case DTDAttribute.TYPE_CDATA:
+ nsAttr = new DTDCdataAttr(attrName, defValue, -1, mNsAware, mXml11);
+ break;
+ default: // something else, default to NMTOKEN then
+ nsAttr = new DTDNmTokenAttr(attrName, defValue, -1, mNsAware, mXml11);
+ break;
+ }
+
+ // Ok. So which prefix are we to bind? Need to access by prefix...
+ String prefix = attrName.getPrefix();
+ if (prefix == null || prefix.length() == 0) { // defult NS -> ""
+ prefix = "";
+ } else { // non-default, use the local name
+ prefix = attrName.getLocalName();
+ }
+
+ if (mNsDefaults == null) {
+ mNsDefaults = new HashMap();
+ } else {
+ if (mNsDefaults.containsKey(prefix)) {
+ return null;
+ }
+ }
+ mNsDefaults.put(prefix, nsAttr);
+ return nsAttr;
+ }
+
+ public void mergeMissingAttributesFrom(InputProblemReporter rep, DTDElement other,
+ boolean fullyValidate)
+ throws XMLStreamException
+ {
+ Map otherMap = other.getAttributes();
+ HashMap m = mAttrMap;
+ if (m == null) {
+ mAttrMap = m = new HashMap();
+ }
+
+ //boolean anyAdded = false;
+
+ if (otherMap != null && otherMap.size() > 0) {
+ for (Map.Entry me : otherMap.entrySet()) {
+ PrefixedName key = me.getKey();
+ // Should only add if no such attribute exists...
+ if (!m.containsKey(key)) {
+ // can only use as is, if it's not a special attr
+ DTDAttribute newAttr = me.getValue();
+ List specList;
+ // otherwise need to clone
+ if (newAttr.isSpecial()) {
+ specList = getSpecialList();
+ newAttr = newAttr.cloneWith(specList.size());
+ } else {
+ specList = null;
+ }
+ doAddAttribute(m, rep, newAttr, specList, fullyValidate);
+ }
+ }
+ }
+
+ HashMap otherNs = other.mNsDefaults;
+ if (otherNs != null) {
+ if (mNsDefaults == null) {
+ mNsDefaults = new HashMap();
+ }
+ for (Map.Entry en : otherNs.entrySet()) {
+ String prefix = en.getKey();
+ // Should only add if no such attribute exists...
+ if (!mNsDefaults.containsKey(prefix)) {
+ mNsDefaults.put(prefix, en.getValue());
+ }
+ }
+ }
+ }
+
+ /**
+ * @return Earlier declaration of the attribute, if any; null if
+ * this was a new attribute
+ */
+ private DTDAttribute doAddAttribute(Map attrMap, InputProblemReporter rep,
+ DTDAttribute attr, List specList,
+ boolean fullyValidate)
+ throws XMLStreamException
+ {
+ PrefixedName attrName = attr.getName();
+
+ // Maybe we already have it? If so, need to ignore
+ DTDAttribute old = attrMap.get(attrName);
+ if (old != null) {
+ rep.reportProblem(null, ErrorConsts.WT_ATTR_DECL, ErrorConsts.W_DTD_DUP_ATTR,
+ attrName, mName);
+ return old;
+ }
+
+ switch (attr.getValueType()) {
+ case DTDAttribute.TYPE_ID:
+ // Only one such attribute per element (Specs, 1.0#3.3.1)
+ if (fullyValidate && mIdAttr != null) {
+ rep.throwParseError("Invalid id attribute \"{0}\" for element <{1}>: already had id attribute \""+mIdAttr.getName()+"\"", attrName, mName);
+ }
+ mIdAttr = attr;
+ break;
+
+ case DTDAttribute.TYPE_NOTATION:
+ // Only one such attribute per element (Specs, 1.0#3.3.1)
+ if (fullyValidate && mNotationAttr != null) {
+ rep.throwParseError("Invalid notation attribute '"+attrName+"' for element <"+mName+">: already had notation attribute '"+mNotationAttr.getName()+"'");
+ }
+ mNotationAttr = attr;
+ break;
+ }
+
+ attrMap.put(attrName, attr);
+ if (specList != null) {
+ specList.add(attr);
+ }
+ if (!mAnyFixed) {
+ mAnyFixed = attr.isFixed();
+ }
+ if (!mValidateAttrs) {
+ mValidateAttrs = attr.needsValidation();
+ }
+ if (!mAnyDefaults) {
+ mAnyDefaults = attr.hasDefaultValue();
+ }
+
+ return null;
+ }
+
+ /*
+ ///////////////////////////////////////////////////
+ // Public API, accessors:
+ ///////////////////////////////////////////////////
+ */
+
+ public PrefixedName getName() { return mName; }
+
+ @Override
+ public String toString() {
+ return mName.toString();
+ }
+
+ public String getDisplayName() {
+ return mName.toString();
+ }
+
+ public Location getLocation() { return mLocation; }
+
+ public boolean isDefined() {
+ return (mAllowedContent != XMLValidator.CONTENT_ALLOW_UNDEFINED);
+ }
+
+ /**
+ * @return Constant that identifies what kind of nodes are in general
+ * allowed inside this element.
+ */
+ public int getAllowedContent() {
+ return mAllowedContent;
+ }
+
+ /**
+ * Specialized accessor used by non-validating but typing 'validator':
+ * essentially, used to figure out whether #PCDATA is allowed or not;
+ * and based on that, return one of 2 allowable text values (only
+ * space, or anything). This is the relevant subset in non-validating
+ * modes, needed to properly type resulting character events.
+ */
+ public int getAllowedContentIfSpace()
+ {
+ int vld = mAllowedContent;
+ return (vld <= XMLValidator.CONTENT_ALLOW_WS) ?
+ XMLValidator.CONTENT_ALLOW_WS_NONSTRICT :
+ XMLValidator.CONTENT_ALLOW_ANY_TEXT;
+ }
+
+ public HashMap getAttributes() {
+ return mAttrMap;
+ }
+
+ public int getSpecialCount() {
+ return (mSpecAttrList == null) ? 0 : mSpecAttrList.size();
+ }
+
+ public List getSpecialAttrs() {
+ return mSpecAttrList;
+ }
+
+ /**
+ * @return True if at least one of the attributes has type other than
+ * CDATA; false if not
+ */
+ public boolean attrsNeedValidation() {
+ return mValidateAttrs;
+ }
+
+ public boolean hasFixedAttrs() {
+ return mAnyFixed;
+ }
+
+ public boolean hasAttrDefaultValues() {
+ return mAnyDefaults;
+ }
+
+ public DTDAttribute getIdAttribute() {
+ return mIdAttr;
+ }
+
+ public DTDAttribute getNotationAttribute() {
+ return mNotationAttr;
+ }
+
+ public boolean hasNsDefaults() {
+ return (mNsDefaults != null);
+ }
+
+ /*
+ ///////////////////////////////////////////////////
+ // Public API, factory methods:
+ ///////////////////////////////////////////////////
+ */
+
+ public StructValidator getValidator()
+ {
+ return (mValidator == null) ? null : mValidator.newInstance();
+ }
+
+ protected HashMap getNsDefaults() {
+ return mNsDefaults;
+ }
+
+ /*
+ ///////////////////////////////////////////////////
+ // Internal methods
+ ///////////////////////////////////////////////////
+ */
+
+ private List getSpecialList()
+ {
+ ArrayList l = mSpecAttrList;
+ if (l == null) {
+ mSpecAttrList = l = new ArrayList();
+ }
+ return l;
+ }
+}
diff -Nru libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/dtd/DTDEntitiesAttr.java libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/dtd/DTDEntitiesAttr.java
--- libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/dtd/DTDEntitiesAttr.java 1970-01-01 00:00:00.000000000 +0000
+++ libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/dtd/DTDEntitiesAttr.java 2018-03-31 01:33:28.000000000 +0000
@@ -0,0 +1,178 @@
+package com.ctc.wstx.dtd;
+
+import java.util.StringTokenizer;
+
+import javax.xml.stream.XMLStreamException;
+
+import com.ctc.wstx.ent.EntityDecl;
+import com.ctc.wstx.io.WstxInputData;
+import com.ctc.wstx.sr.InputProblemReporter;
+import com.ctc.wstx.util.PrefixedName;
+
+/**
+ * Specific attribute class for attributes that contain (unique)
+ * identifiers.
+ */
+public final class DTDEntitiesAttr
+ extends DTDAttribute
+{
+ /*
+ ///////////////////////////////////////////////////
+ // Life-cycle
+ ///////////////////////////////////////////////////
+ */
+
+ /**
+ * Main constructor. Note that id attributes can never have
+ * default values.
+ */
+ public DTDEntitiesAttr(PrefixedName name, DefaultAttrValue defValue, int specIndex,
+ boolean nsAware, boolean xml11)
+
+ {
+ super(name, defValue, specIndex, nsAware, xml11);
+ }
+
+ @Override
+ public DTDAttribute cloneWith(int specIndex) {
+ return new DTDEntitiesAttr(mName, mDefValue, specIndex, mCfgNsAware, mCfgXml11);
+ }
+
+ /*
+ ///////////////////////////////////////////////////
+ // Public API
+ ///////////////////////////////////////////////////
+ */
+
+ @Override
+ public int getValueType() {
+ return TYPE_ENTITIES;
+ }
+
+ /*
+ ///////////////////////////////////////////////////
+ // Public API, validation
+ ///////////////////////////////////////////////////
+ */
+
+ /**
+ * Method called by the {@link DTDValidatorBase}
+ * to let the attribute do necessary normalization and/or validation
+ * for the value.
+ *
+ */
+ @Override
+ public String validate(DTDValidatorBase v, char[] cbuf, int start, int end, boolean normalize)
+ throws XMLStreamException
+ {
+ /* Let's skip leading/trailing white space, even if we are not
+ * to normalize visible attribute value. This allows for better
+ * round-trip handling (no changes for physical value caller
+ * gets), but still allows succesful validation.
+ */
+ while (start < end && WstxInputData.isSpaceChar(cbuf[start])) {
+ ++start;
+ }
+
+ // Empty value?
+ if (start >= end) {
+ return reportValidationProblem(v, "Empty ENTITIES value");
+ }
+ --end; // so that it now points to the last char
+ while (end > start && WstxInputData.isSpaceChar(cbuf[end])) {
+ --end;
+ }
+
+ // Ok; now start points to first, last to last char (both inclusive)
+ String idStr = null;
+ StringBuilder sb = null;
+
+ while (start <= end) {
+ // Ok, need to check char validity, and also calc hash code:
+ char c = cbuf[start];
+ if (!WstxInputData.isNameStartChar(c, mCfgNsAware, mCfgXml11)) {
+ return reportInvalidChar(v, c, "not valid as the first ENTITIES character");
+ }
+ int i = start+1;
+ for (; i <= end; ++i) {
+ c = cbuf[i];
+ if (WstxInputData.isSpaceChar(c)) {
+ break;
+ }
+ if (!WstxInputData.isNameChar(c, mCfgNsAware, mCfgXml11)) {
+ return reportInvalidChar(v, c, "not valid as an ENTITIES character");
+ }
+ }
+
+ EntityDecl ent = findEntityDecl(v, cbuf, start, (i - start));
+ // only returns if entity was found...
+
+ // Can skip the trailing space char (if there was one)
+ start = i+1;
+
+ /* When normalizing, we can possibly share id String, or
+ * alternatively, compose normalized String if multiple
+ */
+ if (normalize) {
+ if (idStr == null) { // first idref
+ idStr = ent.getName();
+ } else {
+ if (sb == null) {
+ sb = new StringBuilder(idStr);
+ }
+ idStr = ent.getName();
+ sb.append(' ');
+ sb.append(idStr);
+ }
+ }
+
+ // Ok, any white space to skip?
+ while (start <= end && WstxInputData.isSpaceChar(cbuf[start])) {
+ ++start;
+ }
+ }
+
+ if (normalize) {
+ if (sb != null) {
+ idStr = sb.toString();
+ }
+ return idStr;
+ }
+
+ return null;
+ }
+
+ /**
+ * Method called by the validator object
+ * to ask attribute to verify that the default it has (if any) is
+ * valid for such type.
+ */
+ @Override
+ public void validateDefault(InputProblemReporter rep, boolean normalize)
+ throws XMLStreamException
+ {
+ String normStr = validateDefaultNames(rep, true);
+ if (normalize) {
+ mDefValue.setValue(normStr);
+ }
+
+ // Ok, but were they declared?
+
+ /* Performance really shouldn't be critical here (only called when
+ * parsing DTDs, which get cached) -- let's just
+ * tokenize using standard StringTokenizer
+ */
+ StringTokenizer st = new StringTokenizer(normStr);
+ /* !!! 03-Dec-2004, TSa: This is rather ugly -- need to know we
+ * actually really get a DTD reader, and DTD reader needs
+ * to expose a special method... but it gets things done.
+ */
+ MinimalDTDReader dtdr = (MinimalDTDReader) rep;
+ while (st.hasMoreTokens()) {
+ String str = st.nextToken();
+ EntityDecl ent = dtdr.findEntity(str);
+ // Needs to exists, and be an unparsed entity...
+ checkEntity(rep, normStr, ent);
+ }
+ }
+}
diff -Nru libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/dtd/DTDEntityAttr.java libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/dtd/DTDEntityAttr.java
--- libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/dtd/DTDEntityAttr.java 1970-01-01 00:00:00.000000000 +0000
+++ libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/dtd/DTDEntityAttr.java 2018-03-31 01:33:28.000000000 +0000
@@ -0,0 +1,118 @@
+package com.ctc.wstx.dtd;
+
+import javax.xml.stream.XMLStreamException;
+
+import com.ctc.wstx.ent.EntityDecl;
+import com.ctc.wstx.io.WstxInputData;
+import com.ctc.wstx.sr.InputProblemReporter;
+import com.ctc.wstx.util.PrefixedName;
+
+/**
+ * Specific attribute class for attributes that contain (unique)
+ * identifiers.
+ */
+public final class DTDEntityAttr
+ extends DTDAttribute
+{
+ /*
+ ///////////////////////////////////////////////////
+ // Life-cycle
+ ///////////////////////////////////////////////////
+ */
+
+ /**
+ * Main constructor. Note that id attributes can never have
+ * default values.
+ */
+ public DTDEntityAttr(PrefixedName name, DefaultAttrValue defValue, int specIndex,
+ boolean nsAware, boolean xml11)
+ {
+ super(name, defValue, specIndex, nsAware, xml11);
+ }
+
+ @Override
+ public DTDAttribute cloneWith(int specIndex) {
+ return new DTDEntityAttr(mName, mDefValue, specIndex, mCfgNsAware, mCfgXml11);
+ }
+
+ /*
+ ///////////////////////////////////////////////////
+ // Public API
+ ///////////////////////////////////////////////////
+ */
+
+ @Override
+ public int getValueType() {
+ return TYPE_ENTITY;
+ }
+
+ /*
+ ///////////////////////////////////////////////////
+ // Public API, validation
+ ///////////////////////////////////////////////////
+ */
+
+ /**
+ * Method called by the {@link DTDValidatorBase}
+ * to let the attribute do necessary normalization and/or validation
+ * for the value.
+ */
+ @Override
+ public String validate(DTDValidatorBase v, char[] cbuf, int start, int end, boolean normalize)
+ throws XMLStreamException
+ {
+ while (start < end && WstxInputData.isSpaceChar(cbuf[start])) {
+ ++start;
+ }
+
+ // Empty value?
+ if (start >= end) {
+ return reportValidationProblem(v, "Empty ENTITY value");
+ }
+ --end; // so that it now points to the last char
+ while (end > start && WstxInputData.isSpaceChar(cbuf[end])) {
+ --end;
+ }
+
+ // Ok, need to check char validity, and also calc hash code:
+ char c = cbuf[start];
+ if (!WstxInputData.isNameStartChar(c, mCfgNsAware, mCfgXml11) && c != ':') {
+ return reportInvalidChar(v, c, "not valid as the first ID character");
+ }
+ for (int i = start+1; i <= end; ++i) {
+ c = cbuf[i];
+ if (!WstxInputData.isNameChar(c, mCfgNsAware, mCfgXml11)) {
+ return reportInvalidChar(v, c, "not valid as an ID character");
+ }
+ }
+
+ EntityDecl ent = findEntityDecl(v, cbuf, start, (end - start + 1));
+ // only returns if it succeeded...
+
+ return normalize ? ent.getName() : null;
+ }
+
+ /**
+ * Method called by the validator object
+ * to ask attribute to verify that the default it has (if any) is
+ * valid for such type.
+ */
+ @Override
+ public void validateDefault(InputProblemReporter rep, boolean normalize)
+ throws XMLStreamException
+ {
+ String normStr = validateDefaultName(rep, normalize);
+ if (normalize) {
+ mDefValue.setValue(normStr);
+ }
+
+ // Ok, but was it declared?
+
+ /* 03-Dec-2004, TSa: This is rather ugly -- need to know we
+ * actually really get a DTD reader, and DTD reader needs
+ * to expose a special method... but it gets things done.
+ */
+ EntityDecl ent = ((MinimalDTDReader) rep).findEntity(normStr);
+ checkEntity(rep, normStr, ent);
+ }
+}
diff -Nru libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/dtd/DTDEnumAttr.java libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/dtd/DTDEnumAttr.java
--- libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/dtd/DTDEnumAttr.java 1970-01-01 00:00:00.000000000 +0000
+++ libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/dtd/DTDEnumAttr.java 2018-03-31 01:33:28.000000000 +0000
@@ -0,0 +1,97 @@
+package com.ctc.wstx.dtd;
+
+import javax.xml.stream.XMLStreamException;
+
+import com.ctc.wstx.sr.InputProblemReporter;
+import com.ctc.wstx.util.PrefixedName;
+import com.ctc.wstx.util.WordResolver;
+
+/**
+ * Specific attribute class for attributes that have enumerated values.
+ */
+public final class DTDEnumAttr
+ extends DTDAttribute
+{
+ final WordResolver mEnumValues;
+
+ /*
+ ///////////////////////////////////////////////////
+ // Life-cycle
+ ///////////////////////////////////////////////////
+ */
+
+ public DTDEnumAttr(PrefixedName name, DefaultAttrValue defValue,
+ int specIndex, boolean nsAware, boolean xml11,
+ WordResolver enumValues)
+ {
+ super(name, defValue, specIndex, nsAware, xml11);
+ mEnumValues = enumValues;
+ }
+
+ @Override
+ public DTDAttribute cloneWith(int specIndex)
+ {
+ return new DTDEnumAttr(mName, mDefValue, specIndex, mCfgNsAware,
+ mCfgXml11, mEnumValues);
+ }
+
+ /*
+ ///////////////////////////////////////////////////
+ // Public API
+ ///////////////////////////////////////////////////
+ */
+
+ @Override
+ public int getValueType() {
+ return TYPE_ENUMERATED;
+ }
+
+ /*
+ ///////////////////////////////////////////////////
+ // Public API, validation
+ ///////////////////////////////////////////////////
+ */
+
+ /**
+ * Method called by the validator
+ * to let the attribute do necessary normalization and/or validation
+ * for the value.
+ */
+ @Override
+ public String validate(DTDValidatorBase v, char[] cbuf, int start, int end, boolean normalize)
+ throws XMLStreamException
+ {
+ String ok = validateEnumValue(cbuf, start, end, normalize, mEnumValues);
+ if (ok == null) {
+ String val = new String(cbuf, start, (end-start));
+ return reportValidationProblem(v, "Invalid enumerated value '"+val+"': has to be one of ("
+ +mEnumValues+")");
+ }
+ return ok;
+ }
+
+ /**
+ * Method called by the validator
+ * to ask attribute to verify that the default it has (if any) is
+ * valid for such type.
+ */
+ @Override
+ public void validateDefault(InputProblemReporter rep, boolean normalize)
+ throws XMLStreamException
+ {
+ String def = validateDefaultNmToken(rep, normalize);
+
+ // And then that it's one of listed values:
+ String shared = mEnumValues.find(def);
+ if (shared == null) {
+ reportValidationProblem(rep, "Invalid default value '"+def+"': has to be one of ("
+ +mEnumValues+")");
+ return;
+ }
+
+ // Ok, cool it's ok...
+ if (normalize) {
+ mDefValue.setValue(shared);
+ }
+ }
+}
diff -Nru libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/dtd/DTDEventListener.java libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/dtd/DTDEventListener.java
--- libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/dtd/DTDEventListener.java 1970-01-01 00:00:00.000000000 +0000
+++ libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/dtd/DTDEventListener.java 2018-03-31 01:33:28.000000000 +0000
@@ -0,0 +1,51 @@
+/* Woodstox XML processor
+ *
+ * Copyright (c) 2004- 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 com.ctc.wstx.dtd;
+
+import java.net.URL;
+
+import javax.xml.stream.XMLStreamException;
+
+public interface DTDEventListener
+{
+ // Configuration
+
+ /**
+ * @return True, if there is a listener interested in getting comment
+ * events within DTD subset (since that's optional)
+ */
+ public boolean dtdReportComments();
+
+ // Basic content events
+
+ public void dtdProcessingInstruction(String target, String data);
+ public void dtdComment(char[] data, int offset, int len);
+ public void dtdSkippedEntity(String name);
+
+ // DTD declarations that must be exposed
+ public void dtdNotationDecl(String name, String publicId, String systemId, URL baseURL)
+ throws XMLStreamException;
+
+ public void dtdUnparsedEntityDecl(String name, String publicId, String systemId, String notationName, URL baseURL)
+ throws XMLStreamException;
+
+ // DTD declarations that can be exposed
+
+ public void attributeDecl(String eName, String aName, String type, String mode, String value);
+ public void dtdElementDecl(String name, String model);
+ public void dtdExternalEntityDecl(String name, String publicId, String systemId);
+ public void dtdInternalEntityDecl(String name, String value);
+}
diff -Nru libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/dtd/DTDIdAttr.java libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/dtd/DTDIdAttr.java
--- libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/dtd/DTDIdAttr.java 1970-01-01 00:00:00.000000000 +0000
+++ libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/dtd/DTDIdAttr.java 2018-03-31 01:33:28.000000000 +0000
@@ -0,0 +1,136 @@
+package com.ctc.wstx.dtd;
+
+import javax.xml.stream.Location;
+import javax.xml.stream.XMLStreamException;
+
+import com.ctc.wstx.cfg.ErrorConsts;
+import com.ctc.wstx.io.WstxInputData;
+import com.ctc.wstx.sr.InputProblemReporter;
+import com.ctc.wstx.util.ElementId;
+import com.ctc.wstx.util.ElementIdMap;
+import com.ctc.wstx.util.PrefixedName;
+
+/**
+ * Specific attribute class for attributes that contain (unique)
+ * identifiers.
+ */
+public final class DTDIdAttr
+ extends DTDAttribute
+{
+ /*
+ ///////////////////////////////////////////////////
+ // Life-cycle
+ ///////////////////////////////////////////////////
+ */
+
+ /**
+ * Main constructor. Note that id attributes can never have
+ * default values.
+ *
+ * note: although ID attributes are not to have default value,
+ * this is 'only' a validity constraint, and in dtd-aware-but-
+ * not-validating mode it is apparently 'legal' to add default
+ * values.
+ */
+ public DTDIdAttr(PrefixedName name, DefaultAttrValue defValue, int specIndex,
+ boolean nsAware, boolean xml11)
+ {
+ super(name, defValue, specIndex, nsAware, xml11);
+ }
+
+ @Override
+ public DTDAttribute cloneWith(int specIndex) {
+ return new DTDIdAttr(mName, mDefValue, specIndex, mCfgNsAware, mCfgXml11);
+ }
+
+ /*
+ ///////////////////////////////////////////////////
+ // Public API
+ ///////////////////////////////////////////////////
+ */
+
+ @Override
+ public int getValueType() {
+ return TYPE_ID;
+ }
+
+ @Override
+ public boolean typeIsId() {
+ return true;
+ }
+
+ /*
+ ///////////////////////////////////////////////////
+ // Public API, validation
+ ///////////////////////////////////////////////////
+ */
+
+ /**
+ * Method called by the validator
+ * to let the attribute do necessary normalization and/or validation
+ * for the value.
+ */
+ @SuppressWarnings("cast")
+ @Override
+ public String validate(DTDValidatorBase v, char[] cbuf, int start, int end, boolean normalize)
+ throws XMLStreamException
+ {
+ // Let's trim leading white space first...
+ while (start < end && WstxInputData.isSpaceChar(cbuf[start])) {
+ ++start;
+ }
+
+ // No id?
+ if (start >= end) {
+ return reportValidationProblem(v, "Empty ID value");
+ }
+ --end; // so that it now points to the last char
+ while (end > start && WstxInputData.isSpaceChar(cbuf[end])) {
+ --end;
+ }
+
+ // Ok, need to check char validity, and also calc hash code:
+ char c = cbuf[start];
+ if (!WstxInputData.isNameStartChar(c, mCfgNsAware, mCfgXml11)) {
+ return reportInvalidChar(v, c, "not valid as the first ID character");
+ }
+ int hash = (int) c;
+ for (int i = start+1; i <= end; ++i) {
+ c = cbuf[i];
+ if (!WstxInputData.isNameChar(c, mCfgNsAware, mCfgXml11)) {
+ return reportInvalidChar(v, c, "not valid as an ID character");
+ }
+ hash = (hash * 31) + (int) c;
+ }
+
+ // Either way, we do need to validate characters, and calculate hash
+ ElementIdMap m = v.getIdMap();
+ PrefixedName elemName = v.getElemName();
+ Location loc = v.getLocation();
+ ElementId id = m.addDefined(cbuf, start, (end - start + 1), hash,
+ loc, elemName, mName);
+
+ // We can detect dups by checking if Location is the one we passed:
+ if (id.getLocation() != loc) {
+ return reportValidationProblem(v, "Duplicate id '"+id.getId()+"', first declared at "
+ +id.getLocation());
+ }
+
+ if (normalize) {
+ return id.getId();
+ }
+ return null;
+ }
+
+ /**
+ * Method called by the validator
+ * to ask attribute to verify that the default it has (if any) is
+ * valid for such type.
+ */
+ @Override
+ public void validateDefault(InputProblemReporter rep, boolean normalize)
+ {
+ // Should never get called
+ throw new IllegalStateException(ErrorConsts.ERR_INTERNAL);
+ }
+}
diff -Nru libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/dtd/DTDId.java libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/dtd/DTDId.java
--- libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/dtd/DTDId.java 1970-01-01 00:00:00.000000000 +0000
+++ libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/dtd/DTDId.java 2018-03-31 01:33:28.000000000 +0000
@@ -0,0 +1,142 @@
+/* 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 com.ctc.wstx.dtd;
+
+import java.net.URI;
+
+/**
+ * Simple key object class, used for accessing (external) DTDs when stored for
+ * caching. Main idea is that the primary id of a DTD (public or system id;
+ * latter normalized if possible)
+ * has to match, as well as couple of on/off settings for parsing (namespace
+ * support, text normalization).
+ * Latter restriction is needed since although DTDs do not deal
+ * with (or understand) namespaces, some parsing is done to be able to validate
+ * namespace aware/non-aware documents, and handling differs between the two.
+ * As to primary key part, public id is used if one was defined; if so,
+ * comparison is String equality. If not, then system id is compared: system
+ * id has to be expressed as URL if so.
+ */
+public final class DTDId
+{
+ protected final String mPublicId;
+
+ protected final URI mSystemId;
+
+ protected final int mConfigFlags;
+
+ protected final boolean mXml11;
+
+ protected int mHashCode = 0;
+
+ /*
+ ///////////////////////////////////////////////////////////////////////
+ // Life-cycle:
+ ///////////////////////////////////////////////////////////////////////
+ */
+
+ private DTDId(String publicId, URI systemId, int configFlags, boolean xml11)
+ {
+ mPublicId = publicId;
+ mSystemId = systemId;
+ mConfigFlags = configFlags;
+ mXml11 = xml11;
+ }
+
+ public static DTDId constructFromPublicId(String publicId, int configFlags,
+ boolean xml11)
+ {
+ if (publicId == null || publicId.length() == 0) {
+ throw new IllegalArgumentException("Empty/null public id.");
+ }
+ return new DTDId(publicId, null, configFlags, xml11);
+ }
+
+ public static DTDId constructFromSystemId(URI systemId, int configFlags,
+ boolean xml11)
+ {
+ if (systemId == null) {
+ throw new IllegalArgumentException("Null system id.");
+ }
+ return new DTDId(null, systemId, configFlags, xml11);
+ }
+
+ public static DTDId construct(String publicId, URI systemId, int configFlags, boolean xml11)
+ {
+ if (publicId != null && publicId.length() > 0) {
+ return new DTDId(publicId, null, configFlags, xml11);
+ }
+ if (systemId == null) {
+ throw new IllegalArgumentException("Illegal arguments; both public and system id null/empty.");
+ }
+ return new DTDId(null, systemId, configFlags, xml11);
+ }
+
+ /*
+ ///////////////////////////////////////////////////////////////////////
+ // Overridden standard methods
+ ///////////////////////////////////////////////////////////////////////
+ */
+
+ @Override
+ public int hashCode() {
+ int hash = mHashCode;
+ if (hash == 0) {
+ hash = mConfigFlags;
+ if (mPublicId != null) {
+ hash ^= mPublicId.hashCode();
+ } else {
+ hash ^= mSystemId.hashCode();
+ }
+ if (mXml11) {
+ hash ^= 1;
+ }
+ mHashCode = hash;
+ }
+ return hash;
+ }
+
+ @Override
+ public String toString() {
+ StringBuffer sb = new StringBuffer(60);
+ sb.append("Public-id: ");
+ sb.append(mPublicId);
+ sb.append(", system-id: ");
+ sb.append(mSystemId);
+ sb.append(" [config flags: 0x");
+ sb.append(Integer.toHexString(mConfigFlags));
+ sb.append("], xml11: ");
+ sb.append(mXml11);
+ return sb.toString();
+ }
+
+ @Override
+ public boolean equals(Object o)
+ {
+ if (o == this) return true;
+ if (o == null || o.getClass() != getClass()) return false;
+ DTDId other = (DTDId) o;
+ if (other.mConfigFlags != mConfigFlags
+ || other.mXml11 != mXml11) {
+ return false;
+ }
+ if (mPublicId != null) {
+ String op = other.mPublicId;
+ return (op != null) && op.equals(mPublicId);
+ }
+ return mSystemId.equals(other.mSystemId);
+ }
+}
diff -Nru libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/dtd/DTDIdRefAttr.java libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/dtd/DTDIdRefAttr.java
--- libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/dtd/DTDIdRefAttr.java 1970-01-01 00:00:00.000000000 +0000
+++ libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/dtd/DTDIdRefAttr.java 2018-03-31 01:33:28.000000000 +0000
@@ -0,0 +1,120 @@
+package com.ctc.wstx.dtd;
+
+import javax.xml.stream.Location;
+import javax.xml.stream.XMLStreamException;
+
+import com.ctc.wstx.io.WstxInputData;
+import com.ctc.wstx.sr.InputProblemReporter;
+import com.ctc.wstx.util.ElementId;
+import com.ctc.wstx.util.ElementIdMap;
+import com.ctc.wstx.util.PrefixedName;
+
+/**
+ * Attribute class for attributes that contain references
+ * to elements that have matching identifier specified.
+ */
+public final class DTDIdRefAttr
+ extends DTDAttribute
+{
+ /*
+ ///////////////////////////////////////////////////
+ // Life-cycle
+ ///////////////////////////////////////////////////
+ */
+
+ /**
+ * Main constructor.
+ */
+ public DTDIdRefAttr(PrefixedName name, DefaultAttrValue defValue, int specIndex,
+ boolean nsAware, boolean xml11)
+ {
+ super(name, defValue, specIndex, nsAware, xml11);
+ }
+
+ @Override
+ public DTDAttribute cloneWith(int specIndex) {
+ return new DTDIdRefAttr(mName, mDefValue, specIndex, mCfgNsAware, mCfgXml11);
+ }
+
+ /*
+ ///////////////////////////////////////////////////
+ // Public API
+ ///////////////////////////////////////////////////
+ */
+
+ @Override
+ public int getValueType() {
+ return TYPE_IDREF;
+ }
+
+ /*
+ ///////////////////////////////////////////////////
+ // Public API, validation
+ ///////////////////////////////////////////////////
+ */
+
+ /**
+ * Method called by the validator
+ * to let the attribute do necessary normalization and/or validation
+ * for the value.
+ */
+ @SuppressWarnings("cast")
+ @Override
+ public String validate(DTDValidatorBase v, char[] cbuf, int start, int end, boolean normalize)
+ throws XMLStreamException
+ {
+ /* Let's skip leading/trailing white space, even if we are not
+ * to normalize visible attribute value. This allows for better
+ * round-trip handling, but still allow validation.
+ */
+ while (start < end && WstxInputData.isSpaceChar(cbuf[start])) {
+ ++start;
+ }
+
+ if (start >= end) { // empty (all white space) value?
+ return reportValidationProblem(v, "Empty IDREF value");
+ }
+
+ --end; // so that it now points to the last char
+ while (end > start && WstxInputData.isSpaceChar(cbuf[end])) {
+ --end;
+ }
+
+ // Ok, need to check char validity, and also calc hash code:
+ char c = cbuf[start];
+ if (!WstxInputData.isNameStartChar(c, mCfgNsAware, mCfgXml11)) {
+ return reportInvalidChar(v, c, "not valid as the first IDREF character");
+ }
+ int hash = (int) c;
+ for (int i = start+1; i <= end; ++i) {
+ c = cbuf[i];
+ if (!WstxInputData.isNameChar(c, mCfgNsAware, mCfgXml11)) {
+ return reportInvalidChar(v, c, "not valid as an IDREF character");
+ }
+ hash = (hash * 31) + (int) c;
+ }
+
+ // Ok, let's check and update id ref list...
+ ElementIdMap m = v.getIdMap();
+ Location loc = v.getLocation();
+ ElementId id = m.addReferenced(cbuf, start, (end - start + 1), hash,
+ loc, v.getElemName(), mName);
+ // and that's all; no more checks needed here
+ return normalize ? id.getId() : null;
+ }
+
+ /**
+ * Method called by the validator
+ * to ask attribute to verify that the default it has (if any) is
+ * valid for such type.
+ */
+ @Override
+ public void validateDefault(InputProblemReporter rep, boolean normalize)
+ throws XMLStreamException
+ {
+ String def = validateDefaultName(rep, normalize);
+ if (normalize) {
+ mDefValue.setValue(def);
+ }
+ }
+}
diff -Nru libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/dtd/DTDIdRefsAttr.java libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/dtd/DTDIdRefsAttr.java
--- libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/dtd/DTDIdRefsAttr.java 1970-01-01 00:00:00.000000000 +0000
+++ libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/dtd/DTDIdRefsAttr.java 2018-03-31 01:33:28.000000000 +0000
@@ -0,0 +1,162 @@
+package com.ctc.wstx.dtd;
+
+import javax.xml.stream.Location;
+import javax.xml.stream.XMLStreamException;
+
+import com.ctc.wstx.io.WstxInputData;
+import com.ctc.wstx.sr.InputProblemReporter;
+import com.ctc.wstx.util.ElementId;
+import com.ctc.wstx.util.ElementIdMap;
+import com.ctc.wstx.util.PrefixedName;
+
+/**
+ * Attribute class for attributes that contain multiple references
+ * to elements that have matching identifier specified.
+ */
+public final class DTDIdRefsAttr
+ extends DTDAttribute
+{
+ /*
+ ///////////////////////////////////////////////////
+ // Life-cycle
+ ///////////////////////////////////////////////////
+ */
+
+ /**
+ * Main constructor.
+ */
+ public DTDIdRefsAttr(PrefixedName name, DefaultAttrValue defValue, int specIndex,
+ boolean nsAware, boolean xml11)
+ {
+ super(name, defValue, specIndex, nsAware, xml11);
+ }
+
+ @Override
+ public DTDAttribute cloneWith(int specIndex) {
+ return new DTDIdRefsAttr(mName, mDefValue, specIndex, mCfgNsAware, mCfgXml11);
+ }
+
+ /*
+ ///////////////////////////////////////////////////
+ // Public API
+ ///////////////////////////////////////////////////
+ */
+
+ @Override
+ public int getValueType() {
+ return TYPE_IDREFS;
+ }
+
+ /*
+ ///////////////////////////////////////////////////
+ // Public API, validation
+ ///////////////////////////////////////////////////
+ */
+
+ @SuppressWarnings("cast")
+ @Override
+ public String validate(DTDValidatorBase v, char[] cbuf, int start, int end, boolean normalize)
+ throws XMLStreamException
+ {
+ /* Let's skip leading/trailing white space, even if we are not
+ * to normalize visible attribute value. This allows for better
+ * round-trip handling (no changes for physical value caller
+ * gets), but still allows succesful validation.
+ */
+ while (start < end && WstxInputData.isSpaceChar(cbuf[start])) {
+ ++start;
+ }
+
+ // No id?
+ if (start >= end) {
+ return reportValidationProblem(v, "Empty IDREFS value");
+ }
+
+ --end; // so that it now points to the last char
+ // We now the first char is not a space by now...
+ while (end > start && WstxInputData.isSpaceChar(cbuf[end])) {
+ --end;
+ }
+
+ // Ok; now start points to first, end to last char (both inclusive)
+ ElementIdMap m = v.getIdMap();
+ Location loc = v.getLocation();
+
+ String idStr = null;
+ StringBuilder sb = null;
+ while (start <= end) {
+ // Ok, need to check char validity, and also calc hash code:
+ char c = cbuf[start];
+ if (!WstxInputData.isNameStartChar(c, mCfgNsAware, mCfgXml11)) {
+ return reportInvalidChar(v, c, "not valid as the first IDREFS character");
+ }
+ int hash = (int) c;
+ int i = start+1;
+ for (; i <= end; ++i) {
+ c = cbuf[i];
+ if (WstxInputData.isSpaceChar(c)) {
+ break;
+ }
+ if (!WstxInputData.isNameChar(c, mCfgNsAware, mCfgXml11)) {
+ return reportInvalidChar(v, c, "not valid as an IDREFS character");
+ }
+ hash = (hash * 31) + (int) c;
+ }
+
+ // Ok, got the next id ref...
+ ElementId id = m.addReferenced(cbuf, start, i - start, hash,
+ loc, v.getElemName(), mName);
+
+ // Can skip the trailing space char (if there was one)
+ start = i+1;
+
+ /* When normalizing, we can possibly share id String, or
+ * alternatively, compose normalized String if multiple
+ */
+ if (normalize) {
+ if (idStr == null) { // first idref
+ idStr = id.getId();
+ } else {
+ if (sb == null) {
+ sb = new StringBuilder(idStr);
+ }
+ idStr = id.getId();
+ sb.append(' ');
+ sb.append(idStr);
+ }
+ }
+
+ // Ok, any white space to skip?
+ while (start <= end && WstxInputData.isSpaceChar(cbuf[start])) {
+ ++start;
+ }
+ }
+
+ if (normalize) {
+ if (sb != null) {
+ idStr = sb.toString();
+ }
+ return idStr;
+ }
+
+ return null;
+ }
+
+ /**
+ * Method called by the validator
+ * to ask attribute to verify that the default it has (if any) is
+ * valid for such type.
+ *
+ * It's unlikely there will be default values... but just in case,
+ * let's implement it properly.
+ */
+ @Override
+ public void validateDefault(InputProblemReporter rep, boolean normalize)
+ throws XMLStreamException
+ {
+ String def = validateDefaultNames(rep, normalize);
+ if (normalize) {
+ mDefValue.setValue(def);
+ }
+ }
+}
diff -Nru libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/dtd/DTDNmTokenAttr.java libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/dtd/DTDNmTokenAttr.java
--- libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/dtd/DTDNmTokenAttr.java 1970-01-01 00:00:00.000000000 +0000
+++ libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/dtd/DTDNmTokenAttr.java 2018-03-31 01:33:28.000000000 +0000
@@ -0,0 +1,112 @@
+package com.ctc.wstx.dtd;
+
+import javax.xml.stream.XMLStreamException;
+
+import com.ctc.wstx.io.WstxInputData;
+import com.ctc.wstx.sr.InputProblemReporter;
+import com.ctc.wstx.util.PrefixedName;
+
+/**
+ * Specific attribute class for attributes that contain (unique)
+ * identifiers.
+ */
+public final class DTDNmTokenAttr
+ extends DTDAttribute
+{
+ /*
+ ///////////////////////////////////////////////////
+ // Life-cycle
+ ///////////////////////////////////////////////////
+ */
+
+ /**
+ * Main constructor.
+ */
+ public DTDNmTokenAttr(PrefixedName name, DefaultAttrValue defValue, int specIndex,
+ boolean nsAware, boolean xml11)
+ {
+ super(name, defValue, specIndex, nsAware, xml11);
+ }
+
+ @Override
+ public DTDAttribute cloneWith(int specIndex)
+ {
+ return new DTDNmTokenAttr(mName, mDefValue, specIndex, mCfgNsAware, mCfgXml11);
+ }
+
+ /*
+ ///////////////////////////////////////////////////
+ // Public API
+ ///////////////////////////////////////////////////
+ */
+
+ @Override
+ public int getValueType() {
+ return TYPE_NMTOKEN;
+ }
+
+ /*
+ ///////////////////////////////////////////////////
+ // Public API, validation
+ ///////////////////////////////////////////////////
+ */
+
+ /**
+ * Method called by the validator
+ * to let the attribute do necessary normalization and/or validation
+ * for the value.
+ */
+ @Override
+ public String validate(DTDValidatorBase v, char[] cbuf, int start, int end, boolean normalize)
+ throws XMLStreamException
+ {
+ int origLen = end-start;
+
+ // Let's trim leading white space first...
+ while (start < end && WstxInputData.isSpaceChar(cbuf[start])) {
+ ++start;
+ }
+
+ // Empty value?
+ if (start >= end) {
+ return reportValidationProblem(v, "Empty NMTOKEN value");
+ }
+
+ --end; // so that it now points to the last char
+ while (end > start && WstxInputData.isSpaceChar(cbuf[end])) {
+ --end;
+ }
+
+ // Ok, need to check char validity
+ for (int i = start; i <= end; ++i) {
+ char c = cbuf[i];
+ if (!WstxInputData.isNameChar(c, mCfgNsAware, mCfgXml11)) {
+ return reportInvalidChar(v, c, "not valid NMTOKEN character");
+ }
+ }
+
+ if (normalize) {
+ // Let's only create the String if we trimmed something
+ int len = (end - start)+1;
+ if (len != origLen) {
+ return new String(cbuf, start, len);
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Method called by the validator
+ * to ask attribute to verify that the default it has (if any) is
+ * valid for such type.
+ */
+ @Override
+ public void validateDefault(InputProblemReporter rep, boolean normalize)
+ throws XMLStreamException
+ {
+ String def = validateDefaultNmToken(rep, normalize);
+ if (normalize) {
+ mDefValue.setValue(def);
+ }
+ }
+}
diff -Nru libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/dtd/DTDNmTokensAttr.java libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/dtd/DTDNmTokensAttr.java
--- libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/dtd/DTDNmTokensAttr.java 1970-01-01 00:00:00.000000000 +0000
+++ libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/dtd/DTDNmTokensAttr.java 2018-03-31 01:33:28.000000000 +0000
@@ -0,0 +1,208 @@
+package com.ctc.wstx.dtd;
+
+import javax.xml.stream.XMLStreamException;
+
+import com.ctc.wstx.io.WstxInputData;
+import com.ctc.wstx.sr.InputProblemReporter;
+import com.ctc.wstx.util.PrefixedName;
+
+/**
+ * Specific attribute class for attributes that contain (unique)
+ * identifiers.
+ */
+public final class DTDNmTokensAttr
+ extends DTDAttribute
+{
+ /*
+ ///////////////////////////////////////////////////
+ // Life-cycle
+ ///////////////////////////////////////////////////
+ */
+
+ /**
+ * Main constructor.
+ */
+ public DTDNmTokensAttr(PrefixedName name, DefaultAttrValue defValue, int specIndex,
+ boolean nsAware, boolean xml11)
+ {
+ super(name, defValue, specIndex, nsAware, xml11);
+ }
+
+ @Override
+ public DTDAttribute cloneWith(int specIndex) {
+ return new DTDNmTokensAttr(mName, mDefValue, specIndex, mCfgNsAware, mCfgXml11);
+ }
+
+ /*
+ ///////////////////////////////////////////////////
+ // Public API
+ ///////////////////////////////////////////////////
+ */
+
+ @Override
+ public int getValueType() {
+ return TYPE_NMTOKENS;
+ }
+
+ /*
+ ///////////////////////////////////////////////////
+ // Public API, validation
+ ///////////////////////////////////////////////////
+ */
+
+ /**
+ * Method called by the validator
+ * to let the attribute do necessary normalization and/or validation
+ * for the value.
+ */
+ @Override
+ public String validate(DTDValidatorBase v, char[] cbuf, int start, int end, boolean normalize)
+ throws XMLStreamException
+ {
+ //int origStart = start;
+
+ /* First things first; let's ensure value is not empty (all
+ * white space)...
+ */
+ while (start < end && WstxInputData.isSpaceChar(cbuf[start])) {
+ ++start;
+ }
+ // Empty value?
+ if (start >= end) {
+ return reportValidationProblem(v, "Empty NMTOKENS value");
+ }
+
+ /* Then, let's have separate handling for normalizing and
+ * non-normalizing case, since latter is trivially easy case:
+ */
+ if (!normalize) {
+ for (; start < end; ++start) {
+ char c = cbuf[start];
+ if (!WstxInputData.isSpaceChar(c)
+ && !WstxInputData.isNameChar(c, mCfgNsAware, mCfgXml11)) {
+ return reportInvalidChar(v, c, "not valid as NMTOKENS character");
+ }
+ }
+ return null; // ok, all good
+ }
+
+ //boolean trimmed = (origStart != start);
+ //origStart = start;
+
+ --end; // so that it now points to the last char
+ // Wouldn't absolutely have to trim trailing... but is easy to do
+ while (end > start && WstxInputData.isSpaceChar(cbuf[end])) {
+ --end;
+ //trimmed = true;
+ }
+
+ /* Ok, now, need to check we only have valid chars, and maybe
+ * also coalesce multiple spaces, if any.
+ */
+ StringBuilder sb = null;
+
+ while (start <= end) {
+ int i = start;
+ for (; i <= end; ++i) {
+ char c = cbuf[i];
+ if (WstxInputData.isSpaceChar(c)) {
+ break;
+ }
+ if (!WstxInputData.isNameChar(c, mCfgNsAware, mCfgXml11)) {
+ return reportInvalidChar(v, c, "not valid as an NMTOKENS character");
+ }
+ }
+
+ if (sb == null) {
+ sb = new StringBuilder(end - start + 1);
+ } else {
+ sb.append(' ');
+ }
+ sb.append(cbuf, start, (i - start));
+
+ start = i + 1;
+ // Ok, any white space to skip?
+ while (start <= end && WstxInputData.isSpaceChar(cbuf[start])) {
+ ++start;
+ }
+ }
+
+ /* 27-Nov-2005, TSa: Could actually optimize trimming, and often
+ * avoid using StringBuilder... but let's only do it if it turns
+ * out dealing with NMTOKENS normalization shows up on profiling...
+ */
+ return sb.toString();
+ }
+
+ /**
+ * Method called by the validator
+ * to ask attribute to verify that the default it has (if any) is
+ * valid for such type.
+ */
+ @Override
+ public void validateDefault(InputProblemReporter rep, boolean normalize)
+ throws XMLStreamException
+ {
+ String defValue = mDefValue.getValue();
+ int len = defValue.length();
+
+ // Then code similar to actual value validation:
+ StringBuilder sb = null;
+ int count = 0;
+ int start = 0;
+
+ main_loop:
+ while (start < len) {
+ char c = defValue.charAt(start);
+
+ // Ok, any white space to skip?
+ while (true) {
+ if (!WstxInputData.isSpaceChar(c)) {
+ break;
+ }
+ if (++start >= len) {
+ break main_loop;
+ }
+ c = defValue.charAt(start);
+ }
+
+ int i = start+1;
+
+ do {
+ if (++i >= len) {
+ break;
+ }
+ c = defValue.charAt(i);
+ } while (!WstxInputData.isSpaceChar(c));
+ ++count;
+ String token = defValue.substring(start, i);
+ int illegalIx = WstxInputData.findIllegalNmtokenChar(token, mCfgNsAware, mCfgXml11);
+ if (illegalIx >= 0) {
+ reportValidationProblem(rep, "Invalid default value '"+defValue
+ +"'; character #"+illegalIx+" ("
+ +WstxInputData.getCharDesc(defValue.charAt(illegalIx))
+ +") not a valid NMTOKENS character");
+ }
+
+ if (normalize) {
+ if (sb == null) {
+ sb = new StringBuilder(i - start + 32);
+ } else {
+ sb.append(' ');
+ }
+ sb.append(token);
+ }
+ start = i+1;
+ }
+
+ if (count == 0) {
+ reportValidationProblem(rep, "Invalid default value '"+defValue
+ +"'; empty String is not a valid NMTOKENS value");
+ return;
+ }
+
+ if (normalize) {
+ mDefValue.setValue(sb.toString());
+ }
+ }
+}
diff -Nru libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/dtd/DTDNotationAttr.java libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/dtd/DTDNotationAttr.java
--- libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/dtd/DTDNotationAttr.java 1970-01-01 00:00:00.000000000 +0000
+++ libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/dtd/DTDNotationAttr.java 2018-03-31 01:33:28.000000000 +0000
@@ -0,0 +1,105 @@
+package com.ctc.wstx.dtd;
+
+import javax.xml.stream.XMLStreamException;
+
+import com.ctc.wstx.sr.InputProblemReporter;
+import com.ctc.wstx.util.PrefixedName;
+import com.ctc.wstx.util.WordResolver;
+
+/**
+ * Specific attribute class for attributes that are of NOTATION type,
+ * and also contain enumerated set of legal values.
+ */
+public final class DTDNotationAttr
+ extends DTDAttribute
+{
+ final WordResolver mEnumValues;
+
+ /*
+ ///////////////////////////////////////////////////
+ // Life-cycle
+ ///////////////////////////////////////////////////
+ */
+
+ public DTDNotationAttr(PrefixedName name, DefaultAttrValue defValue,
+ int specIndex, boolean nsAware, boolean xml11,
+ WordResolver enumValues)
+ {
+ super(name, defValue, specIndex, nsAware, xml11);
+ mEnumValues = enumValues;
+ }
+
+ @Override
+ public DTDAttribute cloneWith(int specIndex)
+ {
+ return new DTDNotationAttr(mName, mDefValue, specIndex,
+ mCfgNsAware, mCfgXml11, mEnumValues);
+ }
+
+ /*
+ ///////////////////////////////////////////////////
+ // Public API
+ ///////////////////////////////////////////////////
+ */
+
+ @Override
+ public int getValueType() {
+ return TYPE_NOTATION;
+ }
+
+ @Override
+ public boolean typeIsNotation() {
+ return true;
+ }
+
+ /*
+ ///////////////////////////////////////////////////
+ // Public API, validation
+ ///////////////////////////////////////////////////
+ */
+
+ /**
+ * Method called by the validator
+ * to let the attribute do necessary normalization and/or validation
+ * for the value.
+ *
+ * Note: identical to the implementation in {@link DTDEnumAttr}
+ */
+ @Override
+ public String validate(DTDValidatorBase v, char[] cbuf, int start, int end, boolean normalize)
+ throws XMLStreamException
+ {
+ String ok = validateEnumValue(cbuf, start, end, normalize, mEnumValues);
+ if (ok == null) {
+ String val = new String(cbuf, start, (end-start));
+ return reportValidationProblem(v, "Invalid notation value '"+val+"': has to be one of ("
+ +mEnumValues+")");
+ }
+ return ok;
+ }
+
+ /**
+ * Method called by the validator
+ * to ask attribute to verify that the default it has (if any) is
+ * valid for such type.
+ */
+ @Override
+ public void validateDefault(InputProblemReporter rep, boolean normalize)
+ throws XMLStreamException
+ {
+ // First, basic checks that it's a valid non-empty name:
+ String def = validateDefaultName(rep, normalize);
+
+ // And then that it's one of listed values:
+ String shared = mEnumValues.find(def);
+ if (shared == null) {
+ reportValidationProblem(rep, "Invalid default value '"+def+"': has to be one of ("
+ +mEnumValues+")");
+ }
+
+ // Ok, cool it's ok...
+ if (normalize) {
+ mDefValue.setValue(shared);
+ }
+ }
+}
diff -Nru libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/dtd/DTDSchemaFactory.java libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/dtd/DTDSchemaFactory.java
--- libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/dtd/DTDSchemaFactory.java 1970-01-01 00:00:00.000000000 +0000
+++ libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/dtd/DTDSchemaFactory.java 2018-03-31 01:33:28.000000000 +0000
@@ -0,0 +1,204 @@
+/* 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 com.ctc.wstx.dtd;
+
+import java.io.*;
+import java.net.URL;
+
+import javax.xml.stream.*;
+
+import org.codehaus.stax2.validation.*;
+
+import com.ctc.wstx.api.ReaderConfig;
+import com.ctc.wstx.api.ValidatorConfig;
+import com.ctc.wstx.cfg.XmlConsts;
+import com.ctc.wstx.exc.WstxIOException;
+import com.ctc.wstx.io.*;
+import com.ctc.wstx.util.DefaultXmlSymbolTable;
+import com.ctc.wstx.util.SymbolTable;
+import com.ctc.wstx.util.URLUtil;
+
+/**
+ * Factory for creating DTD validator schema objects (shareable stateless
+ * "blueprints" for creating actual validators).
+ *
+ * Due to close coupling of XML and DTD, some of the functionality
+ * implemented (like that of reading internal subsets embedded in XML
+ * documents) is only accessible by core Woodstox. The externally
+ * accessible
+ */
+public class DTDSchemaFactory
+ extends XMLValidationSchemaFactory
+{
+ /*
+ /////////////////////////////////////////////////////
+ // Objects shared by actual parsers
+ /////////////////////////////////////////////////////
+ */
+
+ /**
+ * 'Root' symbol table, used for creating actual symbol table instances,
+ * but never as is.
+ */
+ final static SymbolTable mRootSymbols = DefaultXmlSymbolTable.getInstance();
+ static {
+ mRootSymbols.setInternStrings(true);
+ }
+
+ /**
+ * Current configurations for this factory
+ */
+ protected final ValidatorConfig mSchemaConfig;
+
+ /**
+ * This configuration object is used (instead of a more specific one)
+ * since the actual DTD reader uses such configuration object.
+ */
+ protected final ReaderConfig mReaderConfig;
+
+ public DTDSchemaFactory()
+ {
+ super(XMLValidationSchema.SCHEMA_ID_DTD);
+ mReaderConfig = ReaderConfig.createFullDefaults();
+ mSchemaConfig = ValidatorConfig.createDefaults();
+ }
+
+ /*
+ ////////////////////////////////////////////////////////////
+ // Stax2, Configuration methods
+ ////////////////////////////////////////////////////////////
+ */
+
+ @Override
+ public boolean isPropertySupported(String propName) {
+ return mSchemaConfig.isPropertySupported(propName);
+ }
+
+ @Override
+ public boolean setProperty(String propName, Object value) {
+ return mSchemaConfig.setProperty(propName, value);
+ }
+
+ @Override
+ public Object getProperty(String propName) {
+ return mSchemaConfig.getProperty(propName);
+ }
+
+ /*
+ ////////////////////////////////////////////////////////////
+ // Stax2, Factory methods
+ ////////////////////////////////////////////////////////////
+ */
+
+ @Override
+ public XMLValidationSchema createSchema(InputStream in, String encoding,
+ String publicId, String systemId)
+ throws XMLStreamException
+ {
+ ReaderConfig rcfg = createPrivateReaderConfig();
+ return doCreateSchema(rcfg, StreamBootstrapper.getInstance
+ (publicId, SystemId.construct(systemId), in), publicId, systemId, null);
+ }
+
+ @Override
+ public XMLValidationSchema createSchema(Reader r,
+ String publicId, String systemId)
+ throws XMLStreamException
+ {
+ ReaderConfig rcfg = createPrivateReaderConfig();
+ return doCreateSchema(rcfg, ReaderBootstrapper.getInstance
+ (publicId, SystemId.construct(systemId), r, null), publicId, systemId, null);
+ }
+
+ @SuppressWarnings("resource")
+ @Override
+ public XMLValidationSchema createSchema(URL url)
+ throws XMLStreamException
+ {
+ ReaderConfig rcfg = createPrivateReaderConfig();
+ try {
+ InputStream in = URLUtil.inputStreamFromURL(url);
+ return doCreateSchema(rcfg, StreamBootstrapper.getInstance
+ (null, null, in),
+ null, url.toExternalForm(), url);
+ } catch (IOException ioe) {
+ throw new WstxIOException(ioe);
+ }
+ }
+
+ @SuppressWarnings("resource")
+ @Override
+ public XMLValidationSchema createSchema(File f)
+ throws XMLStreamException
+ {
+ ReaderConfig rcfg = createPrivateReaderConfig();
+ try {
+ URL url = URLUtil.toURL(f);
+ return doCreateSchema(rcfg, StreamBootstrapper.getInstance
+ (null, null, new FileInputStream(f)),
+ null, url.toExternalForm(), url);
+ } catch (IOException ioe) {
+ throw new WstxIOException(ioe);
+ }
+ }
+
+ /*
+ ////////////////////////////////////////////////////////////
+ // Internal methods
+ ////////////////////////////////////////////////////////////
+ */
+
+ /**
+ * The main validator construction method, called by all externally
+ * visible methods.
+ */
+ @SuppressWarnings("resource")
+ protected XMLValidationSchema doCreateSchema
+ (ReaderConfig rcfg, InputBootstrapper bs, String publicId, String systemIdStr, URL ctxt)
+ throws XMLStreamException
+ {
+ try {
+ Reader r = bs.bootstrapInput(rcfg, false, XmlConsts.XML_V_UNKNOWN);
+ if (bs.declaredXml11()) {
+ rcfg.enableXml11(true);
+ }
+ if (ctxt == null) { // this is just needed as context for param entity expansion
+ ctxt = URLUtil.urlFromCurrentDir();
+ }
+ /* Note: need to pass unknown for 'xmlVersion' here (as well as
+ * above for bootstrapping), since this is assumed to be the main
+ * level parsed document and no xml version compatibility checks
+ * should be done.
+ */
+ SystemId systemId = SystemId.construct(systemIdStr, ctxt);
+ WstxInputSource src = InputSourceFactory.constructEntitySource
+ (rcfg, null, null, bs, publicId, systemId, XmlConsts.XML_V_UNKNOWN, r);
+
+ /* true -> yes, fully construct for validation
+ * (does not mean it has to be used for validation, but required
+ * if it is to be used for that purpose)
+ */
+ return FullDTDReader.readExternalSubset(src, rcfg, /*int.subset*/null, true, bs.getDeclaredVersion());
+ } catch (IOException ioe) {
+ throw new WstxIOException(ioe);
+ }
+ }
+
+ private ReaderConfig createPrivateReaderConfig()
+ {
+ return mReaderConfig.createNonShared(mRootSymbols.makeChild());
+ }
+}
diff -Nru libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/dtd/DTDSubsetImpl.java libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/dtd/DTDSubsetImpl.java
--- libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/dtd/DTDSubsetImpl.java 1970-01-01 00:00:00.000000000 +0000
+++ libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/dtd/DTDSubsetImpl.java 2018-03-31 01:33:28.000000000 +0000
@@ -0,0 +1,531 @@
+/* Woodstox XML processor
+ *
+ * Copyright (c) 2004- 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 com.ctc.wstx.dtd;
+
+import java.text.MessageFormat;
+import java.util.*;
+
+import javax.xml.stream.Location;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.events.NotationDeclaration;
+
+import org.codehaus.stax2.validation.*;
+
+import com.ctc.wstx.cfg.ErrorConsts;
+import com.ctc.wstx.ent.EntityDecl;
+import com.ctc.wstx.exc.WstxParsingException;
+import com.ctc.wstx.sr.InputProblemReporter;
+import com.ctc.wstx.util.DataUtil;
+import com.ctc.wstx.util.PrefixedName;
+
+/**
+ * The default implementation of {@link DTDSubset}
+ */
+public final class DTDSubsetImpl
+ extends DTDSubset
+{
+ /**
+ * Whether this subset is cachable. Only those external
+ * subsets that do not refer to PEs defined by internal subsets (or
+ * GEs via default attribute value expansion) are cachable.
+ */
+ final boolean mIsCachable;
+
+ /**
+ * Whether this subset has full validation information; and
+ * consequently whether it will do actual validation, or just allow
+ * access to type information, notations, entities, and add default
+ * attribute values.
+ */
+ final boolean mFullyValidating;
+
+ /**
+ * Flag that indicates whether any of the elements declarared
+ * has any attribute default values for namespace pseudo-attributes.
+ */
+ final boolean mHasNsDefaults;
+
+ /*
+ //////////////////////////////////////////////////////
+ // Entity information
+ //////////////////////////////////////////////////////
+ */
+
+ /**
+ * Map (name-to-EntityDecl) of general entity declarations (internal,
+ * external) for this DTD subset.
+ */
+ final HashMap mGeneralEntities;
+
+ /**
+ * Lazily instantiated List that contains all notations from
+ * {@link #mGeneralEntities} (preferably in their declaration order; depends
+ * on whether platform, ie. JDK version, has insertion-ordered
+ * Maps available), used by DTD event Objects.
+ */
+ volatile transient List mGeneralEntityList = null;
+
+ /**
+ * Set of names of general entities references by this subset. Note that
+ * only those GEs that are referenced by default attribute value
+ * definitions count, since GEs in text content are only expanded
+ * when reading documents, but attribute default values are expanded
+ * when reading DTD subset itself.
+ *
+ * Needed
+ * for determinining if external subset materially depends on definitions
+ * from internal subset; if so, such subset is not cachable.
+ * This also
+ * means that information is not stored for non-cachable instance.
+ */
+ final Set mRefdGEs;
+
+ // // // Parameter entity info:
+
+ /**
+ * Map (name-to-WEntityDeclaration) that contains all parameter entities
+ * defined by this subset. May be empty if such information will not be
+ * needed for use; for example, external subset's definitions are needed,
+ * nor are combined DTD set's.
+ */
+ final HashMap mDefinedPEs;
+
+ /**
+ * Set of names of parameter entities references by this subset. Needed
+ * when determinining if external subset materially depends on definitions
+ * from internal subset, which is needed to know when caching external
+ * subsets.
+ *
+ * Needed
+ * for determinining if external subset materially depends on definitions
+ * from internal subset; if so, such subset is not cachable.
+ * This also
+ * means that information is not stored for non-cachable instance.
+ */
+ final Set mRefdPEs;
+
+ /*
+ //////////////////////////////////////////////////////
+ // Notation definitions:
+ //////////////////////////////////////////////////////
+ */
+
+ /**
+ * Map (name-to-NotationDecl) that this subset has defined.
+ */
+ final HashMap mNotations;
+
+ /**
+ * Lazily instantiated List that contains all notations from
+ * {@link #mNotations} (preferably in their declaration order; depends
+ * on whether platform, ie. JDK version, has insertion-ordered
+ * Maps available), used by DTD event Objects.
+ */
+ transient List mNotationList = null;
+
+
+ /*
+ //////////////////////////////////////////////////////
+ // Element definitions:
+ //////////////////////////////////////////////////////
+ */
+
+ final HashMap mElements;
+
+ /*
+ //////////////////////////////////////////////////////
+ // Life-cycle
+ //////////////////////////////////////////////////////
+ */
+
+ private DTDSubsetImpl(boolean cachable,
+ HashMap genEnt, Set refdGEs,
+ HashMap paramEnt, Set peRefs,
+ HashMap notations, HashMap elements,
+ boolean fullyValidating)
+ {
+ mIsCachable = cachable;
+ mGeneralEntities = genEnt;
+ mRefdGEs = refdGEs;
+ mDefinedPEs = paramEnt;
+ mRefdPEs = peRefs;
+ mNotations = notations;
+ mElements = elements;
+ mFullyValidating = fullyValidating;
+
+ boolean anyNsDefs = false;
+ if (elements != null) {
+ for (DTDElement elem : elements.values()) {
+ if (elem.hasNsDefaults()) {
+ anyNsDefs = true;
+ break;
+ }
+ }
+ }
+ mHasNsDefaults = anyNsDefs;
+ }
+
+ public static DTDSubsetImpl constructInstance(boolean cachable,
+ HashMap genEnt, Set refdGEs,
+ HashMap paramEnt, Set refdPEs,
+ HashMap notations,
+ HashMap elements,
+ boolean fullyValidating)
+ {
+ return new DTDSubsetImpl(cachable, genEnt, refdGEs,
+ paramEnt, refdPEs,
+ notations, elements,
+ fullyValidating);
+ }
+
+ /**
+ * Method that will combine definitions from internal and external subsets,
+ * producing a single DTD set.
+ */
+ @Override
+ public DTDSubset combineWithExternalSubset(InputProblemReporter rep, DTDSubset extSubset)
+ throws XMLStreamException
+ {
+ /* First let's see if we can just reuse GE Map used by int or ext
+ * subset; (if only one has contents), or if not, combine them.
+ */
+ HashMap ge1 = getGeneralEntityMap();
+ HashMap ge2 = extSubset.getGeneralEntityMap();
+ if (ge1 == null || ge1.isEmpty()) {
+ ge1 = ge2;
+ } else {
+ if (ge2 != null && !ge2.isEmpty()) {
+ /* Internal subset Objects are never shared or reused (and by
+ * extension, neither are objects they contain), so we can just
+ * modify GE map if necessary
+ */
+ combineMaps(ge1, ge2);
+ }
+ }
+
+ // Ok, then, let's combine notations similarly
+ HashMap n1 = getNotationMap();
+ HashMap n2 = extSubset.getNotationMap();
+ if (n1 == null || n1.isEmpty()) {
+ n1 = n2;
+ } else {
+ if (n2 != null && !n2.isEmpty()) {
+ /* First; let's make sure there are no colliding notation
+ * definitions: it's an error to try to redefine notations.
+ */
+ checkNotations(n1, n2);
+
+ /* Internal subset Objects are never shared or reused (and by
+ * extension, neither are objects they contain), so we can just
+ * modify notation map if necessary
+ */
+ combineMaps(n1, n2);
+ }
+ }
+
+
+ // And finally elements, rather similarly:
+ HashMap e1 = getElementMap();
+ HashMap e2 = extSubset.getElementMap();
+ if (e1 == null || e1.isEmpty()) {
+ e1 = e2;
+ } else {
+ if (e2 != null && !e2.isEmpty()) {
+ /* Internal subset Objects are never shared or reused (and by
+ * extension, neither are objects they contain), so we can just
+ * modify element map if necessary
+ */
+ combineElements(rep, e1, e2);
+ }
+ }
+
+ /* Combos are not cachable, and because of that, there's no point
+ * in storing any PE info either.
+ */
+ return constructInstance(false, ge1, null, null, null, n1, e1,
+ mFullyValidating);
+ }
+
+ /*
+ //////////////////////////////////////////////////////
+ // XMLValidationSchema implementation
+ //////////////////////////////////////////////////////
+ */
+
+ @Override
+ public XMLValidator createValidator(ValidationContext ctxt)
+ throws XMLStreamException
+ {
+ if (mFullyValidating) {
+ return new DTDValidator(this, ctxt, mHasNsDefaults,
+ getElementMap(), getGeneralEntityMap());
+ }
+ return new DTDTypingNonValidator(this, ctxt, mHasNsDefaults,
+ getElementMap(), getGeneralEntityMap());
+
+ }
+
+ /*
+ //////////////////////////////////////////////////////
+ // DTDValidationSchema implementation
+ //////////////////////////////////////////////////////
+ */
+
+ @Override
+ public int getEntityCount() {
+ return (mGeneralEntities == null) ? 0 : mGeneralEntities.size();
+ }
+
+ @Override
+ public int getNotationCount() {
+ return (mNotations == null) ? 0 : mNotations.size();
+ }
+
+ /*
+ //////////////////////////////////////////////////////
+ // Woodstox-specific public API
+ //////////////////////////////////////////////////////
+ */
+
+ @Override
+ public boolean isCachable() {
+ return mIsCachable;
+ }
+
+ @Override
+ public HashMap getGeneralEntityMap() {
+ return mGeneralEntities;
+ }
+
+ @Override
+ public List getGeneralEntityList()
+ {
+ List l = mGeneralEntityList;
+ if (l == null) {
+ if (mGeneralEntities == null || mGeneralEntities.size() == 0) {
+ l = Collections.emptyList();
+ } else {
+ l = Collections.unmodifiableList(new ArrayList(mGeneralEntities.values()));
+ }
+ mGeneralEntityList = l;
+ }
+
+ return l;
+ }
+
+ @Override
+ public HashMap getParameterEntityMap() {
+ return mDefinedPEs;
+ }
+
+ @Override
+ public HashMap getNotationMap() {
+ return mNotations;
+ }
+
+ @Override
+ public synchronized List getNotationList()
+ {
+ List l = mNotationList;
+ if (l == null) {
+ if (mNotations == null || mNotations.size() == 0) {
+ l = Collections.emptyList();
+ } else {
+ l = Collections.unmodifiableList(new ArrayList(mNotations.values()));
+ }
+ mNotationList = l;
+ }
+
+ return l;
+ }
+
+ @Override
+ public HashMap getElementMap() {
+ return mElements;
+ }
+
+ /**
+ * Method used in determining whether cached external subset instance
+ * can be used with specified internal subset. If ext. subset references
+ * any parameter/general entities int subset (re-)defines, it can not;
+ * otherwise it can be used.
+ *
+ * @return True if this (external) subset refers to a parameter entity
+ * defined in passed-in internal subset.
+ */
+ @Override
+ public boolean isReusableWith(DTDSubset intSubset)
+ {
+ Set refdPEs = mRefdPEs;
+
+ if (refdPEs != null && refdPEs.size() > 0) {
+ HashMap intPEs = intSubset.getParameterEntityMap();
+ if (intPEs != null && intPEs.size() > 0) {
+ if (DataUtil.anyValuesInCommon(refdPEs, intPEs.keySet())) {
+ return false;
+ }
+ }
+ }
+ Set refdGEs = mRefdGEs;
+
+ if (refdGEs != null && refdGEs.size() > 0) {
+ HashMap intGEs = intSubset.getGeneralEntityMap();
+ if (intGEs != null && intGEs.size() > 0) {
+ if (DataUtil.anyValuesInCommon(refdGEs, intGEs.keySet())) {
+ return false;
+ }
+ }
+ }
+ return true; // yep, no dependencies overridden
+ }
+
+ /*
+ //////////////////////////////////////////////////////
+ // Overridden default methods:
+ //////////////////////////////////////////////////////
+ */
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append("[DTDSubset: ");
+ int count = getEntityCount();
+ sb.append(count);
+ sb.append(" general entities");
+ sb.append(']');
+ return sb.toString();
+ }
+
+ /*
+ //////////////////////////////////////////////////////
+ // Convenience methods used by other classes
+ //////////////////////////////////////////////////////
+ */
+
+ public static void throwNotationException(NotationDeclaration oldDecl, NotationDeclaration newDecl)
+ throws XMLStreamException
+ {
+ throw new WstxParsingException
+ (MessageFormat.format(ErrorConsts.ERR_DTD_NOTATION_REDEFD,
+ new Object[] {
+ newDecl.getName(),
+ oldDecl.getLocation().toString()}),
+ newDecl.getLocation());
+ }
+
+ public static void throwElementException(DTDElement oldElem, Location loc)
+ throws XMLStreamException
+ {
+ throw new WstxParsingException
+ (MessageFormat.format(ErrorConsts.ERR_DTD_ELEM_REDEFD,
+ new Object[] {
+ oldElem.getDisplayName(),
+ oldElem.getLocation().toString() }),
+ loc);
+ }
+
+ /*
+ //////////////////////////////////////////////////////
+ // Internal methods
+ //////////////////////////////////////////////////////
+ */
+
+ /**
+ *
+ * Note: The first Map argument WILL be modified; second one
+ * not. Caller needs to ensure this is acceptable.
+ */
+ private static void combineMaps(Map m1, Map m2)
+ {
+ for (Map.Entry me : m2.entrySet()) {
+ K key = me.getKey();
+ /* Int. subset has precedence, but let's guess most of
+ * the time there are no collisions:
+ */
+ V old = m1.put(key, me.getValue());
+ // Oops, got value! Let's put it back
+ if (old != null) {
+ m1.put(key, old);
+ }
+ }
+ }
+
+ /**
+ * Method that will try to merge in elements defined in the external
+ * subset, into internal subset; it will also check for redeclarations
+ * when doing this, as it's invalid to redeclare elements. Care has to
+ * be taken to only check actual redeclarations: placeholders should
+ * not cause problems.
+ */
+ private void combineElements(InputProblemReporter rep, HashMap intElems, HashMap extElems)
+ throws XMLStreamException
+ {
+ for (Map.Entry me : extElems.entrySet()) {
+ PrefixedName key = me.getKey();
+ DTDElement extElem = me.getValue();
+ DTDElement intElem = intElems.get(key);
+
+ // If there was no old value, can just merge new one in and continue
+ if (intElem == null) {
+ intElems.put(key, extElem);
+ continue;
+ }
+
+ // Which one is defined (if either)?
+ if (extElem.isDefined()) { // one from the ext subset
+ if (intElem.isDefined()) { // but both can't be; that's an error
+ throwElementException(intElem, extElem.getLocation());
+ } else {
+ /* Note: can/should not modify the external element (by
+ * for example adding attributes); external element may
+ * be cached and shared... so, need to do the reverse,
+ * define the one from internal subset.
+ */
+ intElem.defineFrom(rep, extElem, mFullyValidating);
+ }
+ } else {
+ if (!intElem.isDefined()) {
+ /* ??? Should we warn about neither of them being really
+ * declared?
+ */
+ rep.reportProblem(intElem.getLocation(),
+ ErrorConsts.WT_ENT_DECL,
+ ErrorConsts.W_UNDEFINED_ELEM,
+ extElem.getDisplayName(), null);
+
+ } else {
+ intElem.mergeMissingAttributesFrom(rep, extElem, mFullyValidating);
+ }
+ }
+ }
+ }
+
+ private static void checkNotations(HashMap fromInt, HashMap fromExt)
+ throws XMLStreamException
+ {
+ /* Since it's external subset that would try to redefine things
+ * defined in internal subset, let's traverse definitions in
+ * the ext. subset first (even though that may not be the fastest
+ * way), so that we have a chance of catching the first problem
+ * (As long as Maps iterate in insertion order).
+ */
+ for (Map.Entry en : fromExt.entrySet()) {
+ if (fromInt.containsKey(en.getKey())) {
+ throwNotationException(fromInt.get(en.getKey()), en.getValue());
+ }
+ }
+ }
+}
diff -Nru libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/dtd/DTDSubset.java libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/dtd/DTDSubset.java
--- libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/dtd/DTDSubset.java 1970-01-01 00:00:00.000000000 +0000
+++ libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/dtd/DTDSubset.java 2018-03-31 01:33:28.000000000 +0000
@@ -0,0 +1,122 @@
+/* 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 com.ctc.wstx.dtd;
+
+import java.util.*;
+
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.events.NotationDeclaration;
+
+import org.codehaus.stax2.validation.*;
+
+import com.ctc.wstx.ent.EntityDecl;
+import com.ctc.wstx.sr.InputProblemReporter;
+import com.ctc.wstx.util.PrefixedName;
+
+/**
+ * This is the abstract base class that implements the standard Stax2
+ * validation schema base class ({@link XMLValidationSchema}, as well
+ * as specifies extended Woodstox-specific interface for accessing
+ * DTD-specific things like entity expansions and notation properties.
+ *
+ * API is separated from its implementation to reduce coupling; for example,
+ * it is possible to have DTD subset implementations that do not implement
+ * validation logics, just entity expansion.
+ */
+public abstract class DTDSubset
+ implements DTDValidationSchema
+{
+ /*
+ //////////////////////////////////////////////////////
+ // Life-cycle
+ //////////////////////////////////////////////////////
+ */
+
+ protected DTDSubset() { }
+
+ /**
+ * Method that will combine definitions from this internal subset with
+ * definitions from passed-in external subset, producing a new combined
+ * DTDSubset instance.
+ */
+ public abstract DTDSubset combineWithExternalSubset(InputProblemReporter rep,
+ DTDSubset extSubset)
+ throws XMLStreamException;
+
+ /*
+ //////////////////////////////////////////////////////
+ // XMLValidationSchema implementation
+ //////////////////////////////////////////////////////
+ */
+
+ @Override
+ public abstract XMLValidator createValidator(ValidationContext ctxt)
+ throws XMLStreamException;
+
+ @Override
+ public String getSchemaType() {
+ return XMLValidationSchema.SCHEMA_ID_DTD;
+ }
+
+ /*
+ //////////////////////////////////////////////////////
+ // And extended DTDValidationSchema
+ //////////////////////////////////////////////////////
+ */
+
+ @Override
+ public abstract int getEntityCount();
+
+ @Override
+ public abstract int getNotationCount();
+
+ /*
+ //////////////////////////////////////////////////////
+ // Woodstox-specific API, caching support
+ //////////////////////////////////////////////////////
+ */
+
+ public abstract boolean isCachable();
+
+ /**
+ * Method used in determining whether cached external subset instance
+ * can be used with specified internal subset. If ext. subset references
+ * any parameter entities int subset (re-)defines, it can not; otherwise
+ * it can be used.
+ *
+ * @return True if this (external) subset refers to a parameter entity
+ * defined in passed-in internal subset.
+ */
+ public abstract boolean isReusableWith(DTDSubset intSubset);
+
+ /*
+ //////////////////////////////////////////////////////
+ // Woodstox-specific API, entity/notation handling
+ //////////////////////////////////////////////////////
+ */
+
+ public abstract HashMap getGeneralEntityMap();
+
+ public abstract List getGeneralEntityList();
+
+ public abstract HashMap getParameterEntityMap();
+
+ public abstract HashMap getNotationMap();
+
+ public abstract List getNotationList();
+
+ public abstract HashMap getElementMap();
+}
diff -Nru libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/dtd/DTDTypingNonValidator.java libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/dtd/DTDTypingNonValidator.java
--- libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/dtd/DTDTypingNonValidator.java 1970-01-01 00:00:00.000000000 +0000
+++ libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/dtd/DTDTypingNonValidator.java 2018-03-31 01:33:28.000000000 +0000
@@ -0,0 +1,326 @@
+/* Woodstox XML processor
+ *
+ * Copyright (c) 2004- 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 com.ctc.wstx.dtd;
+
+import java.util.*;
+
+import javax.xml.stream.XMLStreamException;
+
+import org.codehaus.stax2.validation.*;
+
+import com.ctc.wstx.ent.EntityDecl;
+import com.ctc.wstx.util.DataUtil;
+import com.ctc.wstx.util.ElementIdMap;
+import com.ctc.wstx.util.ExceptionUtil;
+import com.ctc.wstx.util.PrefixedName;
+
+/**
+ * This class is a "non-validating validator"; a validator-like object
+ * that handles DTD-based non-validation functionality: determining type
+ * information and default values. This instance does NOT implement any
+ * actual DTD-validation, and is to be used in DTD-aware non-validating
+ * mode.
+ */
+public class DTDTypingNonValidator
+ extends DTDValidatorBase
+{
+ /*
+ ///////////////////////////////////////////
+ // Element def/spec/validator stack, state
+ ///////////////////////////////////////////
+ */
+
+ /**
+ * Flag that indicates if current element has any attributes that
+ * have default values.
+ */
+ protected boolean mHasAttrDefaults = false;
+
+ /**
+ * Bitset used for keeping track of defaulted attributes for which values
+ * have been found. Only non-null when current element does have such
+ * attributes
+ */
+ protected BitSet mCurrDefaultAttrs = null;
+
+ /**
+ * Flag that indicates whether any of the attributes is potentially
+ * normalizable, and we are in attribute-normalizing mode.
+ */
+ protected boolean mHasNormalizableAttrs = false;
+
+ /*
+ ///////////////////////////////////////
+ // Temporary helper objects
+ ///////////////////////////////////////
+ */
+
+ /**
+ * Reusable lazily instantiated BitSet; needed to keep track of
+ * 'missing' attributes with default values (normal default, #FIXED).
+ */
+ BitSet mTmpDefaultAttrs;
+
+ /*
+ ///////////////////////////////////////////
+ // Life-cycle
+ ///////////////////////////////////////////
+ */
+
+ public DTDTypingNonValidator(DTDSubset schema, ValidationContext ctxt, boolean hasNsDefaults,
+ Map elemSpecs, Map genEntities)
+ {
+ super(schema, ctxt, hasNsDefaults, elemSpecs, genEntities);
+ }
+
+ /**
+ * @return False, since this is not a real validator
+ */
+ @Override
+ public final boolean reallyValidating() { return false; }
+
+ /*
+ ///////////////////////////////////////
+ // Configuration
+ ///////////////////////////////////////
+ */
+
+ /**
+ * This 'validator' will not normalize any attributes,
+ * so let's implement this as no-op.
+ */
+ @Override
+ public void setAttrValueNormalization(boolean state) {
+ // nop
+ }
+
+ /*
+ ///////////////////////////////////////
+ // XMLValidator implementation
+ ///////////////////////////////////////
+ */
+
+ //public XMLValidationSchema getSchema()
+
+ @Override
+ public void validateElementStart(String localName, String uri, String prefix)
+ throws XMLStreamException
+ {
+ // Ok, can we find the element definition?
+ mTmpKey.reset(prefix, localName);
+ DTDElement elem = mElemSpecs.get(mTmpKey);
+ // whether it's found or not, let's add a stack frame:
+ int elemCount = mElemCount++;
+ if (elemCount >= mElems.length) {
+ mElems = (DTDElement[]) DataUtil.growArrayBy50Pct(mElems);
+ }
+
+ mElems[elemCount] = mCurrElem = elem;
+ mAttrCount = 0;
+ mIdAttrIndex = -2; // -2 as a "don't know yet" marker
+
+ /* but if not found, can not obtain any type information. Not
+ * a validation problem though, since we are doing none...
+ * Oh, also, unlike with real validation, not having actual element
+ * information is ok; can still have attributes!
+ */
+ if (elem == null) { // || !elem.isDefined())
+ mCurrAttrDefs = NO_ATTRS;
+ mHasAttrDefaults = false;
+ mCurrDefaultAttrs = null;
+ mHasNormalizableAttrs = false;
+ return;
+ }
+
+ // If element found, does it have any attributes?
+ mCurrAttrDefs = elem.getAttributes();
+ if (mCurrAttrDefs == null) {
+ mCurrAttrDefs = NO_ATTRS;
+ mHasAttrDefaults = false;
+ mCurrDefaultAttrs = null;
+ mHasNormalizableAttrs = false;
+ return;
+ }
+
+ // Any normalization needed?
+ mHasNormalizableAttrs = mNormAttrs || elem.attrsNeedValidation();
+
+ // Any default values?
+ mHasAttrDefaults = elem.hasAttrDefaultValues();
+ if (mHasAttrDefaults) {
+ /* Special count also contains ones with #REQUIRED value, but
+ * that's a minor sub-optimality...
+ */
+ int specCount = elem.getSpecialCount();
+ BitSet bs = mTmpDefaultAttrs;
+ if (bs == null) {
+ mTmpDefaultAttrs = bs = new BitSet(specCount);
+ } else {
+ bs.clear();
+ }
+ mCurrDefaultAttrs = bs;
+ } else {
+ mCurrDefaultAttrs = null;
+ }
+ }
+
+ @Override
+ public String validateAttribute(String localName, String uri,
+ String prefix, String value)
+ throws XMLStreamException
+ {
+ /* no need to do any validation; however, need to do following:
+ *
+ * (a) Figure out type info, if any (to get data type, id index etc);
+ * if yes, do:
+ * (1) If attribute has default value, note down it's not needed due
+ * to explicit definition
+ * (2) If attribute is normalizable, normalize it without validation
+ */
+ DTDAttribute attr = mCurrAttrDefs.get(mTmpKey.reset(prefix, localName));
+ int index = mAttrCount++;
+ if (index >= mAttrSpecs.length) {
+ mAttrSpecs = (DTDAttribute[]) DataUtil.growArrayBy50Pct(mAttrSpecs);
+ }
+ mAttrSpecs[index] = attr;
+
+ /* Although undeclared attribute would be a validation error,
+ * we don't care here... just need to skip it
+ */
+ if (attr != null) {
+ if (mHasAttrDefaults) {
+ /* Once again, let's use more generic 'special' index,
+ * even though it also includes #REQUIRED values
+ */
+ int specIndex = attr.getSpecialIndex();
+ if (specIndex >= 0) {
+ mCurrDefaultAttrs.set(specIndex);
+ }
+ }
+ if (mHasNormalizableAttrs) {
+ // !!! TBI
+ }
+ }
+ return null; // fine as is
+ }
+
+ @Override
+ public String validateAttribute(String localName, String uri,
+ String prefix,
+ char[] valueChars, int valueStart,
+ int valueEnd)
+ throws XMLStreamException
+ {
+ // note: cut'n pasted from above...
+ DTDAttribute attr = mCurrAttrDefs.get(mTmpKey.reset(prefix, localName));
+ int index = mAttrCount++;
+ if (index >= mAttrSpecs.length) {
+ mAttrSpecs = (DTDAttribute[]) DataUtil.growArrayBy50Pct(mAttrSpecs);
+ }
+ mAttrSpecs[index] = attr;
+ if (attr != null) {
+ if (mHasAttrDefaults) {
+ int specIndex = attr.getSpecialIndex();
+ if (specIndex >= 0) {
+ mCurrDefaultAttrs.set(specIndex);
+ }
+ }
+ if (mHasNormalizableAttrs) { // may get normalized, after all
+ return attr.normalize(this, valueChars, valueStart, valueEnd);
+ }
+ }
+ return null; // fine as is
+ }
+
+ @Override
+ public int validateElementAndAttributes()
+ throws XMLStreamException
+ {
+ /* Ok; since we are not really validating, we just need to add possible
+ * attribute default values, and return "anything goes"
+ * as the allowable content:
+ */
+ DTDElement elem = mCurrElem;
+ if (mHasAttrDefaults) {
+ BitSet specBits = mCurrDefaultAttrs;
+ int specCount = elem.getSpecialCount();
+ int ix = specBits.nextClearBit(0);
+ while (ix < specCount) { // something amiss!
+ List specAttrs = elem.getSpecialAttrs();
+ DTDAttribute attr = specAttrs.get(ix);
+ if (attr.hasDefaultValue()) { // no default for #REQUIRED...
+ doAddDefaultValue(attr);
+ }
+ ix = specBits.nextClearBit(ix+1);
+ }
+ }
+ /* However: we should indicate cases where PCDATA is not supposed
+ * to occur -- although it won't be considered an error, when not
+ * validating, info is needed to determine type of SPACE instead
+ * of CHARACTERS. Other validation types are not to be returned,
+ * however, since caller doesn't know how to deal with such
+ * cases.
+ */
+ return (elem == null) ? XMLValidator.CONTENT_ALLOW_ANY_TEXT :
+ elem.getAllowedContentIfSpace();
+ }
+
+ @Override
+ public int validateElementEnd(String localName, String uri, String prefix)
+ throws XMLStreamException
+ {
+ /* Since we are not really validating, only need to maintain
+ * the element stack, and return "anything goes" as allowable content:
+ */
+ int ix = --mElemCount;
+ mElems[ix] = null;
+ if (ix < 1) {
+ return XMLValidator.CONTENT_ALLOW_ANY_TEXT;
+ }
+ DTDElement elem = mElems[ix-1];
+ return (elem == null) ? XMLValidator.CONTENT_ALLOW_ANY_TEXT :
+ mElems[ix-1].getAllowedContentIfSpace();
+ }
+
+ // base class implements these ok:
+ //public void validateText(String text, boolean lastTextSegment)
+ //public void validateText(char[] cbuf, int textStart, int textEnd, boolean lastTextSegment)
+
+ @Override
+ public void validationCompleted(boolean eod)
+ //throws XMLStreamException
+ {
+ // fine, great, nothing to do...
+ }
+
+ /*
+ ///////////////////////////////////////
+ // Package methods, accessors
+ ///////////////////////////////////////
+ */
+
+ @Override
+ protected ElementIdMap getIdMap()
+ {
+ /* should never be called; for now let's throw an exception, if it
+ * turns out it does get called can/should return an empty immutable
+ * map or something
+ */
+ ExceptionUtil.throwGenericInternal();
+ return null; // never gets here
+ }
+
+}
diff -Nru libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/dtd/DTDValidatorBase.java libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/dtd/DTDValidatorBase.java
--- libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/dtd/DTDValidatorBase.java 1970-01-01 00:00:00.000000000 +0000
+++ libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/dtd/DTDValidatorBase.java 2018-03-31 01:33:28.000000000 +0000
@@ -0,0 +1,549 @@
+/* Woodstox XML processor
+ *
+ * Copyright (c) 2004- 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 com.ctc.wstx.dtd;
+
+import java.text.MessageFormat;
+import java.util.*;
+
+import javax.xml.stream.Location;
+import javax.xml.stream.XMLStreamException;
+
+import org.codehaus.stax2.validation.*;
+
+import com.ctc.wstx.api.WstxInputProperties;
+import com.ctc.wstx.ent.EntityDecl;
+import com.ctc.wstx.sr.NsDefaultProvider;
+import com.ctc.wstx.sr.InputElementStack;
+import com.ctc.wstx.util.DataUtil;
+import com.ctc.wstx.util.ElementIdMap;
+import com.ctc.wstx.util.ExceptionUtil;
+import com.ctc.wstx.util.PrefixedName;
+
+/**
+ * Shared abstract base class for Woodstox implementations
+ * of {@link XMLValidator} for DTD validation.
+ * Since there are 2 sub-types -- full actual DTD validator, and a dummy
+ * one that only adds type information and default values, with no actual
+ * validation -- common functionality was refactored into this base
+ * class.
+ */
+public abstract class DTDValidatorBase
+ extends XMLValidator
+ implements NsDefaultProvider // for namespace attr defaults
+{
+ protected final static HashMap NO_ATTRS = new HashMap();
+
+ /*
+ /////////////////////////////////////////////////////
+ // Constants
+ /////////////////////////////////////////////////////
+ */
+
+ /**
+ * Estimated maximum depth of typical documents; used to allocate
+ * the array for element stack
+ */
+ final static int DEFAULT_STACK_SIZE = 16;
+
+ /**
+ * Estimated maximum number of attributes for a single element
+ */
+ final static int EXP_MAX_ATTRS = 16;
+
+ /**
+ * Let's actually just reuse a local Map...
+ */
+ protected final static HashMap EMPTY_MAP = new HashMap();
+
+ /*
+ ///////////////////////////////////////
+ // Configuration
+ ///////////////////////////////////////
+ */
+
+ /**
+ * Flag that indicates whether any of the elements declared has default
+ * attribute values for namespace declaration pseudo-attributes.
+ */
+ final boolean mHasNsDefaults;
+
+ /**
+ * DTD schema ({@link DTDSubsetImpl}) object that created this validator
+ * instance.
+ */
+ final DTDSubset mSchema;
+
+ /**
+ * Validation context (owner) for this validator. Needed for adding
+ * default attribute values, for example.
+ */
+ final ValidationContext mContext;
+
+ /**
+ * Map that contains element specifications from DTD; null if no
+ * DOCTYPE declaration found.
+ */
+ final Map mElemSpecs;
+
+ /**
+ * General entities defined in DTD subsets; needed for validating
+ * ENTITY/ENTITIES attributes.
+ */
+ final Map mGeneralEntities;
+
+ /**
+ * Flag that indicates whether parser wants the attribute values
+ * to be normalized (according to XML specs) or not (which may be
+ * more efficient, although not compliant with the specs)
+ */
+ protected boolean mNormAttrs;
+
+ /*
+ ///////////////////////////////////////////
+ // Element def/spec/validator stack, state
+ ///////////////////////////////////////////
+ */
+
+ /**
+ * This is the element that is currently being validated; valid
+ * during
+ * validateElementStart
,
+ * validateAttribute
,
+ * validateElementAndAttributes
calls.
+ */
+ protected DTDElement mCurrElem = null;
+
+ /**
+ * Stack of element definitions matching the current active element stack.
+ * Instances are elements definitions read from DTD.
+ */
+ protected DTDElement[] mElems = null;
+
+ /**
+ * Number of elements in {@link #mElems}.
+ */
+ protected int mElemCount = 0;
+
+ /**
+ * Attribute definitions for attributes the current element may have
+ */
+ protected HashMap mCurrAttrDefs = null;
+
+ /**
+ * List of attribute declarations/specifications, one for each
+ * attribute of the current element, for which there is a matching
+ * value (either explicitly defined, or assigned via defaulting).
+ */
+ protected DTDAttribute[] mAttrSpecs = new DTDAttribute[EXP_MAX_ATTRS];
+
+ /**
+ * Number of attribute specification Objects in
+ * {@link #mAttrSpecs}; needed to store in case type information
+ * is requested later on.
+ */
+ protected int mAttrCount = 0;
+
+ /**
+ * Index of the attribute of type ID, within current element's
+ * attribute list. Track of this is kept separate from other
+ * attribute since id attributes often need to be used for resolving
+ * cross-references.
+ */
+ protected int mIdAttrIndex = -1;
+
+ /*
+ ///////////////////////////////////////
+ // Temporary helper objects
+ ///////////////////////////////////////
+ */
+
+ protected final transient PrefixedName mTmpKey = new PrefixedName(null, null);
+
+ /**
+ * Temporary buffer attribute instances can share for validation
+ * purposes
+ */
+ char[] mTmpAttrValueBuffer = null;
+
+ /*
+ ///////////////////////////////////////
+ // Life-cycle
+ ///////////////////////////////////////
+ */
+
+ public DTDValidatorBase(DTDSubset schema, ValidationContext ctxt, boolean hasNsDefaults,
+ Map elemSpecs, Map genEntities)
+ {
+ mSchema = schema;
+ mContext = ctxt;
+ mHasNsDefaults = hasNsDefaults;
+ if (elemSpecs == null || elemSpecs.size() == 0) {
+ mElemSpecs = Collections.emptyMap();
+ } else {
+ mElemSpecs = elemSpecs;
+ }
+ mGeneralEntities = genEntities;
+ // By default, let's assume attrs are to be normalized (fully xml compliant)
+ mNormAttrs = true;
+ mElems = new DTDElement[DEFAULT_STACK_SIZE];
+ }
+
+ /*
+ ///////////////////////////////////////
+ // Configuration
+ ///////////////////////////////////////
+ */
+
+ /**
+ * Method that allows enabling/disabling attribute value normalization.
+ * In general, readers by default enable normalization (to be fully xml
+ * compliant),
+ * whereas writers do not (since there is usually little to gain, if
+ * anything -- it is even possible value may be written before validation
+ * is called in some cases)
+ */
+ public void setAttrValueNormalization(boolean state) {
+ mNormAttrs = state;
+ }
+
+ /**
+ * @return True for validator object that actually do validate
+ * content; false for objects that only use DTD type information.
+ */
+ public abstract boolean reallyValidating();
+
+ /*
+ ///////////////////////////////////////
+ // XMLValidator implementation
+ ///////////////////////////////////////
+ */
+
+ @Override
+ public final XMLValidationSchema getSchema() {
+ return mSchema;
+ }
+
+ /**
+ * Method called to update information about the newly encountered (start)
+ * element. At this point namespace information has been resolved, but
+ * no DTD validation has been done. Validator is to do these validations,
+ * including checking for attribute value (and existence) compatibility.
+ */
+ @Override
+ public abstract void validateElementStart(String localName, String uri, String prefix)
+ throws XMLStreamException;
+
+ @Override
+ public abstract String validateAttribute(String localName, String uri,
+ String prefix, String value)
+ throws XMLStreamException;
+
+ @Override
+ public abstract String validateAttribute(String localName, String uri,
+ String prefix,
+ char[] valueChars, int valueStart,
+ int valueEnd)
+ throws XMLStreamException;
+
+ @Override
+ public abstract int validateElementAndAttributes()
+ throws XMLStreamException;
+
+ /**
+ * @return Validation state that should be effective for the parent
+ * element state
+ */
+ @Override
+ public abstract int validateElementEnd(String localName, String uri, String prefix)
+ throws XMLStreamException;
+
+ @Override
+ public void validateText(String text, boolean lastTextSegment)
+ throws XMLStreamException
+ {
+ /* This method is a NOP, since basic DTD has no mechanism for
+ * validating textual content.
+ */
+ }
+
+ @Override
+ public void validateText(char[] cbuf, int textStart, int textEnd,
+ boolean lastTextSegment)
+ throws XMLStreamException
+ {
+ /* This method is a NOP, since basic DTD has no mechanism for
+ * validating textual content.
+ */
+ }
+
+ @Override
+ public abstract void validationCompleted(boolean eod)
+ throws XMLStreamException;
+
+ /*
+ ///////////////////////////////////////
+ // Attribute info access
+ ///////////////////////////////////////
+ */
+
+ // // // Access to type info
+
+ @Override
+ public String getAttributeType(int index)
+ {
+ DTDAttribute attr = mAttrSpecs[index];
+ return (attr == null) ? WstxInputProperties.UNKNOWN_ATTR_TYPE :
+ attr.getValueTypeString();
+ }
+
+ /**
+ * Method for finding out the index of the attribute (collected using
+ * the attribute collector; having DTD-derived info in same order)
+ * that is of type ID. DTD 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
+ */
+ @Override
+ public int getIdAttrIndex()
+ {
+ // Let's figure out the index only when needed
+ int ix = mIdAttrIndex;
+ if (ix == -2) {
+ ix = -1;
+ if (mCurrElem != null) {
+ DTDAttribute idAttr = mCurrElem.getIdAttribute();
+ if (idAttr != null) {
+ DTDAttribute[] attrs = mAttrSpecs;
+ for (int i = 0, len = attrs.length; i < len; ++i) {
+ if (attrs[i] == idAttr) {
+ ix = i;
+ break;
+ }
+ }
+ }
+ }
+ mIdAttrIndex = ix;
+ }
+ return ix;
+ }
+
+ /**
+ * Method for finding out the index of the attribute (collected using
+ * the attribute collector; having DTD-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
+ */
+ @Override
+ public int getNotationAttrIndex()
+ {
+ /* If necessary, we could find this index when resolving the
+ * element, could avoid linear search. But who knows how often
+ * it's really needed...
+ */
+ for (int i = 0, len = mAttrCount; i < len; ++i) {
+ if (mAttrSpecs[i].typeIsNotation()) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ /*
+ /////////////////////////////////////////////////////
+ // NsDefaultProvider interface
+ /////////////////////////////////////////////////////
+ */
+
+ /**
+ * Calling this method before {@link #checkNsDefaults} is necessary
+ * to pass information regarding the current element; although
+ * it will become available later on (via normal XMLValidator interface),
+ * that's too late (after namespace binding and resolving).
+ */
+ @Override
+ public boolean mayHaveNsDefaults(String elemPrefix, String elemLN)
+ {
+ mTmpKey.reset(elemPrefix, elemLN);
+ DTDElement elem = mElemSpecs.get(mTmpKey);
+ mCurrElem = elem;
+ return (elem != null) && elem.hasNsDefaults();
+ }
+
+ @Override
+ public void checkNsDefaults(InputElementStack nsStack)
+ throws XMLStreamException
+ {
+ // We only get called if mCurrElem != null, and has defaults
+ HashMap m = mCurrElem.getNsDefaults();
+ if (m != null) {
+ for (Map.Entry me : m.entrySet()) {
+ String prefix = me.getKey();
+ if (!nsStack.isPrefixLocallyDeclared(prefix)) {
+ DTDAttribute attr = me.getValue();
+ String uri = attr.getDefaultValue(mContext, this);
+ nsStack.addNsBinding(prefix, uri);
+ }
+ }
+ }
+ }
+
+ /*
+ ///////////////////////////////////////
+ // Package methods, accessors
+ ///////////////////////////////////////
+ */
+
+ /**
+ * Name of current element on the top of the element stack.
+ */
+ PrefixedName getElemName() {
+ DTDElement elem = mElems[mElemCount-1];
+ return elem.getName();
+ }
+
+ Location getLocation() {
+ return mContext.getValidationLocation();
+ }
+
+ protected abstract ElementIdMap getIdMap();
+
+ Map getEntityMap() {
+ return mGeneralEntities;
+ }
+
+ char[] getTempAttrValueBuffer(int neededLength)
+ {
+ if (mTmpAttrValueBuffer == null
+ || mTmpAttrValueBuffer.length < neededLength) {
+ int size = (neededLength < 100) ? 100 : neededLength;
+ mTmpAttrValueBuffer = new char[size];
+ }
+ return mTmpAttrValueBuffer;
+ }
+
+ public boolean hasNsDefaults() {
+ return mHasNsDefaults;
+ }
+
+ /*
+ ///////////////////////////////////////
+ // Package methods, error handling
+ ///////////////////////////////////////
+ */
+
+ /**
+ * Method called to report validity problems; depending on mode, will
+ * either throw an exception, or add a problem notification to the
+ * list of problems.
+ */
+ void reportValidationProblem(String msg)
+ throws XMLStreamException
+ {
+ doReportValidationProblem(msg, null);
+ }
+
+ void reportValidationProblem(String msg, Location loc)
+ throws XMLStreamException
+ {
+ doReportValidationProblem(msg, loc);
+ }
+
+ void reportValidationProblem(String format, Object arg)
+ throws XMLStreamException
+ {
+ doReportValidationProblem(MessageFormat.format(format, new Object[] { arg }),
+ null);
+ }
+
+ void reportValidationProblem(String format, Object arg1, Object arg2)
+ throws XMLStreamException
+ {
+ doReportValidationProblem(MessageFormat.format(format, new Object[] { arg1, arg2 }),
+ null);
+ }
+
+ /*
+ ///////////////////////////////////////
+ // Private/sub-class methods
+ ///////////////////////////////////////
+ */
+
+ protected void doReportValidationProblem(String msg, Location loc)
+ throws XMLStreamException
+ {
+ if (loc == null) {
+ loc = getLocation();
+ }
+ XMLValidationProblem prob = new XMLValidationProblem(loc, msg, XMLValidationProblem.SEVERITY_ERROR);
+ prob.setReporter(this);
+ mContext.reportProblem(prob);
+ }
+
+ protected void doAddDefaultValue(DTDAttribute attr)
+ throws XMLStreamException
+ {
+ /* If we get here, we should have a non-null (possibly empty) default
+ * value:
+ */
+ String def = attr.getDefaultValue(mContext, this);
+ if (def == null) {
+ ExceptionUtil.throwInternal("null default attribute value");
+ }
+ PrefixedName an = attr.getName();
+ // Ok, do we need to find the URI?
+ String prefix = an.getPrefix();
+ String uri = "";
+ if (prefix != null && prefix.length() > 0) {
+ uri = mContext.getNamespaceURI(prefix);
+ // Can not map to empty NS!
+ if (uri == null || uri.length() == 0) {
+ /* Hmmh. This is a weird case where we do have to
+ * throw a validity exception; even though it really
+ * is more a ns-well-formedness error...
+ */
+ reportValidationProblem("Unbound namespace prefix \"{0}\" for default attribute \"{1}\"", prefix, attr);
+ // May continue if we don't throw errors, just collect them to a list
+ uri = "";
+ }
+ }
+ int defIx = mContext.addDefaultAttribute(an.getLocalName(), uri, prefix, def);
+ if (defIx < 0) {
+ /* 13-Dec-2005, Tatus: Hmmh. For readers this is an error
+ * condition, but writers may just indicate they are not
+ * interested in defaults. So let's let context report
+ * problem(s) if it has any regarding the request.
+ */
+ // nop
+ } else {
+ while (defIx >= mAttrSpecs.length) {
+ mAttrSpecs = (DTDAttribute[]) DataUtil.growArrayBy50Pct(mAttrSpecs);
+ }
+ /* Any intervening empty slots? (can happen if other
+ * validators add default attributes...)
+ */
+ while (mAttrCount < defIx) {
+ mAttrSpecs[mAttrCount++] = null;
+ }
+ mAttrSpecs[defIx] = attr;
+ mAttrCount = defIx+1;
+ }
+ }
+}
diff -Nru libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/dtd/DTDValidator.java libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/dtd/DTDValidator.java
--- libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/dtd/DTDValidator.java 1970-01-01 00:00:00.000000000 +0000
+++ libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/dtd/DTDValidator.java 2018-03-31 01:33:28.000000000 +0000
@@ -0,0 +1,415 @@
+/* Woodstox XML processor
+ *
+ * Copyright (c) 2004- 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 com.ctc.wstx.dtd;
+
+import java.util.*;
+
+import javax.xml.stream.XMLStreamException;
+
+import org.codehaus.stax2.validation.*;
+
+import com.ctc.wstx.cfg.ErrorConsts;
+import com.ctc.wstx.ent.EntityDecl;
+import com.ctc.wstx.util.DataUtil;
+import com.ctc.wstx.util.ElementId;
+import com.ctc.wstx.util.ElementIdMap;
+import com.ctc.wstx.util.PrefixedName;
+import com.ctc.wstx.util.StringUtil;
+
+/**
+ * Woodstox implementation of {@link XMLValidator}; the class that
+ * handles DTD-based validation.
+ */
+public class DTDValidator
+ extends DTDValidatorBase
+{
+ /*
+ ///////////////////////////////////////
+ // Configuration
+ ///////////////////////////////////////
+ */
+
+ /**
+ * Determines if identical problems (definition of the same element,
+ * for example) should cause multiple error notifications or not:
+ * if true, will get one error per instance, if false, only the first
+ * one will get reported.
+ */
+ protected boolean mReportDuplicateErrors = false;
+
+ /*
+ ///////////////////////////////////////
+ // Id/idref state
+ ///////////////////////////////////////
+ */
+
+ /**
+ * Information about declared and referenced element ids (unique
+ * ids that attributes may defined, as defined by DTD)
+ */
+ protected ElementIdMap mIdMap = null;
+
+ /*
+ ///////////////////////////////////////////
+ // Element def/spec/validator stack, state
+ ///////////////////////////////////////////
+ */
+
+ /**
+ * Stack of validators for open elements
+ */
+ protected StructValidator[] mValidators = null;
+
+ /**
+ * Bitset used for keeping track of required and defaulted attributes
+ * for which values have been found.
+ */
+ protected BitSet mCurrSpecialAttrs = null;
+
+ boolean mCurrHasAnyFixed = false;
+
+ /*
+ ///////////////////////////////////////
+ // Temporary helper objects
+ ///////////////////////////////////////
+ */
+
+ /**
+ * Reusable lazily instantiated BitSet; needed to keep track of
+ * missing 'special' attributes (required ones, ones with default
+ * values)
+ */
+ BitSet mTmpSpecialAttrs;
+
+ /*
+ ///////////////////////////////////////
+ // Life-cycle
+ ///////////////////////////////////////
+ */
+
+ public DTDValidator(DTDSubset schema, ValidationContext ctxt, boolean hasNsDefaults,
+ Map elemSpecs, Map genEntities)
+ {
+ super(schema, ctxt, hasNsDefaults, elemSpecs, genEntities);
+ mValidators = new StructValidator[DEFAULT_STACK_SIZE];
+ }
+
+ @Override
+ public final boolean reallyValidating() { return true; }
+
+ /*
+ ///////////////////////////////////////
+ // XMLValidator implementation
+ ///////////////////////////////////////
+ */
+
+ //public XMLValidationSchema getSchema();
+
+ /**
+ * Method called to update information about the newly encountered (start)
+ * element. At this point namespace information has been resolved, but
+ * no DTD validation has been done. Validator is to do these validations,
+ * including checking for attribute value (and existence) compatibility.
+ */
+ @Override
+ public void validateElementStart(String localName, String uri, String prefix)
+ throws XMLStreamException
+ {
+ /* Ok, need to find the element definition; if not found (or
+ * only implicitly defined), need to throw the exception.
+ */
+ mTmpKey.reset(prefix, localName);
+
+ DTDElement elem = mElemSpecs.get(mTmpKey);
+
+ /* Let's add the entry in (even if it's a null); this is necessary
+ * to keep things in-sync if allowing graceful handling of validity
+ * errors
+ */
+ int elemCount = mElemCount++;
+ if (elemCount >= mElems.length) {
+ mElems = (DTDElement[]) DataUtil.growArrayBy50Pct(mElems);
+ mValidators = (StructValidator[]) DataUtil.growArrayBy50Pct(mValidators);
+ }
+ mElems[elemCount] = mCurrElem = elem;
+ if (elem == null || !elem.isDefined()) {
+ reportValidationProblem(ErrorConsts.ERR_VLD_UNKNOWN_ELEM, mTmpKey.toString());
+ }
+
+ // Is this element legal under the parent element?
+ StructValidator pv = (elemCount > 0) ? mValidators[elemCount-1] : null;
+
+ if (pv != null && elem != null) {
+ String msg = pv.tryToValidate(elem.getName());
+ if (msg != null) {
+ int ix = msg.indexOf("$END");
+ String pname = mElems[elemCount-1].toString();
+ if (ix >= 0) {
+ msg = msg.substring(0, ix) + ""+pname+">"
+ +msg.substring(ix+4);
+ }
+ reportValidationProblem("Validation error, encountered element <"
+ +elem.getName()+"> as a child of <"
+ +pname+">: "+msg);
+ }
+ }
+
+ mAttrCount = 0;
+ mIdAttrIndex = -2; // -2 as a "don't know yet" marker
+
+ // Ok, need to get the child validator, then:
+ if (elem == null) {
+ mValidators[elemCount] = null;
+ mCurrAttrDefs = NO_ATTRS;
+ mCurrHasAnyFixed = false;
+ mCurrSpecialAttrs = null;
+ } else {
+ mValidators[elemCount] = elem.getValidator();
+ mCurrAttrDefs = elem.getAttributes();
+ if (mCurrAttrDefs == null) {
+ mCurrAttrDefs = NO_ATTRS;
+ }
+ mCurrHasAnyFixed = elem.hasFixedAttrs();
+ int specCount = elem.getSpecialCount();
+ if (specCount == 0) {
+ mCurrSpecialAttrs = null;
+ } else {
+ BitSet bs = mTmpSpecialAttrs;
+ if (bs == null) {
+ mTmpSpecialAttrs = bs = new BitSet(specCount);
+ } else {
+ bs.clear();
+ }
+ mCurrSpecialAttrs = bs;
+ }
+ }
+ }
+
+ @Override
+ public String validateAttribute(String localName, String uri,
+ String prefix, String value)
+ throws XMLStreamException
+ {
+ DTDAttribute attr = mCurrAttrDefs.get(mTmpKey.reset(prefix, localName));
+ if (attr == null) {
+ // Only report error if not already recovering from an error:
+ if (mCurrElem != null) {
+ reportValidationProblem(ErrorConsts.ERR_VLD_UNKNOWN_ATTR,
+ mCurrElem.toString(), mTmpKey.toString());
+ }
+ /* [WSTX-190] NPE if we continued (after reported didn't
+ * throw an exception); nothing more to do, let's leave
+ */
+ return value;
+ }
+ int index = mAttrCount++;
+ if (index >= mAttrSpecs.length) {
+ mAttrSpecs = (DTDAttribute[]) DataUtil.growArrayBy50Pct(mAttrSpecs);
+ }
+ mAttrSpecs[index] = attr;
+ if (mCurrSpecialAttrs != null) { // Need to mark that we got it
+ int specIndex = attr.getSpecialIndex();
+ if (specIndex >= 0) {
+ mCurrSpecialAttrs.set(specIndex);
+ }
+ }
+ String result = attr.validate(this, value, mNormAttrs);
+ if (mCurrHasAnyFixed && attr.isFixed()) {
+ String act = (result == null) ? value : result;
+ String exp = attr.getDefaultValue(mContext, this);
+ if (!act.equals(exp)) {
+ reportValidationProblem("Value of attribute \""+attr+"\" (element <"+mCurrElem+">) not \""+exp+"\" as expected, but \""+act+"\"");
+ }
+ }
+ return result;
+ }
+
+ @Override
+ public String validateAttribute(String localName, String uri,
+ String prefix,
+ char[] valueChars, int valueStart,
+ int valueEnd)
+ throws XMLStreamException
+ {
+ DTDAttribute attr = mCurrAttrDefs.get(mTmpKey.reset(prefix, localName));
+ if (attr == null) {
+ // Only report error if not already covering from an error:
+ if (mCurrElem != null) {
+ reportValidationProblem(ErrorConsts.ERR_VLD_UNKNOWN_ATTR,
+ mCurrElem.toString(), mTmpKey.toString());
+ }
+ /* [WSTX-190] NPE if we continued (after reported didn't
+ * throw an exception); nothing more to do, let's leave
+ */
+ return new String(valueChars, valueStart, valueEnd);
+ }
+ int index = mAttrCount++;
+ if (index >= mAttrSpecs.length) {
+ mAttrSpecs = (DTDAttribute[]) DataUtil.growArrayBy50Pct(mAttrSpecs);
+ }
+ mAttrSpecs[index] = attr;
+ if (mCurrSpecialAttrs != null) { // Need to mark that we got it
+ int specIndex = attr.getSpecialIndex();
+ if (specIndex >= 0) {
+ mCurrSpecialAttrs.set(specIndex);
+ }
+ }
+ String result = attr.validate(this, valueChars, valueStart, valueEnd, mNormAttrs);
+ if (mCurrHasAnyFixed && attr.isFixed()) {
+ String exp = attr.getDefaultValue(mContext, this);
+ boolean match;
+ if (result == null) {
+ match = StringUtil.matches(exp, valueChars, valueStart, valueEnd - valueStart);
+ } else {
+ match = exp.equals(result);
+ }
+ if (!match) {
+ String act = (result == null) ?
+ new String(valueChars, valueStart, valueEnd) : result;
+ reportValidationProblem("Value of #FIXED attribute \""+attr+"\" (element <"+mCurrElem+">) not \""+exp+"\" as expected, but \""+act+"\"");
+ }
+ }
+ return result;
+ }
+
+ @Override
+ public int validateElementAndAttributes()
+ throws XMLStreamException
+ {
+ // Ok: are we fine with the attributes?
+ DTDElement elem = mCurrElem;
+ if (elem == null) { // had an error, most likely no such element defined...
+ // need to just return, nothing to do here
+ return XMLValidator.CONTENT_ALLOW_ANY_TEXT;
+ }
+
+ // Any special attributes missing?
+ if (mCurrSpecialAttrs != null) {
+ BitSet specBits = mCurrSpecialAttrs;
+ int specCount = elem.getSpecialCount();
+ int ix = specBits.nextClearBit(0);
+ while (ix < specCount) { // something amiss!
+ List specAttrs = elem.getSpecialAttrs();
+ DTDAttribute attr = specAttrs.get(ix);
+
+ /* [WSTX-155]: Problems if reportValidationProblem returns
+ * ok (which happens if a reporter handles it). So what
+ * to do with missing required value? First thought is
+ * to just leave it as is.
+ */
+ if (attr.isRequired()) {
+ reportValidationProblem("Required attribute \"{0}\" missing from element <{1}>", attr, elem);
+ } else {
+ doAddDefaultValue(attr);
+ }
+ ix = specBits.nextClearBit(ix+1);
+ }
+ }
+
+ return elem.getAllowedContent();
+ }
+
+ /**
+ * @return Validation state that should be effective for the parent
+ * element state
+ */
+ @Override
+ public int validateElementEnd(String localName, String uri, String prefix)
+ throws XMLStreamException
+ {
+ // First, let's remove the top:
+ int ix = mElemCount-1;
+ /* [WSTX-200]: need to avoid problems when doing sub-tree
+ * validation...
+ */
+ if (ix < 0) {
+ return XMLValidator.CONTENT_ALLOW_WS;
+ }
+ mElemCount = ix;
+
+ DTDElement closingElem = mElems[ix];
+ mElems[ix] = null;
+ StructValidator v = mValidators[ix];
+ mValidators[ix] = null;
+
+ // Validation?
+ if (v != null) {
+ String msg = v.fullyValid();
+ if (msg != null) {
+ reportValidationProblem("Validation error, element "
+ +closingElem+">: "+msg);
+ }
+ }
+
+ // Then let's get info from parent, if any
+ if (ix < 1) { // root element closing..
+ // doesn't really matter; epilog/prolog differently handled:
+ return XMLValidator.CONTENT_ALLOW_WS;
+ }
+ return mElems[ix-1].getAllowedContent();
+ }
+
+ //public void validateText(String text, boolean lastTextSegment) ;
+ //public void validateText(char[] cbuf, int textStart, int textEnd, boolean lastTextSegment) ;
+
+ @Override
+ public void validationCompleted(boolean eod) throws XMLStreamException
+ {
+ /* Need to now ensure that all IDREF/IDREFS references
+ * point to defined ID attributes
+ */
+ checkIdRefs();
+ }
+
+ /*
+ ///////////////////////////////////////
+ // Package methods, accessors
+ ///////////////////////////////////////
+ */
+
+ @Override
+ protected ElementIdMap getIdMap() {
+ if (mIdMap == null) {
+ mIdMap = new ElementIdMap();
+ }
+ return mIdMap;
+ }
+
+ /*
+ ///////////////////////////////////////
+ // Internal methods
+ ///////////////////////////////////////
+ */
+
+ protected void checkIdRefs()
+ throws XMLStreamException
+ {
+ /* 02-Oct-2004, TSa: Now we can also check that all id references
+ * pointed to ids that actually are defined
+ */
+ if (mIdMap != null) {
+ ElementId ref = mIdMap.getFirstUndefined();
+ if (ref != null) { // problem!
+ reportValidationProblem("Undefined id '"+ref.getId()
+ +"': referenced from element <"
+ +ref.getElemName()+">, attribute '"
+ +ref.getAttrName()+"'",
+ ref.getLocation());
+ }
+ }
+ }
+
+}
diff -Nru libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/dtd/DTDWriter.java libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/dtd/DTDWriter.java
--- libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/dtd/DTDWriter.java 1970-01-01 00:00:00.000000000 +0000
+++ libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/dtd/DTDWriter.java 2018-03-31 01:33:28.000000000 +0000
@@ -0,0 +1,164 @@
+package com.ctc.wstx.dtd;
+
+import java.io.IOException;
+import java.io.Writer;
+
+import javax.xml.stream.XMLStreamException;
+
+import com.ctc.wstx.exc.WstxIOException;
+
+/**
+ * Simple utility class used by {@link DTDReader} when writing out
+ * flattened external DTD subset file. Writing functionality encapsulated
+ * here since it's specific to one mode of operation (flattening).
+ *
+ * Note, too, that underlying {@link IOException}s are generally wrapped
+ * as {@link XMLStreamException}s. This is needed to reduce amount of
+ * work caller has to do for wrapping. It will still be possible to
+ * unwrap these exceptions further up the call stack if need be.
+ */
+final class DTDWriter
+{
+ /*
+ //////////////////////////////////////////////////
+ // Configuration
+ //////////////////////////////////////////////////
+ */
+
+ final Writer mWriter;
+
+ final boolean mIncludeComments;
+
+ final boolean mIncludeConditionals;
+
+ final boolean mIncludePEs;
+
+ /*
+ //////////////////////////////////////////////////
+ // Output status
+ //////////////////////////////////////////////////
+ */
+
+ /**
+ * Counter that indicates whether flattened output should be written to
+ * (non-null) mWriter; values above zero indicate output is enabled,
+ * zero and below that output is disabled.
+ * Only enabled if mWriter is not
+ * null; will be temporarily disabled during processing of content
+ * that is not to be included (PE reference; or comments / conditional
+ * sections if comment/cs output is suppressed)
+ */
+ int mIsFlattening = 0;
+
+ /**
+ * Pointer to first character in the current input buffer that
+ * has not yet been written to flatten writer.
+ */
+ int mFlattenStart = 0;
+
+ /*
+ //////////////////////////////////////////////////
+ // Life-cycle
+ //////////////////////////////////////////////////
+ */
+
+ public DTDWriter(Writer out, boolean inclComments, boolean inclCond,
+ boolean inclPEs)
+ {
+ mWriter = out;
+ mIncludeComments = inclComments;
+ mIncludeConditionals = inclCond;
+ mIncludePEs = inclPEs;
+
+ mIsFlattening = 1; // starts enabled
+ }
+
+ /*
+ //////////////////////////////////////////////////
+ // Public API, accessors, state change
+ //////////////////////////////////////////////////
+ */
+
+ public boolean includeComments() {
+ return mIncludeComments;
+ }
+
+ public boolean includeConditionals() {
+ return mIncludeConditionals;
+ }
+
+ public boolean includeParamEntities() {
+ return mIncludePEs;
+ }
+
+ public void disableOutput()
+ {
+ --mIsFlattening;
+ }
+
+ public void enableOutput(int newStart)
+ {
+ ++mIsFlattening;
+ mFlattenStart = newStart;
+ }
+
+ public void setFlattenStart(int ptr) {
+ mFlattenStart = ptr;
+ }
+
+ public int getFlattenStart() {
+ return mFlattenStart;
+ }
+
+ /*
+ //////////////////////////////////////////////////
+ // Public API, output methods:
+ //////////////////////////////////////////////////
+ */
+
+ public void flush(char[] buf, int upUntil)
+ throws XMLStreamException
+ {
+ if (mFlattenStart < upUntil) {
+ if (mIsFlattening > 0) {
+ try {
+ mWriter.write(buf, mFlattenStart, upUntil - mFlattenStart);
+ } catch (IOException ioe) {
+ throw new WstxIOException(ioe);
+ }
+ }
+ mFlattenStart = upUntil;
+ }
+ }
+
+ /**
+ * Method called when explicit output has to be done for flatten output:
+ * this is usually done when there's need to do speculative checks
+ * before it's known if some chars are output (when suppressing comments
+ * or conditional sections)
+ */
+ public void output(String output)
+ throws XMLStreamException
+ {
+ if (mIsFlattening > 0) {
+ try {
+ mWriter.write(output);
+ } catch (IOException ioe) {
+ throw new WstxIOException(ioe);
+ }
+ }
+ }
+
+ public void output(char c)
+ throws XMLStreamException
+ {
+ if (mIsFlattening > 0) {
+ try {
+ mWriter.write(c);
+ } catch (IOException ioe) {
+ throw new WstxIOException(ioe);
+ }
+ }
+ }
+}
+
diff -Nru libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/dtd/EmptyValidator.java libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/dtd/EmptyValidator.java
--- libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/dtd/EmptyValidator.java 1970-01-01 00:00:00.000000000 +0000
+++ libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/dtd/EmptyValidator.java 2018-03-31 01:33:28.000000000 +0000
@@ -0,0 +1,49 @@
+package com.ctc.wstx.dtd;
+
+import com.ctc.wstx.util.PrefixedName;
+
+/**
+ * Simple content model validator that accepts no elements, ever; this
+ * is true for pure #PCDATA content model as well as EMPTY content model.
+ * Can be used as a singleton, since all info needed for diagnostics
+ * is passed via methods.
+ */
+public class EmptyValidator
+ extends StructValidator
+{
+ final static EmptyValidator sPcdataInstance = new EmptyValidator("No elements allowed in pure #PCDATA content model");
+
+ final static EmptyValidator sEmptyInstance = new EmptyValidator("No elements allowed in EMPTY content model");
+
+ final String mErrorMsg;
+
+ private EmptyValidator(String errorMsg) {
+ mErrorMsg = errorMsg;
+ }
+
+ public static EmptyValidator getPcdataInstance() { return sPcdataInstance; }
+ public static EmptyValidator getEmptyInstance() { return sPcdataInstance; }
+
+ /**
+ * Simple; can always (re)use instance itself; no state information
+ * is kept.
+ */
+ @Override
+ public StructValidator newInstance() {
+ return this;
+ }
+
+ @Override
+ public String tryToValidate(PrefixedName elemName) {
+ return mErrorMsg;
+ }
+
+ /**
+ * If we ever get as far as element closing, things are all good;
+ * can just return null.
+ */
+ @Override
+ public String fullyValid() {
+ return null;
+ }
+}
diff -Nru libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/dtd/FullDTDReader.java libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/dtd/FullDTDReader.java
--- libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/dtd/FullDTDReader.java 1970-01-01 00:00:00.000000000 +0000
+++ libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/dtd/FullDTDReader.java 2018-03-31 01:33:28.000000000 +0000
@@ -0,0 +1,3520 @@
+/* Woodstox XML processor
+ *
+ * Copyright (c) 2004- 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 com.ctc.wstx.dtd;
+
+import java.io.IOException;
+import java.io.Writer;
+import java.net.URL;
+import java.text.MessageFormat;
+import java.util.*;
+
+import javax.xml.stream.Location;
+import javax.xml.stream.XMLReporter;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.events.NotationDeclaration;
+
+import org.codehaus.stax2.validation.XMLValidationProblem;
+import org.codehaus.stax2.validation.XMLValidator;
+
+import com.ctc.wstx.api.ReaderConfig;
+import com.ctc.wstx.cfg.ErrorConsts;
+import com.ctc.wstx.cfg.XmlConsts;
+import com.ctc.wstx.ent.*;
+import com.ctc.wstx.evt.WNotationDeclaration;
+import com.ctc.wstx.exc.WstxIOException;
+import com.ctc.wstx.io.WstxInputData;
+import com.ctc.wstx.io.WstxInputSource;
+import com.ctc.wstx.util.*;
+
+/**
+ * Reader that reads in DTD information from internal or external subset.
+ *
+ * There are 2 main modes for DTDReader, depending on whether it is parsing
+ * internal or external subset. Parsing of internal subset is somewhat
+ * simpler, since no dependency checking is needed. For external subset,
+ * handling of parameter entities is bit more complicated, as care has to
+ * be taken to distinguish between using PEs defined in int. subset, and
+ * ones defined in ext. subset itself. This determines cachability of
+ * external subsets.
+ *
+ * Reader also implements simple stand-alone functionality for flattening
+ * DTD files (expanding all references to their eventual textual form);
+ * this is sometimes useful when optimizing modularized DTDs
+ * (which are more maintainable) into single monolithic DTDs (which in
+ * general can be more performant).
+ *
+ * @author Tatu Saloranta
+ */
+public class FullDTDReader
+ extends MinimalDTDReader
+{
+ /**
+ * Flag that can be changed to enable or disable interning of shared
+ * names; shared names are used for enumerated values to reduce
+ * memory usage.
+ */
+ final static boolean INTERN_SHARED_NAMES = false;
+
+ // // // Entity expansion types:
+
+ final static Boolean ENTITY_EXP_GE = Boolean.FALSE;
+
+ final static Boolean ENTITY_EXP_PE = Boolean.TRUE;
+
+ /*
+ ///////////////////////////////////////////////////////////
+ // Configuration
+ ///////////////////////////////////////////////////////////
+ */
+
+ final int mConfigFlags;
+
+ // Extracted wstx-specific settings:
+
+ final boolean mCfgSupportDTDPP;
+
+ /**
+ * This flag indicates whether we should build a validating 'real'
+ * validator (true, the usual case),
+ * or a simpler pseudo-validator that can do all non-validation tasks
+ * that are based on DTD info (entity expansion, notation references,
+ * default attribute values). Latter is used in non-validating mode.
+ *
+ */
+ final boolean mCfgFullyValidating;
+
+ /*
+ ///////////////////////////////////////////////////////////
+ // Entity handling, parameter entities (PEs)
+ ///////////////////////////////////////////////////////////
+ */
+
+ /**
+ * Set of parameter entities defined so far in the currently parsed
+ * subset. Note: the first definition sticks, entities can not be
+ * redefined.
+ *
+ * Keys are entity name Strings; values are instances of EntityDecl
+ */
+ HashMap mParamEntities;
+
+ /**
+ * Set of parameter entities already defined for the subset being
+ * parsed; namely, PEs defined in the internal subset passed when
+ * parsing matching external subset. Null when parsing internal
+ * subset.
+ */
+ final HashMap mPredefdPEs;
+
+ /**
+ * Set of parameter entities (ids) that have been referenced by this
+ * DTD; only maintained for external subsets, and only as long as
+ * no pre-defined PE has been referenced.
+ */
+ Set mRefdPEs;
+
+ /*
+ ///////////////////////////////////////////////////////////
+ // Entity handling, general entities (GEs)
+ ///////////////////////////////////////////////////////////
+ */
+
+ /**
+ * Set of generic entities defined so far in this subset.
+ * As with parameter entities, the first definition sticks.
+ *
+ * Keys are entity name Strings; values are instances of EntityDecl
+ *
+ * Note: this Map only contains entities declared and defined in the
+ * subset being parsed; no previously defined values are passed.
+ */
+ HashMap mGeneralEntities;
+
+ /**
+ * Set of general entities already defined for the subset being
+ * parsed; namely, PEs defined in the internal subset passed when
+ * parsing matching external subset. Null when parsing internal
+ * subset. Such entities are only needed directly for one purpose;
+ * to be expanded when reading attribute default value definitions.
+ */
+ final HashMap mPredefdGEs;
+
+ /**
+ * Set of general entities (ids) that have been referenced by this
+ * DTD; only maintained for external subsets, and only as long as
+ * no pre-defined GEs have been referenced.
+ */
+ Set mRefdGEs;
+
+ /*
+ ///////////////////////////////////////////////////////////
+ // Entity handling, both PEs and GEs
+ ///////////////////////////////////////////////////////////
+ */
+
+ /**
+ * Flag used to keep track of whether current (external) subset
+ * has referenced at least one PE that was pre-defined.
+ */
+ boolean mUsesPredefdEntities = false;
+
+ /*
+ ///////////////////////////////////////////////////////////
+ // Notation settings
+ ///////////////////////////////////////////////////////////
+ */
+
+ /**
+ * Set of notations defined so far. Since it's illegal to (try to)
+ * redefine notations, there's no specific precedence.
+ *
+ * Keys are entity name Strings; values are instances of
+ * NotationDecl objects
+ */
+ HashMap mNotations;
+
+ /**
+ * Notations already parsed before current subset; that is,
+ * notations from the internal subset if we are currently
+ * parsing matching external subset.
+ */
+ final HashMap mPredefdNotations;
+
+ /**
+ * Flag used to keep track of whether current (external) subset
+ * has referenced at least one notation that was defined in internal
+ * subset. If so, can not cache the external subset
+ */
+ boolean mUsesPredefdNotations = false;
+
+ /**
+ * Finally, we need to keep track of Notation references that were
+ * made prior to declaration. This is needed to ensure that all
+ * references can be properly resolved.
+ */
+ HashMap mNotationForwardRefs;
+
+ /*
+ ///////////////////////////////////////////////////////////
+ // Element specifications
+ ///////////////////////////////////////////////////////////
+ */
+
+ /**
+ * Map used to shared PrefixedName instances, to reduce memory usage
+ * of (qualified) element and attribute names
+ */
+ HashMap mSharedNames = null;
+
+ /**
+ * Contains definition of elements and matching content specifications.
+ * Also contains temporary placeholders for elements that are indirectly
+ * "created" by ATTLIST declarations that precede actual declaration
+ * for the ELEMENT referred to.
+ */
+ LinkedHashMap mElements;
+
+ /**
+ * Map used for sharing legal enumeration values; used since oftentimes
+ * same enumeration values are used with multiple attributes
+ */
+ HashMap mSharedEnumValues = null;
+
+ /*
+ ///////////////////////////////////////////////////////////
+ // Entity expansion state
+ ///////////////////////////////////////////////////////////
+ */
+
+ /**
+ * This is the attribute default value that is currently being parsed.
+ * Needs to be a global member due to the way entity expansion failures
+ * are reported: problems need to be attached to this object, even
+ * thought the default value itself will not be passed through.
+ */
+ DefaultAttrValue mCurrAttrDefault = null;
+
+ /**
+ * Flag that indicates if the currently expanding (or last expanded)
+ * entity is a Parameter Entity or General Entity.
+ */
+ boolean mExpandingPE = false;
+
+ /**
+ * Text buffer used for constructing expansion value of the internal
+ * entities, and for default attribute values.
+ * Lazily constructed when needed, reused.
+ */
+ TextBuffer mValueBuffer = null;
+
+ /*
+ ///////////////////////////////////////////////////////////
+ // Reader state
+ ///////////////////////////////////////////////////////////
+ */
+
+ /**
+ * Nesting count for conditionally included sections; 0 means that
+ * we are not inside such a section. Note that condition ignore is
+ * handled separately.
+ */
+ int mIncludeCount = 0;
+
+ /**
+ * This flag is used to catch uses of PEs in the internal subset
+ * within declarations (full declarations are ok, but not other types)
+ */
+ boolean mCheckForbiddenPEs = false;
+
+ /**
+ * Keyword of the declaration being currently parsed (if any). Can be
+ * used for error reporting purposes.
+ */
+ String mCurrDeclaration;
+
+ /*
+ ///////////////////////////////////////////////////////////
+ // DTD++ support information
+ ///////////////////////////////////////////////////////////
+ */
+
+ /**
+ * Flag that indicates if any DTD++ features have been encountered
+ * (in DTD++-supporting mode).
+ */
+ boolean mAnyDTDppFeatures = false;
+
+ /**
+ * Currently active default namespace URI.
+ */
+ String mDefaultNsURI = "";
+
+ /**
+ * Prefix-to-NsURI mappings for this DTD, if any: lazily
+ * constructed when needed
+ */
+ HashMap mNamespaces = null;
+
+ /*
+ ///////////////////////////////////////////////////////////
+ // Additional support for creating expanded output
+ // of processed DTD.
+ ///////////////////////////////////////////////////////////
+ */
+
+ DTDWriter mFlattenWriter = null;
+
+ /*
+ ///////////////////////////////////////////////////////////
+ // Support for SAX API impl:
+ ///////////////////////////////////////////////////////////
+ */
+
+ final DTDEventListener mEventListener;
+
+ transient TextBuffer mTextBuffer = null;
+
+ /*
+ ///////////////////////////////////////////////////////////
+ // Life-cycle
+ ///////////////////////////////////////////////////////////
+ */
+
+ /**
+ * Constructor used for reading/skipping internal subset.
+ */
+ private FullDTDReader(WstxInputSource input, ReaderConfig cfg,
+ boolean constructFully, int xmlVersion)
+ {
+ this(input, cfg, false, null, constructFully, xmlVersion);
+ }
+
+ /**
+ * Constructor used for reading external subset.
+ */
+ private FullDTDReader(WstxInputSource input, ReaderConfig cfg,
+ DTDSubset intSubset,
+ boolean constructFully, int xmlVersion)
+ {
+ this(input, cfg, true, intSubset, constructFully, xmlVersion);
+
+ // Let's make sure line/col offsets are correct...
+ input.initInputLocation(this, mCurrDepth, 0);
+ }
+
+ /**
+ * Common initialization part of int/ext subset constructors.
+ */
+ private FullDTDReader(WstxInputSource input, ReaderConfig cfg,
+ boolean isExt, DTDSubset intSubset,
+ boolean constructFully, int xmlVersion)
+ {
+ super(input, cfg, isExt);
+ /* What matters here is what the main xml doc had; that determines
+ * xml conformance level to use.
+ */
+ mDocXmlVersion = xmlVersion;
+ mXml11 = cfg.isXml11();
+ int cfgFlags = cfg.getConfigFlags();
+ mConfigFlags = cfgFlags;
+ mCfgSupportDTDPP = (cfgFlags & CFG_SUPPORT_DTDPP) != 0;
+ mCfgFullyValidating = constructFully;
+
+ mUsesPredefdEntities = false;
+ mParamEntities = null;
+ mRefdPEs = null;
+ mRefdGEs = null;
+ mGeneralEntities = null;
+
+ // Did we get any existing parameter entities?
+ HashMap pes = (intSubset == null) ?
+ null : intSubset.getParameterEntityMap();
+ if (pes == null || pes.isEmpty()) {
+ mPredefdPEs = null;
+ } else {
+ mPredefdPEs = pes;
+ }
+
+ // How about general entities (needed only for attr. def. values)
+ HashMap ges = (intSubset == null) ?
+ null : intSubset.getGeneralEntityMap();
+ if (ges == null || ges.isEmpty()) {
+ mPredefdGEs = null;
+ } else {
+ mPredefdGEs = ges;
+ }
+
+ // And finally, notations
+ HashMap not = (intSubset == null) ?
+ null : intSubset.getNotationMap();
+ if (not == null || not.isEmpty()) {
+ mPredefdNotations = null;
+ } else {
+ mPredefdNotations = not;
+ }
+ mEventListener = mConfig.getDTDEventListener();
+ }
+
+ /**
+ * Method called to read in the internal subset definition.
+ */
+ public static DTDSubset readInternalSubset(WstxInputData srcData,
+ WstxInputSource input,
+ ReaderConfig cfg,
+ boolean constructFully,
+ int xmlVersion)
+ throws XMLStreamException
+ {
+ FullDTDReader r = new FullDTDReader(input, cfg, constructFully, xmlVersion);
+ // Need to read using the same low-level reader interface:
+ r.copyBufferStateFrom(srcData);
+ DTDSubset ss;
+
+ try {
+ ss = r.parseDTD();
+ } finally {
+ /* And then need to restore changes back to owner (line nrs etc);
+ * effectively means that we'll stop reading external DTD subset,
+ * if so.
+ */
+ srcData.copyBufferStateFrom(r);
+ }
+ return ss;
+ }
+
+ /**
+ * Method called to read in the external subset definition.
+ */
+ public static DTDSubset readExternalSubset
+ (WstxInputSource src, ReaderConfig cfg, DTDSubset intSubset,
+ boolean constructFully, int xmlVersion)
+ throws XMLStreamException
+ {
+ FullDTDReader r = new FullDTDReader(src, cfg, intSubset, constructFully, xmlVersion);
+ return r.parseDTD();
+ }
+
+ /**
+ * Method that will parse, process and output contents of an external
+ * DTD subset. It will do processing similar to
+ * {@link #readExternalSubset}, but additionally will copy its processed
+ * ("flattened") input to specified writer.
+ *
+ * @param src Input source used to read the main external subset
+ * @param flattenWriter Writer to output processed DTD content to
+ * @param inclComments If true, will pass comments to the writer; if false,
+ * will strip comments out
+ * @param inclConditionals If true, will include conditional block markers,
+ * as well as intervening content; if false, will strip out both markers
+ * and ignorable sections.
+ * @param inclPEs If true, will output parameter entity declarations; if
+ * false will parse and use them, but not output.
+ */
+ public static DTDSubset flattenExternalSubset(WstxInputSource src, Writer flattenWriter,
+ boolean inclComments, boolean inclConditionals,
+ boolean inclPEs)
+ throws IOException, XMLStreamException
+ {
+ ReaderConfig cfg = ReaderConfig.createFullDefaults();
+ // Need to create a non-shared copy to populate symbol table field
+ cfg = cfg.createNonShared(new SymbolTable());
+
+ /* Let's assume xml 1.0... can be taken as an arg later on, if we
+ * truly care.
+ */
+ FullDTDReader r = new FullDTDReader(src, cfg, null, true, XmlConsts.XML_V_UNKNOWN);
+ r.setFlattenWriter(flattenWriter, inclComments, inclConditionals,
+ inclPEs);
+ DTDSubset ss = r.parseDTD();
+ r.flushFlattenWriter();
+ flattenWriter.flush();
+ return ss;
+ }
+
+ private TextBuffer getTextBuffer()
+ {
+ if (mTextBuffer == null) {
+ mTextBuffer = TextBuffer.createTemporaryBuffer();
+ mTextBuffer.resetInitialized();
+ } else {
+ mTextBuffer.resetWithEmpty();
+ }
+ return mTextBuffer;
+ }
+
+ /*
+ ///////////////////////////////////////////////////////////
+ // Configuration
+ ///////////////////////////////////////////////////////////
+ */
+
+ /**
+ * Method that will set specified Writer as the 'flattening writer';
+ * writer used to output flattened version of DTD read in. This is
+ * similar to running a C-preprocessor on C-sources, except that
+ * defining writer will not prevent normal parsing of DTD itself.
+ */
+ public void setFlattenWriter(Writer w, boolean inclComments,
+ boolean inclConditionals, boolean inclPEs)
+ {
+ mFlattenWriter = new DTDWriter(w, inclComments, inclConditionals,
+ inclPEs);
+ }
+
+ private void flushFlattenWriter() throws XMLStreamException {
+ mFlattenWriter.flush(mInputBuffer, mInputPtr);
+ }
+
+ /*
+ ///////////////////////////////////////////////////////////
+ // Internal API
+ ///////////////////////////////////////////////////////////
+ */
+
+ /**
+ * Method that may need to be called by attribute default value
+ * validation code, during parsing....
+ *
+ * Note: see base class for some additional remarks about this
+ * method.
+ */
+ @Override
+ public EntityDecl findEntity(String entName)
+ {
+ if (mPredefdGEs != null) {
+ EntityDecl decl = mPredefdGEs.get(entName);
+ if (decl != null) {
+ return decl;
+ }
+ }
+ return mGeneralEntities.get(entName);
+ }
+
+ /*
+ ///////////////////////////////////////////////////////////
+ // Main-level parsing methods
+ ///////////////////////////////////////////////////////////
+ */
+
+ protected DTDSubset parseDTD()
+ throws XMLStreamException
+ {
+ while (true) {
+ mCheckForbiddenPEs = false; // PEs are ok at this point
+ int i = getNextAfterWS();
+ if (i < 0) {
+ if (mIsExternal) { // ok for external DTDs
+ break;
+ }
+ // Error for internal subset
+ throwUnexpectedEOF(SUFFIX_IN_DTD_INTERNAL);
+ }
+ if (i == '%') { // parameter entity
+ expandPE();
+ continue;
+ }
+
+ /* First, let's keep track of start of the directive; needed for
+ * entity and notation declaration events.
+ */
+ mTokenInputTotal = mCurrInputProcessed + mInputPtr;
+ mTokenInputRow = mCurrInputRow;
+ mTokenInputCol = mInputPtr - mCurrInputRowStart;
+
+ if (i == '<') {
+ // PEs not allowed within declarations, in the internal subset proper
+ mCheckForbiddenPEs = !mIsExternal && (mInput == mRootInput);
+ if (mFlattenWriter == null) {
+ parseDirective();
+ } else {
+ parseDirectiveFlattened();
+ }
+ continue;
+ }
+
+ if (i == ']') {
+ if (mIncludeCount == 0 && !mIsExternal) { // End of internal subset
+ break;
+ }
+ if (mIncludeCount > 0) { // active INCLUDE block(s) open?
+ boolean suppress = (mFlattenWriter != null) && !mFlattenWriter.includeConditionals();
+
+ if (suppress) {
+ mFlattenWriter.flush(mInputBuffer, mInputPtr-1);
+ mFlattenWriter.disableOutput();
+ }
+
+ try {
+ // ]]> needs to be a token, can not come from PE:
+ char c = dtdNextFromCurr();
+ if (c == ']') {
+ c = dtdNextFromCurr();
+ if (c == '>') {
+ // Ok, fine, conditional include section ended.
+ --mIncludeCount;
+ continue;
+ }
+ }
+ throwDTDUnexpectedChar(c, "; expected ']]>' to close conditional include section");
+ } finally {
+ if (suppress) {
+ mFlattenWriter.enableOutput(mInputPtr);
+ }
+ }
+ }
+ // otherwise will fall through, and give an error
+ }
+
+ if (mIsExternal) {
+ throwDTDUnexpectedChar(i, "; expected a '<' to start a directive");
+ }
+ throwDTDUnexpectedChar(i, "; expected a '<' to start a directive, or \"]>\" to end internal subset");
+ }
+
+ /* 05-Feb-2006, TSa: Not allowed to have unclosed INCLUDE/IGNORE
+ * blocks...
+ */
+ if (mIncludeCount > 0) { // active INCLUDE block(s) open?
+ String suffix = (mIncludeCount == 1) ? "an INCLUDE block" : (""+mIncludeCount+" INCLUDE blocks");
+ throwUnexpectedEOF(getErrorMsg()+"; expected closing marker for "+suffix);
+ }
+
+ /* First check: have all notation references been resolved?
+ * (related to [WSTX-121])
+ */
+ if (mNotationForwardRefs != null && mNotationForwardRefs.size() > 0) {
+ _reportUndefinedNotationRefs();
+ }
+
+ // Ok; time to construct and return DTD data object.
+ DTDSubset ss;
+
+ // There are more settings for ext. subsets:
+ if (mIsExternal) {
+ /* External subsets are cachable if they did not refer to any
+ * PEs or GEs defined in internal subset passed in (if any),
+ * nor to any notations.
+ * We don't care about PEs it defined itself, but need to pass
+ * in Set of PEs it refers to, to check if cached copy can be
+ * used with different int. subsets.
+ * We need not worry about notations referred, since they are
+ * not allowed to be re-defined.
+ */
+ boolean cachable = !mUsesPredefdEntities && !mUsesPredefdNotations;
+ ss = DTDSubsetImpl.constructInstance(cachable,
+ mGeneralEntities, mRefdGEs,
+ null, mRefdPEs,
+ mNotations, mElements,
+ mCfgFullyValidating);
+ } else {
+ /* Internal subsets are not cachable (no unique way to refer
+ * to unique internal subsets), and there can be no references
+ * to pre-defined PEs, as none were passed.
+ */
+ ss = DTDSubsetImpl.constructInstance(false, mGeneralEntities, null,
+ mParamEntities, null,
+ mNotations, mElements,
+ mCfgFullyValidating);
+ }
+ return ss;
+ }
+
+ protected void parseDirective()
+ throws XMLStreamException
+ {
+ /* Hmmh. Don't think PEs are allowed to contain starting
+ * '!' (or '?')... and it has to come from the same
+ * input source too (no splits)
+ */
+ char c = dtdNextFromCurr();
+ if (c == '?') { // xml decl?
+ readPI();
+ return;
+ }
+ if (c != '!') { // nothing valid
+ throwDTDUnexpectedChar(c, "; expected '!' to start a directive");
+ }
+
+ /* ignore/include, comment, or directive; we are still getting
+ * token from same section though
+ */
+ c = dtdNextFromCurr();
+ if (c == '-') { // plain comment
+ c = dtdNextFromCurr();
+ if (c != '-') {
+ throwDTDUnexpectedChar(c, "; expected '-' for a comment");
+ }
+ if (mEventListener != null && mEventListener.dtdReportComments()) {
+ readComment(mEventListener);
+ } else {
+ skipComment();
+ }
+ } else if (c == '[') {
+ checkInclusion();
+ } else if (c >= 'A' && c <= 'Z') {
+ handleDeclaration(c);
+ } else {
+ throwDTDUnexpectedChar(c, ErrorConsts.ERR_DTD_MAINLEVEL_KEYWORD);
+ }
+ }
+
+ /**
+ * Method similar to {@link #parseDirective}, but one that takes care
+ * to properly output dtd contents via {@link com.ctc.wstx.dtd.DTDWriter}
+ * as necessary.
+ * Separated to simplify both methods; otherwise would end up with
+ * 'if (... flatten...) ... else ...' spaghetti code.
+ */
+ protected void parseDirectiveFlattened()
+ throws XMLStreamException
+ {
+ /* First, need to flush any flattened output there may be, at
+ * this point (except for opening lt char): and then need to
+ * temporarily disable more output until we know the type and
+ * whether it should be output or not:
+ */
+ mFlattenWriter.flush(mInputBuffer, mInputPtr-1);
+ mFlattenWriter.disableOutput();
+
+ /* Let's determine type here, and call appropriate skip/parse
+ * methods.
+ */
+ char c = dtdNextFromCurr();
+ if (c == '?') { // xml decl?
+ mFlattenWriter.enableOutput(mInputPtr);
+ mFlattenWriter.output("");
+ readPI();
+ //throwDTDUnexpectedChar(c, " expected '!' to start a directive");
+ return;
+ }
+ if (c != '!') { // nothing valid
+ throwDTDUnexpectedChar(c, ErrorConsts.ERR_DTD_MAINLEVEL_KEYWORD);
+ }
+
+ // ignore/include, comment, or directive
+
+ c = dtdNextFromCurr();
+ if (c == '-') { // plain comment
+ c = dtdNextFromCurr();
+ if (c != '-') {
+ throwDTDUnexpectedChar(c, "; expected '-' for a comment");
+ }
+ boolean comm = mFlattenWriter.includeComments();
+ if (comm) {
+ mFlattenWriter.enableOutput(mInputPtr);
+ mFlattenWriter.output("");
+ }
+
+ @Override
+ public final void writePIStart(String target, boolean addSpace) throws IOException
+ {
+ fastWriteRaw('<', '?');
+ fastWriteRaw(target);
+ if (addSpace) {
+ fastWriteRaw(' ');
+ }
+ }
+
+ @Override
+ public final void writePIEnd() throws IOException {
+ fastWriteRaw('?', '>');
+ }
+
+ /*
+ ////////////////////////////////////////////////
+ // Higher-level output methods, text output
+ ////////////////////////////////////////////////
+ */
+
+ @Override
+ public int writeCData(String data) throws IOException
+ {
+ if (mCheckContent) {
+ int ix = verifyCDataContent(data);
+ if (ix >= 0) {
+ if (!mFixContent) { // Can we fix it?
+ return ix;
+ }
+ // Yes we can! (...Bob the Builder...)
+ writeSegmentedCData(data, ix);
+ return -1;
+ }
+ }
+ fastWriteRaw("");
+ return -1;
+ }
+
+ @Override
+ public int writeCData(char[] cbuf, int offset, int len) throws IOException
+ {
+ if (mCheckContent) {
+ int ix = verifyCDataContent(cbuf, offset, len);
+ if (ix >= 0) {
+ if (!mFixContent) { // Can we fix it?
+ return ix;
+ }
+ // Yes we can! (...Bob the Builder...)
+ writeSegmentedCData(cbuf, offset, len, ix);
+ return -1;
+ }
+ }
+ fastWriteRaw("");
+ return -1;
+ }
+
+ @Override
+ public void writeCharacters(String text) throws IOException
+ {
+ if (mOut == null) {
+ return;
+ }
+ if (mTextWriter != null) { // custom escaping?
+ mTextWriter.write(text);
+ return;
+ }
+ int inPtr = 0;
+ final int len = text.length();
+
+ // nope, default:
+ final int[] QC = QUOTABLE_TEXT_CHARS;
+ final int highChar = mEncHighChar;
+ final int MAXQC = Math.min(QC.length, highChar);
+
+ main_loop:
+ while (true) {
+ String ent = null;
+
+ inner_loop:
+ while (true) {
+ if (inPtr >= len) {
+ break main_loop;
+ }
+ char c = text.charAt(inPtr++);
+
+ if (c < MAXQC) {
+ if (QC[c] != 0) {
+ if (c < 0x0020) {
+ if (c != ' ' && c != '\n' && c != '\t') { // fine as is
+ if (c == '\r') {
+ if (mEscapeCR) {
+ break inner_loop;
+ }
+ } else {
+ if (!mXml11 || c == 0) {
+ c = handleInvalidChar(c); // throws an error usually
+ ent = String.valueOf((char) c);
+ } else {
+ break inner_loop; // need quoting
+ }
+ }
+ }
+ } else if (c == '<') {
+ ent = "<";
+ break inner_loop;
+ } else if (c == '&') {
+ ent = "&";
+ break inner_loop;
+ } else if (c == '>') {
+ // Let's be conservative; and if there's any
+ // change it might be part of "]]>" quote it
+ if (inPtr < 2 || text.charAt(inPtr-2) == ']') {
+ ent = ">";
+ break inner_loop;
+ }
+ } else if (c >= 0x7F) {
+ break;
+ }
+ }
+ } else if (c >= highChar) {
+ break inner_loop;
+ }
+ if (mOutputPtr >= mOutputBufLen) {
+ flushBuffer();
+ }
+ mOutputBuffer[mOutputPtr++] = c;
+ }
+ if (ent != null) {
+ writeRaw(ent);
+ } else {
+ writeAsEntity(text.charAt(inPtr-1));
+ }
+ }
+ }
+
+ @Override
+ public void writeCharacters(char[] cbuf, int offset, int len) throws IOException
+ {
+ if (mOut == null) {
+ return;
+ }
+ if (mTextWriter != null) { // custom escaping?
+ mTextWriter.write(cbuf, offset, len);
+ return;
+ }
+ // nope, default:
+ final int[] QC = QUOTABLE_TEXT_CHARS;
+ final int highChar = mEncHighChar;
+ final int MAXQC = Math.min(QC.length, highChar);
+ len += offset;
+ do {
+ int c = 0;
+ int start = offset;
+ String ent = null;
+
+ for (; offset < len; ++offset) {
+ c = cbuf[offset];
+
+ if (c < MAXQC) {
+ if (QC[c] != 0) {
+ // Ok, possibly needs quoting... further checks needed
+ if (c == '<') {
+ ent = "<";
+ break;
+ } else if (c == '&') {
+ ent = "&";
+ break;
+ } else if (c == '>') {
+ /* Let's be conservative; and if there's any
+ * change it might be part of "]]>" quote it
+ */
+ if ((offset == start) || cbuf[offset-1] == ']') {
+ ent = ">";
+ break;
+ }
+ } else if (c < 0x0020) {
+ if (c == '\n' || c == '\t') { // fine as is
+ ;
+ } else if (c == '\r') {
+ if (mEscapeCR) {
+ break;
+ }
+ } else {
+ if (!mXml11 || c == 0) {
+ c = handleInvalidChar(c);
+ // Hmmh. This is very inefficient, but...
+ ent = String.valueOf((char) c);
+ }
+ break; // need quoting
+ }
+ } else if (c >= 0x7F) {
+ break;
+ }
+ }
+ } else if (c >= highChar) {
+ break;
+ }
+ // otherwise fine
+ }
+ int outLen = offset - start;
+ if (outLen > 0) {
+ writeRaw(cbuf, start, outLen);
+ }
+ if (ent != null) {
+ writeRaw(ent);
+ ent = null;
+ } else if (offset < len) {
+ writeAsEntity(c);
+ }
+ } while (++offset < len);
+ }
+
+ /**
+ * Method that will try to output the content as specified. If
+ * the content passed in has embedded "--" in it, it will either
+ * add an intervening space between consequtive hyphens (if content
+ * fixing is enabled), or return the offset of the first hyphen in
+ * multi-hyphen sequence.
+ */
+ @Override
+ public int writeComment(String data) throws IOException
+ {
+ if (mCheckContent) {
+ int ix = verifyCommentContent(data);
+ if (ix >= 0) {
+ if (!mFixContent) { // Can we fix it?
+ return ix;
+ }
+ // Yes we can! (...Bob the Builder...)
+ writeSegmentedComment(data, ix);
+ return -1;
+ }
+ }
+ fastWriteRaw("");
+ return -1;
+ }
+
+ @Override
+ public void writeDTD(String data) throws IOException
+ {
+ writeRaw(data);
+ }
+
+ @Override
+ public void writeDTD(String rootName, String systemId, String publicId,
+ String internalSubset)
+ throws IOException, XMLStreamException
+ {
+ fastWriteRaw(" 0) {
+ fastWriteRaw(' ', '[');
+ fastWriteRaw(internalSubset);
+ fastWriteRaw(']');
+ }
+ fastWriteRaw('>');
+ }
+
+ @Override
+ public void writeEntityReference(String name)
+ throws IOException, XMLStreamException
+ {
+ if (mCheckNames) {
+ verifyNameValidity(name, mNsAware);
+ }
+ fastWriteRaw('&');
+ fastWriteRaw(name);
+ fastWriteRaw(';');
+ }
+
+ @Override
+ public void writeXmlDeclaration(String version, String encoding, String standalone)
+ throws IOException
+ {
+ final char chQuote = (mUseDoubleQuotesInXmlDecl ? '"' : '\'');
+
+ fastWriteRaw(" 0) {
+ fastWriteRaw(" encoding=");
+ fastWriteRaw(chQuote);
+ fastWriteRaw(encoding);
+ fastWriteRaw(chQuote);
+ }
+ if (standalone != null) {
+ fastWriteRaw(" standalone=");
+ fastWriteRaw(chQuote);
+ fastWriteRaw(standalone);
+ fastWriteRaw(chQuote);
+ }
+ fastWriteRaw('?', '>');
+ }
+
+ @Override
+ public int writePI(String target, String data)
+ throws IOException, XMLStreamException
+ {
+ if (mCheckNames) {
+ // As per namespace specs, can not have colon(s)
+ verifyNameValidity(target, mNsAware);
+ }
+ fastWriteRaw('<', '?');
+ fastWriteRaw(target);
+ if (data != null && data.length() > 0) {
+ if (mCheckContent) {
+ int ix = data.indexOf('?');
+ if (ix >= 0) {
+ ix = data.indexOf("?>", ix);
+ if (ix >= 0) {
+ return ix;
+ }
+ }
+ }
+ fastWriteRaw(' ');
+ // Data may be longer, let's call regular writeRaw method
+ writeRaw(data);
+ }
+ fastWriteRaw('?', '>');
+ return -1;
+ }
+
+ /*
+ ////////////////////////////////////////////////////
+ // Write methods, elements
+ ////////////////////////////////////////////////////
+ */
+
+ @Override
+ public void writeStartTagStart(String localName)
+ throws IOException, XMLStreamException
+ {
+ if (mCheckNames) {
+ verifyNameValidity(localName, mNsAware);
+ }
+
+ int ptr = mOutputPtr;
+ int extra = (mOutputBufLen - ptr) - (1 + localName.length());
+ if (extra < 0) { // split on boundary, slower
+ fastWriteRaw('<');
+ fastWriteRaw(localName);
+ } else {
+ char[] buf = mOutputBuffer;
+ buf[ptr++] = '<';
+ int len = localName.length();
+ localName.getChars(0, len, buf, ptr);
+ mOutputPtr = ptr+len;
+ }
+ }
+
+ @Override
+ public void writeStartTagStart(String prefix, String localName)
+ throws IOException, XMLStreamException
+ {
+ if (prefix == null || prefix.length() == 0) { // shouldn't happen
+ writeStartTagStart(localName);
+ return;
+ }
+
+ if (mCheckNames) {
+ verifyNameValidity(prefix, mNsAware);
+ verifyNameValidity(localName, mNsAware);
+ }
+
+ int ptr = mOutputPtr;
+ int len = prefix.length();
+ int extra = (mOutputBufLen - ptr) - (2 + localName.length() + len);
+ if (extra < 0) { // across buffer boundary, slow case
+ fastWriteRaw('<');
+ fastWriteRaw(prefix);
+ fastWriteRaw(':');
+ fastWriteRaw(localName);
+ } else { // fast case, all inlined
+ char[] buf = mOutputBuffer;
+ buf[ptr++] = '<';
+ prefix.getChars(0, len, buf, ptr);
+ ptr += len;
+ buf[ptr++] = ':';
+ len = localName.length();
+ localName.getChars(0, len, buf, ptr);
+ mOutputPtr = ptr+len;
+ }
+ }
+
+ @Override
+ public void writeStartTagEnd() throws IOException {
+ fastWriteRaw('>');
+ }
+
+ @Override
+ public void writeStartTagEmptyEnd() throws IOException
+ {
+ int ptr = mOutputPtr;
+ if ((ptr + 3) >= mOutputBufLen) {
+ if (mOut == null) {
+ return;
+ }
+ flushBuffer();
+ ptr = mOutputPtr;
+ }
+ char[] buf = mOutputBuffer;
+ if (mAddSpaceAfterEmptyElem) {
+ buf[ptr++] = ' ';
+ }
+ buf[ptr++] = '/';
+ buf[ptr++] = '>';
+ mOutputPtr = ptr;
+ }
+
+ @Override
+ public void writeEndTag(String localName) throws IOException
+ {
+ int ptr = mOutputPtr;
+ int extra = (mOutputBufLen - ptr) - (3 + localName.length());
+ if (extra < 0) {
+ fastWriteRaw('<', '/');
+ fastWriteRaw(localName);
+ fastWriteRaw('>');
+ } else {
+ char[] buf = mOutputBuffer;
+ buf[ptr++] = '<';
+ buf[ptr++] = '/';
+ int len = localName.length();
+ localName.getChars(0, len, buf, ptr);
+ ptr += len;
+ buf[ptr++] = '>';
+ mOutputPtr = ptr;
+ }
+ }
+
+ @Override
+ public void writeEndTag(String prefix, String localName) throws IOException
+ {
+ if (prefix == null || prefix.length() == 0) {
+ writeEndTag(localName);
+ return;
+ }
+ int ptr = mOutputPtr;
+ int len = prefix.length();
+ int extra = (mOutputBufLen - ptr) - (4 + localName.length() + len);
+ if (extra < 0) {
+ fastWriteRaw('<', '/');
+ /* At this point, it is assumed caller knows that end tag
+ * matches with start tag, and that it (by extension) has been
+ * validated if and as necessary
+ */
+ fastWriteRaw(prefix);
+ fastWriteRaw(':');
+ fastWriteRaw(localName);
+ fastWriteRaw('>');
+ } else {
+ char[] buf = mOutputBuffer;
+ buf[ptr++] = '<';
+ buf[ptr++] = '/';
+ prefix.getChars(0, len, buf, ptr);
+ ptr += len;
+ buf[ptr++] = ':';
+ len = localName.length();
+ localName.getChars(0, len, buf, ptr);
+ ptr += len;
+ buf[ptr++] = '>';
+ mOutputPtr = ptr;
+ }
+ }
+
+ /*
+ ////////////////////////////////////////////////////
+ // Write methods, attributes/ns
+ ////////////////////////////////////////////////////
+ */
+
+ @Override
+ public void writeAttribute(String localName, String value)
+ throws IOException, XMLStreamException
+ {
+ if (mOut == null) {
+ return;
+ }
+ if (mCheckNames) {
+ verifyNameValidity(localName, mNsAware);
+ }
+ int len = localName.length();
+ if (((mOutputBufLen - mOutputPtr) - (3 + len)) < 0) {
+ fastWriteRaw(' ');
+ fastWriteRaw(localName);
+ fastWriteRaw('=', '"');
+ } else {
+ int ptr = mOutputPtr;
+ char[] buf = mOutputBuffer;
+ buf[ptr++] = ' ';
+ localName.getChars(0, len, buf, ptr);
+ ptr += len;
+ buf[ptr++] = '=';
+ buf[ptr++] = '"';
+ mOutputPtr = ptr;
+ }
+
+ len = (value == null) ? 0 : value.length();
+ if (len > 0) {
+ if (mAttrValueWriter != null) { // custom escaping?
+ mAttrValueWriter.write(value, 0, len);
+ } else { // nope, default
+ writeAttrValue(value, len);
+ }
+ }
+ fastWriteRaw('"');
+ }
+
+ @Override
+ public void writeAttribute(String localName, char[] value, int offset, int vlen)
+ throws IOException, XMLStreamException
+ {
+ if (mOut == null) {
+ return;
+ }
+ if (mCheckNames) {
+ verifyNameValidity(localName, mNsAware);
+ }
+ int len = localName.length();
+ if (((mOutputBufLen - mOutputPtr) - (3 + len)) < 0) {
+ fastWriteRaw(' ');
+ fastWriteRaw(localName);
+ fastWriteRaw('=', '"');
+ } else {
+ int ptr = mOutputPtr;
+ char[] buf = mOutputBuffer;
+ buf[ptr++] = ' ';
+ localName.getChars(0, len, buf, ptr);
+ ptr += len;
+ buf[ptr++] = '=';
+ buf[ptr++] = '"';
+ mOutputPtr = ptr;
+ }
+
+ if (vlen > 0) {
+ if (mAttrValueWriter != null) { // custom escaping?
+ mAttrValueWriter.write(value, offset, vlen);
+ } else { // nope, default
+ writeAttrValue(value, offset, vlen);
+ }
+ }
+ fastWriteRaw('"');
+ }
+
+ @Override
+ public void writeAttribute(String prefix, String localName, String value)
+ throws IOException, XMLStreamException
+ {
+ if (mOut == null) {
+ return;
+ }
+ if (mCheckNames) {
+ verifyNameValidity(prefix, mNsAware);
+ verifyNameValidity(localName, mNsAware);
+ }
+ int len = prefix.length();
+ if (((mOutputBufLen - mOutputPtr) - (4 + localName.length() + len)) < 0) {
+ fastWriteRaw(' ');
+ if (len > 0) {
+ fastWriteRaw(prefix);
+ fastWriteRaw(':');
+ }
+ fastWriteRaw(localName);
+ fastWriteRaw('=', '"');
+ } else {
+ int ptr = mOutputPtr;
+ char[] buf = mOutputBuffer;
+ buf[ptr++] = ' ';
+ prefix.getChars(0, len, buf, ptr);
+ ptr += len;
+ buf[ptr++] = ':';
+ len = localName.length();
+ localName.getChars(0, len, buf, ptr);
+ ptr += len;
+ buf[ptr++] = '=';
+ buf[ptr++] = '"';
+ mOutputPtr = ptr;
+ }
+
+ len = (value == null) ? 0 : value.length();
+ if (len > 0) {
+ if (mAttrValueWriter != null) { // custom escaping?
+ mAttrValueWriter.write(value, 0, len);
+ } else { // nope, default
+ writeAttrValue(value, len);
+ }
+ }
+ fastWriteRaw('"');
+ }
+
+ @Override
+ public void writeAttribute(String prefix, String localName, char[] value, int offset, int vlen)
+ throws IOException, XMLStreamException
+ {
+ if (mOut == null) {
+ return;
+ }
+ if (mCheckNames) {
+ verifyNameValidity(prefix, mNsAware);
+ verifyNameValidity(localName, mNsAware);
+ }
+ int len = prefix.length();
+ if (((mOutputBufLen - mOutputPtr) - (4 + localName.length() + len)) < 0) {
+ fastWriteRaw(' ');
+ if (len > 0) {
+ fastWriteRaw(prefix);
+ fastWriteRaw(':');
+ }
+ fastWriteRaw(localName);
+ fastWriteRaw('=', '"');
+ } else {
+ int ptr = mOutputPtr;
+ char[] buf = mOutputBuffer;
+ buf[ptr++] = ' ';
+ prefix.getChars(0, len, buf, ptr);
+ ptr += len;
+ buf[ptr++] = ':';
+ len = localName.length();
+ localName.getChars(0, len, buf, ptr);
+ ptr += len;
+ buf[ptr++] = '=';
+ buf[ptr++] = '"';
+ mOutputPtr = ptr;
+ }
+ if (vlen > 0) {
+ if (mAttrValueWriter != null) { // custom escaping?
+ mAttrValueWriter.write(value, offset, vlen);
+ } else { // nope, default
+ writeAttrValue(value, offset, vlen);
+ }
+ }
+ fastWriteRaw('"');
+ }
+
+ private final void writeAttrValue(String value, int len)
+ throws IOException
+ {
+ int inPtr = 0;
+ final char qchar = mEncQuoteChar;
+ int highChar = mEncHighChar;
+
+ main_loop:
+ while (true) { // main_loop
+ String ent = null;
+
+ inner_loop:
+ while (true) {
+ if (inPtr >= len) {
+ break main_loop;
+ }
+ char c = value.charAt(inPtr++);
+ if (c <= HIGHEST_ENCODABLE_ATTR_CHAR) { // special char?
+ if (c < 0x0020) { // tab, cr/lf need encoding too
+ if (c == '\r') {
+ if (mEscapeCR) {
+ break inner_loop; // quoting
+ }
+ } else if (c != '\n' && c != '\t'
+ && (!mXml11 || c == 0)) {
+ c = handleInvalidChar(c);
+ } else {
+ break inner_loop; // need quoting
+ }
+ } else if (c == qchar) {
+ ent = mEncQuoteEntity;
+ break inner_loop;
+ } else if (c == '<') {
+ ent = "<";
+ break inner_loop;
+ } else if (c == '&') {
+ ent = "&";
+ break inner_loop;
+ }
+ } else if (c >= highChar) { // out of range, have to escape
+ break inner_loop;
+ }
+ if (mOutputPtr >= mOutputBufLen) {
+ flushBuffer();
+ }
+ mOutputBuffer[mOutputPtr++] = c;
+ }
+ if (ent != null) {
+ writeRaw(ent);
+ } else {
+ writeAsEntity(value.charAt(inPtr-1));
+ }
+ }
+ }
+
+ private final void writeAttrValue(char[] value, int offset, int len)
+ throws IOException
+ {
+ len += offset;
+ final char qchar = mEncQuoteChar;
+ int highChar = mEncHighChar;
+
+ main_loop:
+ while (true) { // main_loop
+ String ent = null;
+
+ inner_loop:
+ while (true) {
+ if (offset >= len) {
+ break main_loop;
+ }
+ char c = value[offset++];
+ if (c <= HIGHEST_ENCODABLE_ATTR_CHAR) { // special char?
+ if (c < 0x0020) { // tab, cr/lf need encoding too
+ if (c == '\r') {
+ if (mEscapeCR) {
+ break inner_loop; // quoting
+ }
+ } else if (c != '\n' && c != '\t'
+ && (!mXml11 || c == 0)) {
+ c = handleInvalidChar(c);
+ } else {
+ break inner_loop; // need quoting
+ }
+ } else if (c == qchar) {
+ ent = mEncQuoteEntity;
+ break inner_loop;
+ } else if (c == '<') {
+ ent = "<";
+ break inner_loop;
+ } else if (c == '&') {
+ ent = "&";
+ break inner_loop;
+ }
+ } else if (c >= highChar) { // out of range, have to escape
+ break inner_loop;
+ }
+ if (mOutputPtr >= mOutputBufLen) {
+ flushBuffer();
+ }
+ mOutputBuffer[mOutputPtr++] = c;
+ }
+ if (ent != null) {
+ writeRaw(ent);
+ } else {
+ writeAsEntity(value[offset-1]);
+ }
+ }
+ }
+
+ /*
+ ////////////////////////////////////////////////
+ // Methods used by Typed Access API
+ ////////////////////////////////////////////////
+ */
+
+ @Override
+ public final void writeTypedElement(AsciiValueEncoder enc)
+ throws IOException
+ {
+ if (mOut == null) {
+ return;
+ }
+
+ int free = mOutputBufLen - mOutputPtr;
+ if (enc.bufferNeedsFlush(free)) {
+ flush();
+ }
+ while (true) {
+ mOutputPtr = enc.encodeMore(mOutputBuffer, mOutputPtr, mOutputBufLen);
+ // If no flushing needed, indicates that all data was encoded
+ if (enc.isCompleted()) {
+ break;
+ }
+ flush();
+ }
+ }
+
+ @Override
+ public final void writeTypedElement(AsciiValueEncoder enc,
+ XMLValidator validator, char[] copyBuffer)
+ throws IOException, XMLStreamException
+ {
+ if (mOut == null) {
+ return;
+ }
+ int free = mOutputBufLen - mOutputPtr;
+ if (enc.bufferNeedsFlush(free)) {
+ flush();
+ }
+ int start = mOutputPtr;
+ while (true) {
+ mOutputPtr = enc.encodeMore(mOutputBuffer, mOutputPtr, mOutputBufLen);
+ // False -> can't be sure it's the whole remaining text
+ validator.validateText(mOutputBuffer, start, mOutputPtr, false);
+ if (enc.isCompleted()) {
+ break;
+ }
+ flush();
+ start = mOutputPtr;
+ }
+ }
+
+ @Override
+ public void writeTypedAttribute(String localName, AsciiValueEncoder enc)
+ throws IOException, XMLStreamException
+ {
+ if (mOut == null) {
+ return;
+ }
+ if (mCheckNames) {
+ verifyNameValidity(localName, mNsAware);
+ }
+ int len = localName.length();
+ if ((mOutputPtr + 3 + len) > mOutputBufLen) {
+ fastWriteRaw(' ');
+ fastWriteRaw(localName);
+ fastWriteRaw('=', '"');
+ } else {
+ int ptr = mOutputPtr;
+ char[] buf = mOutputBuffer;
+ buf[ptr++] = ' ';
+ localName.getChars(0, len, buf, ptr);
+ ptr += len;
+ buf[ptr++] = '=';
+ buf[ptr++] = '"';
+ mOutputPtr = ptr;
+ }
+
+ int free = mOutputBufLen - mOutputPtr;
+ if (enc.bufferNeedsFlush(free)) {
+ flush();
+ }
+ while (true) {
+ mOutputPtr = enc.encodeMore(mOutputBuffer, mOutputPtr, mOutputBufLen);
+ if (enc.isCompleted()) {
+ break;
+ }
+ flush();
+ }
+ fastWriteRaw('"');
+ }
+
+ @Override
+ public void writeTypedAttribute(String prefix, String localName,
+ AsciiValueEncoder enc)
+ throws IOException, XMLStreamException
+ {
+ if (mOut == null) {
+ return;
+ }
+ if (mCheckNames) {
+ verifyNameValidity(prefix, mNsAware);
+ verifyNameValidity(localName, mNsAware);
+ }
+ int plen = prefix.length();
+ int llen = localName.length();
+
+ if ((mOutputPtr + 4 + plen + llen) > mOutputBufLen) {
+ writePrefixedName(prefix, localName);
+ fastWriteRaw('=', '"');
+ } else {
+ int ptr = mOutputPtr;
+ char[] buf = mOutputBuffer;
+ buf[ptr++] = ' ';
+ if (plen > 0) {
+ prefix.getChars(0, plen, buf, ptr);
+ ptr += plen;
+ buf[ptr++] = ':';
+
+ }
+ localName.getChars(0, llen, buf, ptr);
+ ptr += llen;
+ buf[ptr++] = '=';
+ buf[ptr++] = '"';
+ mOutputPtr = ptr;
+ }
+
+ int free = mOutputBufLen - mOutputPtr;
+ if (enc.bufferNeedsFlush(free)) {
+ flush();
+ }
+ while (true) {
+ mOutputPtr = enc.encodeMore(mOutputBuffer, mOutputPtr, mOutputBufLen);
+ if (enc.isCompleted()) {
+ break;
+ }
+ flush();
+ }
+
+ fastWriteRaw('"');
+ }
+
+ @Override
+ public void writeTypedAttribute(String prefix, String localName, String nsURI,
+ AsciiValueEncoder enc,
+ XMLValidator validator, char[] copyBuffer)
+ throws IOException, XMLStreamException
+ {
+ if (mOut == null) {
+ return;
+ }
+ if (prefix == null) {
+ prefix = "";
+ }
+ if (nsURI == null) {
+ nsURI = "";
+ }
+ int plen = prefix.length();
+ if (mCheckNames) {
+ if (plen > 0) {
+ verifyNameValidity(prefix, mNsAware);
+ }
+ verifyNameValidity(localName, mNsAware);
+ }
+ if (((mOutputBufLen - mOutputPtr) - (4 + localName.length() + plen)) < 0) {
+ writePrefixedName(prefix, localName);
+ fastWriteRaw('=', '"');
+ } else {
+ int ptr = mOutputPtr;
+ char[] buf = mOutputBuffer;
+ buf[ptr++] = ' ';
+ if (plen > 0) {
+ prefix.getChars(0, plen, buf, ptr);
+ ptr += plen;
+ buf[ptr++] = ':';
+
+ }
+ int llen = localName.length();
+ localName.getChars(0, llen, buf, ptr);
+ ptr += llen;
+ buf[ptr++] = '=';
+ buf[ptr++] = '"';
+ mOutputPtr = ptr;
+ }
+
+ /* Tricky here is this: attributes to validate can not be
+ * split (validators expect complete values). So, if value
+ * won't fit as is, may need to aggregate using StringBuilder
+ */
+ int free = mOutputBufLen - mOutputPtr;
+ if (enc.bufferNeedsFlush(free)) {
+ flush();
+ }
+ int start = mOutputPtr;
+
+ // First, let's see if one call is enough
+ mOutputPtr = enc.encodeMore(mOutputBuffer, mOutputPtr, mOutputBufLen);
+ if (enc.isCompleted()) { // yup
+ validator.validateAttribute(localName, nsURI, prefix, mOutputBuffer, start, mOutputPtr);
+ return;
+ }
+
+ // If not, must combine first
+ StringBuilder sb = new StringBuilder(mOutputBuffer.length << 1);
+ sb.append(mOutputBuffer, start, mOutputPtr-start);
+ while (true) {
+ flush();
+ start = mOutputPtr;
+ mOutputPtr = enc.encodeMore(mOutputBuffer, mOutputPtr, mOutputBufLen);
+ sb.append(mOutputBuffer, start, mOutputPtr-start);
+ // All done?
+ if (enc.isCompleted()) {
+ break;
+ }
+ }
+ fastWriteRaw('"');
+
+ // Then validate
+ String valueStr = sb.toString();
+ validator.validateAttribute(localName, nsURI, prefix, valueStr);
+ }
+
+ protected final void writePrefixedName(String prefix, String localName)
+ throws IOException
+ {
+ fastWriteRaw(' ');
+ if (prefix.length() > 0) {
+ fastWriteRaw(prefix);
+ fastWriteRaw(':');
+ }
+ fastWriteRaw(localName);
+ }
+
+ /*
+ ////////////////////////////////////////////////////
+ // Internal methods, buffering
+ ////////////////////////////////////////////////////
+ */
+
+ private final void flushBuffer()
+ throws IOException
+ {
+ if (mOutputPtr > 0 && mOutputBuffer != null) {
+ int ptr = mOutputPtr;
+ // Need to update location info, to keep it in sync
+ mLocPastChars += ptr;
+ mLocRowStartOffset -= ptr;
+ mOutputPtr = 0;
+ mOut.write(mOutputBuffer, 0, ptr);
+ }
+ }
+
+ private final void fastWriteRaw(char c)
+ throws IOException
+ {
+ if (mOutputPtr >= mOutputBufLen) {
+ if (mOut == null) {
+ return;
+ }
+ flushBuffer();
+ }
+ mOutputBuffer[mOutputPtr++] = c;
+ }
+
+ private final void fastWriteRaw(char c1, char c2)
+ throws IOException
+ {
+ if ((mOutputPtr + 1) >= mOutputBufLen) {
+ if (mOut == null) {
+ return;
+ }
+ flushBuffer();
+ }
+ mOutputBuffer[mOutputPtr++] = c1;
+ mOutputBuffer[mOutputPtr++] = c2;
+ }
+
+ private final void fastWriteRaw(String str)
+ throws IOException
+ {
+ int len = str.length();
+ int ptr = mOutputPtr;
+ if ((ptr + len) >= mOutputBufLen) {
+ if (mOut == null) {
+ return;
+ }
+ /* It's even possible that String is longer than the buffer (not
+ * likely, possible). If so, let's just call the full
+ * method:
+ */
+ if (len > mOutputBufLen) {
+ writeRaw(str);
+ return;
+ }
+ flushBuffer();
+ ptr = mOutputPtr;
+ }
+ str.getChars(0, len, mOutputBuffer, ptr);
+ mOutputPtr = ptr+len;
+ }
+
+ /*
+ ////////////////////////////////////////////////////
+ // Internal methods, content verification/fixing
+ ////////////////////////////////////////////////////
+ */
+
+ /**
+ * @return Index at which a problem was found, if any; -1 if there's
+ * no problem.
+ */
+ protected int verifyCDataContent(String content)
+ {
+ if (content != null && content.length() >= 3) {
+ int ix = content.indexOf(']');
+ if (ix >= 0) {
+ return content.indexOf("]]>", ix);
+ }
+ }
+ return -1;
+ }
+
+ protected int verifyCDataContent(char[] c, int start, int end)
+ {
+ if (c != null) {
+ start += 2;
+ /* Let's do simple optimization for search...
+ * (simple bayer-moore - like algorithm)
+ */
+ while (start < end) {
+ char ch = c[start];
+ if (ch == ']') {
+ ++start; // let's just move by one in this case
+ continue;
+ }
+ if (ch == '>') { // match?
+ if (c[start-1] == ']'
+ && c[start-2] == ']') {
+ return start-2;
+ }
+ }
+ start += 2;
+ }
+ }
+ return -1;
+ }
+
+ protected int verifyCommentContent(String content)
+ {
+ int ix = content.indexOf('-');
+ if (ix >= 0) {
+ /* actually, it's illegal to just end with '-' too, since
+ * that would cause invalid end marker '--->'
+ */
+ if (ix < (content.length() - 1)) {
+ ix = content.indexOf("--", ix);
+ }
+ }
+ return ix;
+ }
+
+ protected void writeSegmentedCData(String content, int index)
+ throws IOException
+ {
+ /* It's actually fairly easy, just split "]]>" into 2 pieces;
+ * for each ']]>'; first one containing "]]", second one ">"
+ * (as long as necessary)
+ */
+ int start = 0;
+ while (index >= 0) {
+ fastWriteRaw("");
+ start = index+2;
+ index = content.indexOf("]]>", start);
+ }
+ // Ok, then the last segment
+ fastWriteRaw("");
+ }
+
+ protected void writeSegmentedCData(char[] c, int start, int len, int index)
+ throws IOException
+ {
+ int end = start + len;
+ while (index >= 0) {
+ fastWriteRaw("");
+ start = index+2;
+ index = verifyCDataContent(c, start, end);
+ }
+ // Ok, then the last segment
+ fastWriteRaw("");
+ }
+
+ protected void writeSegmentedComment(String content, int index)
+ throws IOException
+ {
+ int len = content.length();
+ // First the special case (last char is hyphen):
+ if (index == (len-1)) {
+ fastWriteRaw("");
+ return;
+ }
+
+ /* Fixing comments is more difficult than that of CDATA segments';
+ * this because CDATA can still contain embedded ']]'s, but
+ * comment neither allows '--' nor ending with '-->'; which means
+ * that it's impossible to just split segments. Instead we'll do
+ * something more intrusive, and embed single spaces between all
+ * '--' character pairs... it's intrusive, but comments are not
+ * supposed to contain any data, so that should be fine (plus
+ * at least result is valid, unlike contents as is)
+ */
+ fastWriteRaw("");
+ }
+
+ /**
+ * Method used to figure out which part of the Unicode char set the
+ * encoding can natively support. Values returned are 7, 8 and 16,
+ * to indicate (respectively) "ascii", "ISO-Latin" and "native Unicode".
+ * These just best guesses, but should work ok for the most common
+ * encodings.
+ */
+ public static int guessEncodingBitSize(String enc)
+ {
+ if (enc == null || enc.length() == 0) { // let's assume default is UTF-8...
+ return 16;
+ }
+
+ // Let's see if we can find a normalized name, first:
+ enc = CharsetNames.normalize(enc);
+
+ // Ok, first, do we have known ones; starting with most common:
+ if (enc == CharsetNames.CS_UTF8) {
+ return 16; // meaning up to 2^16 can be represented natively
+ } else if (enc == CharsetNames.CS_ISO_LATIN1) {
+ return 8;
+ } else if (enc == CharsetNames.CS_US_ASCII) {
+ return 7;
+ } else if (enc == CharsetNames.CS_UTF16
+ || enc == CharsetNames.CS_UTF16BE
+ || enc == CharsetNames.CS_UTF16LE
+ || enc == CharsetNames.CS_UTF32BE
+ || enc == CharsetNames.CS_UTF32LE) {
+ return 16;
+ }
+
+ /* Above and beyond well-recognized names, it might still be
+ * good to have more heuristics for as-of-yet unhandled cases...
+ * But, it's probably easier to only assume 8-bit clean (could
+ * even make it just 7, let's see how this works out)
+ */
+ return 8;
+ }
+
+ protected final void writeAsEntity(int c)
+ throws IOException
+ {
+ char[] buf = mOutputBuffer;
+ int ptr = mOutputPtr;
+ if ((ptr + 10) >= buf.length) { // [up to 6 hex digits] ;
+ flushBuffer();
+ ptr = mOutputPtr;
+ }
+ buf[ptr++] = '&';
+
+ // Can use more optimal notation for 8-bit ascii stuff:
+ if (c < 256) {
+ /* Also; although not really mandatory, let's also
+ * use pre-defined entities where possible.
+ */
+ if (c == '&') {
+ buf[ptr++] = 'a';
+ buf[ptr++] = 'm';
+ buf[ptr++] = 'p';
+ } else if (c == '<') {
+ buf[ptr++] = 'l';
+ buf[ptr++] = 't';
+ } else if (c == '>') {
+ buf[ptr++] = 'g';
+ buf[ptr++] = 't';
+ } else if (c == '\'') {
+ buf[ptr++] = 'a';
+ buf[ptr++] = 'p';
+ buf[ptr++] = 'o';
+ buf[ptr++] = 's';
+ } else if (c == '"') {
+ buf[ptr++] = 'q';
+ buf[ptr++] = 'u';
+ buf[ptr++] = 'o';
+ buf[ptr++] = 't';
+ } else {
+ buf[ptr++] = '#';;
+ buf[ptr++] = 'x';;
+ // Can use shortest quoting for tab, cr, lf:
+ if (c >= 16) {
+ int digit = (c >> 4);
+ buf[ptr++] = (char) ((digit < 10) ? ('0' + digit) : (('a' - 10) + digit));
+ c &= 0xF;
+ }
+ buf[ptr++] = (char) ((c < 10) ? ('0' + c) : (('a' - 10) + c));
+ }
+ } else {
+ buf[ptr++] = '#';
+ buf[ptr++] = 'x';
+
+ // Ok, let's write the shortest possible sequence then:
+ int shift = 20;
+ int origPtr = ptr;
+
+ do {
+ int digit = (c >> shift) & 0xF;
+ if (digit > 0 || (ptr != origPtr)) {
+ buf[ptr++] = (char) ((digit < 10) ? ('0' + digit) : (('a' - 10) + digit));
+ }
+ shift -= 4;
+ } while (shift > 0);
+ c &= 0xF;
+ buf[ptr++] = (char) ((c < 10) ? ('0' + c) : (('a' - 10) + c));
+ }
+ buf[ptr++] = ';';
+ mOutputPtr = ptr;
+ }
+}
diff -Nru libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/sw/EncodingXmlWriter.java libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/sw/EncodingXmlWriter.java
--- libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/sw/EncodingXmlWriter.java 1970-01-01 00:00:00.000000000 +0000
+++ libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/sw/EncodingXmlWriter.java 2018-03-31 01:33:28.000000000 +0000
@@ -0,0 +1,980 @@
+/* Woodstox XML processor
+ *
+ * Copyright (c) 2004- 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 com.ctc.wstx.sw;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.Writer;
+
+import javax.xml.stream.XMLStreamException;
+
+import org.codehaus.stax2.ri.typed.AsciiValueEncoder;
+import org.codehaus.stax2.validation.XMLValidator;
+
+import com.ctc.wstx.api.WriterConfig;
+import com.ctc.wstx.cfg.XmlConsts;
+//import com.ctc.wstx.io.CompletelyCloseable;
+
+/**
+ * Intermediate base class used when outputting to streams that use
+ * an encoding that is compatible with 7-bit single-byte Ascii encoding.
+ * That means it can be used for UTF-8, ISO-Latin1 and pure Ascii.
+ *
+ * Implementation notes:
+ *
+ * Parts of surrogate handling are implemented here in the base class:
+ * storage for the first part of a split surrogate (only possible when
+ * character content is output split in multiple calls) is within
+ * base class. Also, simple checks for unmatched surrogate pairs are
+ * in writeAscii
method, since it is the most convenient
+ * place to catch cases where a text segment ends with an unmatched
+ * surrogate pair half.
+ */
+public abstract class EncodingXmlWriter
+ extends XmlWriter
+{
+ /**
+ * Let's use a typical default to have a compromise between large
+ * enough chunks to output, and minimizing memory overhead.
+ * 4k should be close enough to a physical page to work out
+ * acceptably, without causing excessive (if temporary) memory usage.
+ */
+ final static int DEFAULT_BUFFER_SIZE = 4000;
+
+ final static byte BYTE_SPACE = (byte) ' ';
+ final static byte BYTE_COLON = (byte) ':';
+ final static byte BYTE_SEMICOLON = (byte) ';';
+ final static byte BYTE_LBRACKET = (byte) '[';
+ final static byte BYTE_RBRACKET = (byte) ']';
+ final static byte BYTE_QMARK = (byte) '?';
+ final static byte BYTE_EQ = (byte) '=';
+ final static byte BYTE_SLASH = (byte) '/';
+ final static byte BYTE_HASH = (byte) '#';
+ final static byte BYTE_HYPHEN = (byte) '-';
+
+ final static byte BYTE_LT = (byte) '<';
+ final static byte BYTE_GT = (byte) '>';
+ final static byte BYTE_AMP = (byte) '&';
+ final static byte BYTE_QUOT = (byte) '"';
+ final static byte BYTE_APOS = (byte) '\'';
+
+ final static byte BYTE_A = (byte) 'a';
+ final static byte BYTE_G = (byte) 'g';
+ final static byte BYTE_L = (byte) 'l';
+ final static byte BYTE_M = (byte) 'm';
+ final static byte BYTE_O = (byte) 'o';
+ final static byte BYTE_P = (byte) 'p';
+ final static byte BYTE_Q = (byte) 'q';
+ final static byte BYTE_S = (byte) 's';
+ final static byte BYTE_T = (byte) 't';
+ final static byte BYTE_U = (byte) 'u';
+ final static byte BYTE_X = (byte) 'x';
+
+ /*
+ ////////////////////////////////////////////////
+ // Output state, buffering
+ ////////////////////////////////////////////////
+ */
+
+ /**
+ * Actual output stream to use for outputting encoded content as
+ * bytes.
+ */
+ private final OutputStream mOut;
+
+ protected byte[] mOutputBuffer;
+
+ protected int mOutputPtr;
+
+ /**
+ * In case a split surrogate pair is output (which can only successfully
+ * occur with either writeRaw
or
+ * writeCharacters
), the first part is temporarily stored
+ * within this member variable.
+ */
+ protected int mSurrogate = 0;
+
+ /*
+ ////////////////////////////////////////////////
+ //
+ ////////////////////////////////////////////////
+ */
+
+ public EncodingXmlWriter(OutputStream out, WriterConfig cfg, String encoding,
+ boolean autoclose)
+ throws IOException
+ {
+ super(cfg, encoding, autoclose);
+ mOut = out;
+ mOutputBuffer = cfg.allocFullBBuffer(DEFAULT_BUFFER_SIZE);
+ mOutputPtr = 0;
+ }
+
+ /**
+ * This method is needed by the super class, to calculate hard
+ * byte/char offsets.
+ */
+ @Override
+ protected int getOutputPtr() {
+ return mOutputPtr;
+ }
+
+ /*
+ ////////////////////////////////////////////////
+ // Partial API implementation
+ ////////////////////////////////////////////////
+ */
+
+ @Override
+ final protected OutputStream getOutputStream() {
+ return mOut;
+ }
+
+ @Override
+ final protected Writer getWriter() {
+ // No writers are involved with these implementations...
+ return null;
+ }
+
+ @Override
+ public void close(boolean forceRealClose) throws IOException
+ {
+ flush();
+
+ // Buffers to free?
+ byte[] buf = mOutputBuffer;
+ if (buf != null) {
+ mOutputBuffer = null;
+ mConfig.freeFullBBuffer(buf);
+ }
+ // Plus may need to close the actual stream
+ if (forceRealClose || mAutoCloseOutput) {
+ /* 14-Nov-2008, TSa: Wrt [WSTX-163]; no need to
+ * check whether mOut implements CompletelyCloseable
+ * (unlike with BufferingXmlWriter)
+ */
+ mOut.close();
+ }
+ }
+
+ @Override
+ public final void flush() throws IOException
+ {
+ flushBuffer();
+ mOut.flush();
+ }
+
+ @Override
+ public abstract void writeRaw(char[] cbuf, int offset, int len)
+ throws IOException;
+
+ @Override
+ public abstract void writeRaw(String str, int offset, int len)
+ throws IOException;
+
+ /*
+ //////////////////////////////////////////////////
+ // "Trusted" low-level output methods (that do not
+ // need to verify validity of input)
+ //////////////////////////////////////////////////
+ */
+
+ @Override
+ public final void writeCDataStart()
+ throws IOException
+ {
+ writeAscii("");
+ }
+
+ @Override
+ public final void writeCommentStart()
+ throws IOException
+ {
+ writeAscii("");
+ }
+
+ @Override
+ public final void writePIStart(String target, boolean addSpace)
+ throws IOException
+ {
+ writeAscii(BYTE_LT, BYTE_QMARK);
+ writeRaw(target);
+ if (addSpace) {
+ writeAscii(BYTE_SPACE);
+ }
+ }
+
+ @Override
+ public final void writePIEnd() throws IOException
+ {
+ writeAscii(BYTE_QMARK, BYTE_GT);
+ }
+
+ /*
+ ////////////////////////////////////////////////
+ // Higher-level output methods, text output
+ ////////////////////////////////////////////////
+ */
+
+ @Override
+ public int writeCData(String data) throws IOException
+ {
+ writeAscii("= 0) {
+ return ix;
+ }
+ writeAscii("]]>");
+ return -1;
+ }
+
+ @Override
+ public int writeCData(char[] cbuf, int offset, int len)
+ throws IOException
+ {
+ writeAscii("= 0) {
+ return ix;
+ }
+ writeAscii("]]>");
+ return -1;
+ }
+
+ @Override
+ public final void writeCharacters(String data)
+ throws IOException
+ {
+ // Note: may get second part of a surrogate
+ if (mTextWriter != null) { // custom escaping?
+ mTextWriter.write(data);
+ } else { // nope, default:
+ writeTextContent(data);
+ }
+ }
+
+ @Override
+ public final void writeCharacters(char[] cbuf, int offset, int len)
+ throws IOException
+ {
+ // Note: may get second part of a surrogate
+ if (mTextWriter != null) { // custom escaping?
+ mTextWriter.write(cbuf, offset, len);
+ } else { // nope, default:
+ writeTextContent(cbuf, offset, len);
+ }
+ }
+
+ /**
+ * Method that will try to output the content as specified. If
+ * the content passed in has embedded "--" in it, it will either
+ * add an intervening space between consequtive hyphens (if content
+ * fixing is enabled), or return the offset of the first hyphen in
+ * multi-hyphen sequence.
+ */
+ @Override
+ public int writeComment(String data)
+ throws IOException
+ {
+ writeAscii("");
+ return -1;
+ }
+
+ @Override
+ public void writeDTD(String data)
+ throws IOException
+ {
+ if (mSurrogate != 0) {
+ throwUnpairedSurrogate();
+ }
+ writeRaw(data, 0, data.length());
+ }
+
+ @Override
+ public void writeDTD(String rootName, String systemId, String publicId,
+ String internalSubset)
+ throws IOException, XMLStreamException
+ {
+ writeAscii(" 0) {
+ writeAscii(BYTE_SPACE, BYTE_LBRACKET);
+ writeRaw(internalSubset, 0, internalSubset.length());
+ writeAscii(BYTE_RBRACKET);
+ }
+ writeAscii(BYTE_GT);
+ }
+
+ @Override
+ public void writeEntityReference(String name)
+ throws IOException, XMLStreamException
+ {
+ if (mSurrogate != 0) {
+ throwUnpairedSurrogate();
+ }
+ writeAscii(BYTE_AMP);
+ writeName(name);
+ writeAscii(BYTE_SEMICOLON);
+ }
+
+ @Override
+ public void writeXmlDeclaration(String version, String encoding, String standalone)
+ throws IOException
+ {
+ final byte byQuote = (mUseDoubleQuotesInXmlDecl ? BYTE_QUOT : BYTE_APOS);
+
+ writeAscii(" 0) {
+ writeAscii(" encoding=");
+ writeAscii(byQuote);
+ // Should be ascii, but let's play it safe:
+ writeRaw(encoding, 0, encoding.length());
+ writeAscii(byQuote);
+ }
+ if (standalone != null) {
+ writeAscii(" standalone=");
+ writeAscii(byQuote);
+ writeAscii(standalone);
+ writeAscii(byQuote);
+ }
+ writeAscii(BYTE_QMARK, BYTE_GT);
+ }
+
+ @Override
+ public int writePI(String target, String data)
+ throws IOException, XMLStreamException
+ {
+ writeAscii(BYTE_LT, BYTE_QMARK);
+ writeName(target);
+ if (data != null && data.length() > 0) {
+ writeAscii(BYTE_SPACE);
+ int ix = writePIData(data);
+ if (ix >= 0) { // embedded "?>"?
+ return ix;
+ }
+ }
+ writeAscii(BYTE_QMARK, BYTE_GT);
+ return -1;
+ }
+
+ /*
+ ////////////////////////////////////////////////////
+ // Write methods, elements
+ ////////////////////////////////////////////////////
+ */
+
+ @Override
+ public void writeStartTagStart(String localName)
+ throws IOException, XMLStreamException
+ {
+ writeAscii(BYTE_LT);
+ writeName(localName);
+ }
+
+ @Override
+ public void writeStartTagStart(String prefix, String localName)
+ throws IOException, XMLStreamException
+ {
+ if (prefix == null || prefix.length() == 0) {
+ writeStartTagStart(localName);
+ return;
+ }
+ writeAscii(BYTE_LT);
+ writeName(prefix);
+ writeAscii(BYTE_COLON);
+ writeName(localName);
+ }
+
+ @Override
+ public void writeStartTagEnd()
+ throws IOException
+ {
+ writeAscii(BYTE_GT);
+ }
+
+ @Override
+ public void writeStartTagEmptyEnd()
+ throws IOException
+ {
+ if (mAddSpaceAfterEmptyElem) {
+ writeAscii(" />");
+ } else {
+ writeAscii(BYTE_SLASH, BYTE_GT);
+ }
+ }
+
+ @Override
+ public void writeEndTag(String localName)
+ throws IOException
+ {
+ writeAscii(BYTE_LT, BYTE_SLASH);
+ /* At this point, it is assumed caller knows that end tag
+ * matches with start tag, and that it (by extension) has been
+ * validated if and as necessary
+ */
+ writeNameUnchecked(localName);
+ writeAscii(BYTE_GT);
+ }
+
+ @Override
+ public void writeEndTag(String prefix, String localName)
+ throws IOException
+ {
+ writeAscii(BYTE_LT, BYTE_SLASH);
+ /* At this point, it is assumed caller knows that end tag
+ * matches with start tag, and that it (by extension) has been
+ * validated if and as necessary
+ */
+ if (prefix != null && prefix.length() > 0) {
+ writeNameUnchecked(prefix);
+ writeAscii(BYTE_COLON);
+ }
+ writeNameUnchecked(localName);
+ writeAscii(BYTE_GT);
+ }
+
+ /*
+ ////////////////////////////////////////////////////
+ // Write methods, attributes/ns
+ ////////////////////////////////////////////////////
+ */
+
+ @Override
+ public void writeAttribute(String localName, String value)
+ throws IOException, XMLStreamException
+ {
+ writeAscii(BYTE_SPACE);
+ writeName(localName);
+ writeAscii(BYTE_EQ, BYTE_QUOT);
+
+ int len = value.length();
+ if (len > 0) {
+ if (mAttrValueWriter != null) { // custom escaping?
+ mAttrValueWriter.write(value, 0, len);
+ } else { // nope, default
+ writeAttrValue(value);
+ }
+ }
+ writeAscii(BYTE_QUOT);
+ }
+
+ @Override
+ public void writeAttribute(String localName, char[] value, int offset, int len)
+ throws IOException, XMLStreamException
+ {
+ writeAscii(BYTE_SPACE);
+ writeName(localName);
+ writeAscii(BYTE_EQ, BYTE_QUOT);
+
+ if (len > 0) {
+ if (mAttrValueWriter != null) { // custom escaping?
+ mAttrValueWriter.write(value, offset, len);
+ } else { // nope, default
+ writeAttrValue(value, offset, len);
+ }
+ }
+ writeAscii(BYTE_QUOT);
+ }
+
+ @Override
+ public void writeAttribute(String prefix, String localName, String value)
+ throws IOException, XMLStreamException
+ {
+ writeAscii(BYTE_SPACE);
+ writeName(prefix);
+ writeAscii(BYTE_COLON);
+ writeName(localName);
+ writeAscii(BYTE_EQ, BYTE_QUOT);
+
+ int len = value.length();
+ if (len > 0) {
+ if (mAttrValueWriter != null) { // custom escaping?
+ mAttrValueWriter.write(value, 0, len);
+ } else { // nope, default
+ writeAttrValue(value);
+ }
+ }
+ writeAscii(BYTE_QUOT);
+ }
+
+ @Override
+ public void writeAttribute(String prefix, String localName, char[] value, int offset, int len)
+ throws IOException, XMLStreamException
+ {
+ writeAscii(BYTE_SPACE);
+ writeName(prefix);
+ writeAscii(BYTE_COLON);
+ writeName(localName);
+ writeAscii(BYTE_EQ, BYTE_QUOT);
+
+ if (len > 0) {
+ if (mAttrValueWriter != null) { // custom escaping?
+ mAttrValueWriter.write(value, offset, len);
+ } else { // nope, default
+ writeAttrValue(value, offset, len);
+ }
+ }
+ writeAscii(BYTE_QUOT);
+ }
+
+ /*
+ ////////////////////////////////////////////////
+ // Methods used by Typed Access API
+ ////////////////////////////////////////////////
+ */
+
+ /**
+ * Non-validating version of typed write method
+ */
+ @Override
+ public final void writeTypedElement(AsciiValueEncoder enc)
+ throws IOException
+ {
+ if (mSurrogate != 0) {
+ throwUnpairedSurrogate();
+ }
+ if (enc.bufferNeedsFlush(mOutputBuffer.length - mOutputPtr)) {
+ flush();
+ }
+ while (true) {
+ mOutputPtr = enc.encodeMore(mOutputBuffer, mOutputPtr, mOutputBuffer.length);
+ // If no flushing needed, indicates that all data was encoded
+ if (enc.isCompleted()) {
+ break;
+ }
+ flush();
+ }
+ }
+
+ /**
+ * Validating version of typed write method
+ */
+ @Override
+ public final void writeTypedElement(AsciiValueEncoder enc,
+ XMLValidator validator, char[] copyBuffer)
+ throws IOException, XMLStreamException
+ {
+ if (mSurrogate != 0) {
+ throwUnpairedSurrogate();
+ }
+
+ /* Ok, this gets trickier: can't use efficient direct-to-bytes
+ * encoding since validator won't be able to use it. Instead
+ * have to use temporary copy buffer.
+ */
+ final int copyBufferLen = copyBuffer.length;
+
+ // Copy buffer should never be too small, no need to check up front
+ do {
+ int ptr = enc.encodeMore(copyBuffer, 0, copyBufferLen);
+
+ // False -> can't be sure it's the whole remaining text
+ validator.validateText(copyBuffer, 0, ptr, false);
+ writeRawAscii(copyBuffer, 0, ptr);
+ } while (!enc.isCompleted());
+ }
+
+ @Override
+ public void writeTypedAttribute(String localName, AsciiValueEncoder enc)
+ throws IOException, XMLStreamException
+ {
+ writeAscii(BYTE_SPACE);
+ writeName(localName);
+ writeAscii(BYTE_EQ, BYTE_QUOT);
+
+ if (enc.bufferNeedsFlush(mOutputBuffer.length - mOutputPtr)) {
+ flush();
+ }
+ while (true) {
+ mOutputPtr = enc.encodeMore(mOutputBuffer, mOutputPtr, mOutputBuffer.length);
+ if (enc.isCompleted()) {
+ break;
+ }
+ flush();
+ }
+ writeAscii(BYTE_QUOT);
+ }
+
+ @Override
+ public void writeTypedAttribute(String prefix, String localName,
+ AsciiValueEncoder enc)
+ throws IOException, XMLStreamException
+ {
+System.err.println("DEBUG: write typed attr/0 '"+localName+"'");
+
+ writeAscii(BYTE_SPACE);
+ writeName(prefix);
+ writeAscii(BYTE_COLON);
+ writeName(localName);
+ writeAscii(BYTE_EQ, BYTE_QUOT);
+
+ if (enc.bufferNeedsFlush(mOutputBuffer.length - mOutputPtr)) {
+ flush();
+ }
+ while (true) {
+ mOutputPtr = enc.encodeMore(mOutputBuffer, mOutputPtr, mOutputBuffer.length);
+ if (enc.isCompleted()) {
+ break;
+ }
+ flush();
+ }
+ writeAscii(BYTE_QUOT);
+ }
+
+ @Override
+ public void writeTypedAttribute(String prefix, String localName, String nsURI,
+ AsciiValueEncoder enc,
+ XMLValidator validator, char[] copyBuffer)
+ throws IOException, XMLStreamException
+ {
+ boolean hasPrefix = (prefix != null && prefix.length() > 0);
+ if (nsURI == null) {
+ nsURI = "";
+ }
+System.err.println("DEBUG: write typed attr/1 '"+localName+"', vld == "+validator);
+
+ //validator.validateAttribute(localName, nsURI, (hasPrefix ? prefix: ""), buf, offset, len);
+
+ writeAscii(BYTE_SPACE);
+ if (hasPrefix) {
+ writeName(prefix);
+ writeAscii(BYTE_COLON);
+ }
+ writeName(localName);
+ writeAscii(BYTE_EQ, BYTE_QUOT);
+
+ /* Ok, this gets trickier: can't use efficient direct-to-bytes
+ * encoding since validator won't be able to use it. Instead
+ * have to use temporary copy buffer.
+ * In addition, attributes to validate can not be
+ * split (validators expect complete values). So, if value
+ * won't fit as is, may need to aggregate using StringBuilder
+ */
+ final int copyBufferLen = copyBuffer.length;
+
+ // First, let's see if one call is enough
+ int last = enc.encodeMore(copyBuffer, 0, copyBufferLen);
+ writeRawAscii(copyBuffer, 0, last);
+ if (enc.isCompleted()) {
+ validator.validateAttribute(localName, nsURI, prefix, copyBuffer, 0, last);
+ return;
+ }
+
+ // If not, must combine first
+ StringBuilder sb = new StringBuilder(copyBufferLen << 1);
+ sb.append(copyBuffer, 0, last);
+ do {
+ last = enc.encodeMore(copyBuffer, 0, copyBufferLen);
+ writeRawAscii(copyBuffer, 0, last);
+ sb.append(copyBuffer, 0, last);
+ } while (!enc.isCompleted());
+
+ writeAscii(BYTE_QUOT);
+
+ // Then validate
+ String valueStr = sb.toString();
+ validator.validateAttribute(localName, nsURI, prefix, valueStr);
+
+ return;
+ }
+
+ /*
+ ////////////////////////////////////////////////
+ // Methods for sub-classes to use
+ ////////////////////////////////////////////////
+ */
+
+ protected final void flushBuffer()
+ throws IOException
+ {
+ if (mOutputPtr > 0 && mOutputBuffer != null) {
+ int ptr = mOutputPtr;
+ mOutputPtr = 0;
+ mOut.write(mOutputBuffer, 0, ptr);
+ }
+ }
+
+ protected final void writeAscii(byte b)
+ throws IOException
+ {
+ if (mSurrogate != 0) {
+ throwUnpairedSurrogate();
+ }
+ if (mOutputPtr >= mOutputBuffer.length) {
+ flushBuffer();
+ }
+ mOutputBuffer[mOutputPtr++] = b;
+ }
+
+ protected final void writeAscii(byte b1, byte b2)
+ throws IOException
+ {
+ if (mSurrogate != 0) {
+ throwUnpairedSurrogate();
+ }
+ if ((mOutputPtr + 1) >= mOutputBuffer.length) {
+ flushBuffer();
+ }
+ mOutputBuffer[mOutputPtr++] = b1;
+ mOutputBuffer[mOutputPtr++] = b2;
+ }
+
+ protected final void writeAscii(String str)
+ throws IOException
+ {
+ if (mSurrogate != 0) {
+ throwUnpairedSurrogate();
+ }
+
+ int len = str.length();
+ int ptr = mOutputPtr;
+ byte[] buf = mOutputBuffer;
+ if ((ptr + len) >= buf.length) {
+ /* It's even possible that String is longer than the buffer (not
+ * likely, possible). If so, let's just call the full
+ * method:
+ */
+ if (len > buf.length) {
+ writeRaw(str, 0, len);
+ return;
+ }
+ flushBuffer();
+ ptr = mOutputPtr;
+ }
+ mOutputPtr += len;
+ for (int i = 0; i < len; ++i) {
+ buf[ptr++] = (byte)str.charAt(i);
+ }
+ }
+
+ @Override
+ public final void writeRawAscii(char[] buf, int offset, int len)
+ throws IOException
+ {
+ if (mSurrogate != 0) {
+ throwUnpairedSurrogate();
+ }
+ int ptr = mOutputPtr;
+ byte[] dst = mOutputBuffer;
+ if ((ptr + len) >= dst.length) {
+ if (len > dst.length) {
+ writeRaw(buf, offset, len);
+ return;
+ }
+ flushBuffer();
+ ptr = mOutputPtr;
+ }
+ mOutputPtr += len;
+ for (int i = 0; i < len; ++i) {
+ dst[ptr+i] = (byte)buf[offset+i];
+ }
+ }
+
+ /**
+ * Entity writing can be optimized quite nicely, since it only
+ * needs to output ascii characters.
+ *
+ * @return New value of mOutputPtr
+ */
+ protected final int writeAsEntity(int c)
+ throws IOException
+ {
+ byte[] buf = mOutputBuffer;
+ int ptr = mOutputPtr;
+ if ((ptr + 10) >= buf.length) { // [up to 6 hex digits] ;
+ flushBuffer();
+ ptr = mOutputPtr;
+ }
+ buf[ptr++] = BYTE_AMP;
+
+ // Can use more optimal notation for 8-bit ascii stuff:
+ if (c < 256) {
+ /* Also; although not really mandatory, let's also
+ * use pre-defined entities where possible.
+ */
+ if (c == '&') {
+ buf[ptr++] = BYTE_A;
+ buf[ptr++] = BYTE_M;
+ buf[ptr++] = BYTE_P;
+ } else if (c == '<') {
+ buf[ptr++] = BYTE_L;
+ buf[ptr++] = BYTE_T;
+ } else if (c == '>') {
+ buf[ptr++] = BYTE_G;
+ buf[ptr++] = BYTE_T;
+ } else if (c == '\'') {
+ buf[ptr++] = BYTE_A;
+ buf[ptr++] = BYTE_P;
+ buf[ptr++] = BYTE_O;
+ buf[ptr++] = BYTE_S;
+ } else if (c == '"') {
+ buf[ptr++] = BYTE_Q;
+ buf[ptr++] = BYTE_U;
+ buf[ptr++] = BYTE_O;
+ buf[ptr++] = BYTE_T;
+ } else {
+ buf[ptr++] = BYTE_HASH;
+ buf[ptr++] = BYTE_X;
+ // Can use shortest quoting for tab, cr, lf:
+ if (c >= 16) {
+ int digit = (c >> 4);
+ buf[ptr++] = (byte) ((digit < 10) ? ('0' + digit) : (('a' - 10) + digit));
+ c &= 0xF;
+ }
+ buf[ptr++] = (byte) ((c < 10) ? ('0' + c) : (('a' - 10) + c));
+ }
+ } else {
+ buf[ptr++] = BYTE_HASH;
+ buf[ptr++] = BYTE_X;
+
+ // Ok, let's write the shortest possible sequence then:
+ int shift = 20;
+ int origPtr = ptr;
+
+ do {
+ int digit = (c >> shift) & 0xF;
+ if (digit > 0 || (ptr != origPtr)) {
+ buf[ptr++] = (byte) ((digit < 10) ? ('0' + digit) : (('a' - 10) + digit));
+ }
+ shift -= 4;
+ } while (shift > 0);
+ c &= 0xF;
+ buf[ptr++] = (byte) ((c < 10) ? ('0' + c) : (('a' - 10) + c));
+ }
+ buf[ptr++] = BYTE_SEMICOLON;
+ mOutputPtr = ptr;
+ return ptr;
+ }
+
+ protected final void writeName(String name)
+ throws IOException, XMLStreamException
+ {
+ if (mCheckNames) {
+ verifyNameValidity(name, mNsAware);
+ }
+ // TODO: maybe we could reuse some previously encoded names?
+ writeRaw(name, 0, name.length());
+ }
+
+ protected final void writeNameUnchecked(String name)
+ throws IOException
+ {
+ writeRaw(name, 0, name.length());
+ }
+
+ protected final int calcSurrogate(int secondSurr)
+ throws IOException
+ {
+ // First, let's verify first surrogate is valid:
+ int firstSurr = mSurrogate;
+ mSurrogate = 0;
+ if (firstSurr < SURR1_FIRST || firstSurr > SURR1_LAST) {
+ throwUnpairedSurrogate(firstSurr);
+ }
+
+ // Then that the second one is:
+ if ((secondSurr < SURR2_FIRST) || (secondSurr > SURR2_LAST)) {
+ throwUnpairedSurrogate(secondSurr);
+ }
+ int ch = 0x10000 + ((firstSurr - SURR1_FIRST) << 10) + (secondSurr - SURR2_FIRST);
+ if (ch > XmlConsts.MAX_UNICODE_CHAR) {
+ throw new IOException("Illegal surrogate character pair, resulting code 0x"+Integer.toHexString(ch)+" above legal XML character range");
+ }
+ return ch;
+ }
+
+ protected final void throwUnpairedSurrogate()
+ throws IOException
+ {
+ int surr = mSurrogate;
+ mSurrogate = 0;
+ throwUnpairedSurrogate(surr);
+ }
+
+ protected final void throwUnpairedSurrogate(int code)
+ throws IOException
+{
+ // Let's flush to make debugging easier
+ flush();
+ throw new IOException("Unpaired surrogate character (0x"+Integer.toHexString(code)+")");
+}
+
+ /*
+ ////////////////////////////////////////////////
+ // Abstract methods for sub-classes to define
+ ////////////////////////////////////////////////
+ */
+
+ protected abstract void writeAttrValue(String data)
+ throws IOException;
+
+ protected abstract void writeAttrValue(char[] value, int offset, int len)
+ throws IOException;
+
+ protected abstract int writeCDataContent(String data)
+ throws IOException;
+
+ protected abstract int writeCDataContent(char[] cbuf, int start, int len)
+ throws IOException;
+
+ protected abstract int writeCommentContent(String data)
+ throws IOException;
+
+ protected abstract int writePIData(String data)
+ throws IOException, XMLStreamException;
+
+ protected abstract void writeTextContent(String data)
+ throws IOException;
+
+ protected abstract void writeTextContent(char[] cbuf, int start, int len)
+ throws IOException;
+}
diff -Nru libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/sw/ISOLatin1XmlWriter.java libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/sw/ISOLatin1XmlWriter.java
--- libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/sw/ISOLatin1XmlWriter.java 1970-01-01 00:00:00.000000000 +0000
+++ libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/sw/ISOLatin1XmlWriter.java 2018-03-31 01:33:28.000000000 +0000
@@ -0,0 +1,801 @@
+/* Woodstox XML processor
+ *
+ * Copyright (c) 2004- 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 com.ctc.wstx.sw;
+
+import java.io.*;
+
+import javax.xml.stream.XMLStreamException;
+
+import com.ctc.wstx.api.WriterConfig;
+import com.ctc.wstx.io.CharsetNames;
+
+/**
+ * Concrete implementation of {@link EncodingXmlWriter} used when output
+ * is to be encoded using ISO-8859-1, aka ISO-Latin1 encoding.
+ *
+ * Regarding surrogate pair handling: most of the checks are in the base
+ * class, and here we only need to worry about writeRaw
+ * methods.
+ */
+public final class ISOLatin1XmlWriter
+ extends EncodingXmlWriter
+{
+ public ISOLatin1XmlWriter(OutputStream out, WriterConfig cfg, boolean autoclose)
+ throws IOException
+ {
+ super(out, cfg, CharsetNames.CS_ISO_LATIN1, autoclose);
+ }
+
+ @Override
+ public void writeRaw(char[] cbuf, int offset, int len)
+ throws IOException
+ {
+ if (mSurrogate != 0) {
+ throwUnpairedSurrogate();
+ }
+
+ int ptr = mOutputPtr;
+ while (len > 0) {
+ int max = mOutputBuffer.length - ptr;
+ if (max < 1) { // output buffer full?
+ mOutputPtr = ptr;
+ flushBuffer();
+ ptr = 0;
+ max = mOutputBuffer.length;
+ }
+ // How much can we output?
+ if (max > len) {
+ max = len;
+ }
+ if (mCheckContent) {
+ for (int inEnd = offset + max; offset < inEnd; ++offset) {
+ int c = cbuf[offset];
+ if (c < 32) {
+ if (c == '\n') {
+ // !!! TBI: line nr
+ } else if (c == '\r') {
+ // !!! TBI: line nr (and skipping \n that may follow)
+ } else if (c != '\t') {
+ mOutputPtr = ptr;
+ c = handleInvalidChar(c);
+ }
+ } else if (c > 0x7E) {
+ if (c > 0xFF) {
+ mOutputPtr = ptr;
+ handleInvalidLatinChar(c);
+ } else if (mXml11) {
+ if (c < 0x9F && c != 0x85) {
+ mOutputPtr = ptr;
+ c = handleInvalidChar(c);
+ }
+ }
+ }
+ mOutputBuffer[ptr++] = (byte) c;
+ }
+ } else {
+ for (int inEnd = offset + max; offset < inEnd; ++offset) {
+ mOutputBuffer[ptr++] = (byte) cbuf[offset];
+ }
+ }
+ len -= max;
+ }
+ mOutputPtr = ptr;
+ }
+
+ @Override
+ public void writeRaw(String str, int offset, int len)
+ throws IOException
+ {
+ if (mSurrogate != 0) {
+ throwUnpairedSurrogate();
+ }
+ int ptr = mOutputPtr;
+ while (len > 0) {
+ int max = mOutputBuffer.length - ptr;
+ if (max < 1) { // output buffer full?
+ mOutputPtr = ptr;
+ flushBuffer();
+ ptr = 0;
+ max = mOutputBuffer.length;
+ }
+ // How much can we output?
+ if (max > len) {
+ max = len;
+ }
+ if (mCheckContent) {
+ for (int inEnd = offset + max; offset < inEnd; ++offset) {
+ int c = str.charAt(offset);
+ if (c < 32) {
+ if (c == '\n') {
+ // !!! TBI: line nr
+ } else if (c == '\r') {
+ // !!! TBI: line nr (and skipping \n that may follow)
+ } else if (c != '\t') {
+ mOutputPtr = ptr;
+ c = handleInvalidChar(c);
+ }
+ } else if (c > 0x7E) {
+ if (c > 0xFF) {
+ mOutputPtr = ptr;
+ handleInvalidLatinChar(c);
+ } else if (mXml11) {
+ if (c < 0x9F && c != 0x85) {
+ mOutputPtr = ptr;
+ c = handleInvalidChar(c);
+ }
+ }
+ }
+ mOutputBuffer[ptr++] = (byte) c;
+ }
+ } else {
+ for (int inEnd = offset + max; offset < inEnd; ++offset) {
+ mOutputBuffer[ptr++] = (byte) str.charAt(offset);
+ }
+ }
+ len -= max;
+ }
+ mOutputPtr = ptr;
+ }
+
+ @Override
+ protected void writeAttrValue(String data)
+ throws IOException
+ {
+ int offset = 0;
+ int len = data.length();
+ int ptr = mOutputPtr;
+
+ main_loop:
+ while (len > 0) {
+ int max = mOutputBuffer.length - ptr;
+ if (max < 1) { // output buffer full?
+ mOutputPtr = ptr;
+ flushBuffer();
+ ptr = 0;
+ max = mOutputBuffer.length;
+ }
+ // Do we start with a surrogate?
+ if (mSurrogate != 0) {
+ int sec = data.charAt(offset++);
+ sec = calcSurrogate(sec);
+ mOutputPtr = ptr;
+ ptr = writeAsEntity(sec);
+ --len;
+ continue main_loop;
+ }
+ // How much can we output?
+ if (max > len) {
+ max = len;
+ }
+ inner_loop:
+ for (int inEnd = offset + max; offset < inEnd; ) {
+ int c = data.charAt(offset++);
+ if (c < 32) {
+ /* Need to quote all white space except for regular
+ * space chars, to preserve them (round-tripping)
+ */
+ if (c == '\r') {
+ if (!mEscapeCR) {
+ mOutputBuffer[ptr++] = (byte) c;
+ continue;
+ }
+ } else if (c != '\n' && c != '\t') {
+ if (mCheckContent) {
+ if (!mXml11 || c == 0) {
+ c = handleInvalidChar(c);
+ mOutputBuffer[ptr++] = (byte) c;
+ continue;
+ }
+ }
+ }
+ // fall-through to char entity output
+ } else if (c < 0x7F) {
+ if (c != '<' && c != '&' && c != '"') {
+ mOutputBuffer[ptr++] = (byte) c;
+ continue;
+ }
+ // otherwise fall back on quoting
+ } else if (c > 0x9F && c <= 0xFF) {
+ mOutputBuffer[ptr++] = (byte) c;
+ continue; // [WSTX-88]
+ } else {
+ // Surrogate?
+ if (c >= SURR1_FIRST && c <= SURR2_LAST) {
+ mSurrogate = c;
+ // Last char needs special handling:
+ if (offset == inEnd) {
+ break inner_loop;
+ }
+ c = calcSurrogate(data.charAt(offset++));
+ // Let's fall down to entity output
+ }
+ }
+ /* Has to be escaped as char entity; as such, also need
+ * to re-calc max. continguous data we can output
+ */
+ mOutputPtr = ptr;
+ ptr = writeAsEntity(c);
+ len = data.length() - offset;
+ continue main_loop;
+ }
+ len -= max;
+ }
+ mOutputPtr = ptr;
+ }
+
+ @Override
+ protected void writeAttrValue(char[] data, int offset, int len)
+ throws IOException
+ {
+ int ptr = mOutputPtr;
+
+ main_loop:
+ while (len > 0) {
+ int max = mOutputBuffer.length - ptr;
+ if (max < 1) { // output buffer full?
+ mOutputPtr = ptr;
+ flushBuffer();
+ ptr = 0;
+ max = mOutputBuffer.length;
+ }
+ // Do we start with a surrogate?
+ if (mSurrogate != 0) {
+ int sec = data[offset++];
+ sec = calcSurrogate(sec);
+ mOutputPtr = ptr;
+ ptr = writeAsEntity(sec);
+ --len;
+ continue main_loop;
+ }
+ // How much can we output?
+ if (max > len) {
+ max = len;
+ }
+ inner_loop:
+ for (int inEnd = offset + max; offset < inEnd; ) {
+ int c = data[offset++];
+ if (c < 32) {
+ /* Need to quote all white space except for regular
+ * space chars, to preserve them (round-tripping)
+ */
+ if (c == '\r') {
+ if (!mEscapeCR) {
+ mOutputBuffer[ptr++] = (byte) c;
+ continue;
+ }
+ } else if (c != '\n' && c != '\t') {
+ if (mCheckContent) {
+ if (!mXml11 || c == 0) {
+ c = handleInvalidChar(c);
+ mOutputBuffer[ptr++] = (byte) c;
+ continue;
+ }
+ }
+ }
+ // fall-through to char entity output
+ } else if (c < 0x7F) {
+ if (c != '<' && c != '&' && c != '"') {
+ mOutputBuffer[ptr++] = (byte) c;
+ continue;
+ }
+ // otherwise fall back on quoting
+ } else if (c > 0x9F && c <= 0xFF) {
+ mOutputBuffer[ptr++] = (byte) c;
+ continue; // [WSTX-88]
+ } else {
+ // Surrogate?
+ if (c >= SURR1_FIRST && c <= SURR2_LAST) {
+ mSurrogate = c;
+ // Last char needs special handling:
+ if (offset == inEnd) {
+ break inner_loop;
+ }
+ c = calcSurrogate(data[offset++]);
+ // Let's fall down to entity output
+ }
+ }
+ /* Has to be escaped as char entity; as such, also need
+ * to re-calc max. contiguous data we can output
+ */
+ mOutputPtr = ptr;
+ ptr = writeAsEntity(c);
+ max -= (inEnd - offset); // since we didn't loop completely
+ break inner_loop;
+ }
+ len -= max;
+ }
+ mOutputPtr = ptr;
+ }
+
+ @Override
+ protected int writeCDataContent(String data)
+ throws IOException
+ {
+ // Note: mSurrogate can not be non-zero at this point, no need to check
+
+ int offset = 0;
+ int len = data.length();
+ if (!mCheckContent) {
+ writeRaw(data, offset, len);
+ return -1;
+ }
+ int ptr = mOutputPtr;
+
+ main_loop:
+ while (len > 0) {
+ int max = mOutputBuffer.length - ptr;
+ if (max < 1) { // output buffer full?
+ mOutputPtr = ptr;
+ flushBuffer();
+ ptr = 0;
+ max = mOutputBuffer.length;
+ }
+ // How much can we output?
+ if (max > len) {
+ max = len;
+ }
+ for (int inEnd = offset + max; offset < inEnd; ) {
+ int c = data.charAt(offset++);
+ if (c < 32) {
+ if (c == '\n') {
+ // !!! TBI: line nr
+ } else if (c == '\r') {
+ // !!! TBI: line nr (and skipping \n that may follow)
+ } else if (c != '\t') {
+ mOutputPtr = ptr;
+ c = handleInvalidChar(c);
+ }
+ } else if (c > 0x7E) {
+ if (c > 0xFF) {
+ mOutputPtr = ptr;
+ handleInvalidLatinChar(c);
+ } else if (mXml11) {
+ if (c < 0x9F && c != 0x85) {
+ mOutputPtr = ptr;
+ c = handleInvalidChar(c);
+ }
+ }
+ } else if (c == '>') { // embedded "]]>"?
+ if (offset > 2 && data.charAt(offset-2) == ']'
+ && data.charAt(offset-3) == ']') {
+ if (!mFixContent) {
+ return offset-3;
+ }
+ /* Relatively easy fix; just need to close this
+ * section, and open a new one...
+ */
+ mOutputPtr = ptr;
+ writeCDataEnd();
+ writeCDataStart();
+ writeAscii(BYTE_GT);
+ ptr = mOutputPtr;
+ /* No guarantees there's as much free room in the
+ * output buffer, thus, need to restart loop:
+ */
+ len = data.length() - offset;
+ continue main_loop;
+ }
+ }
+ mOutputBuffer[ptr++] = (byte) c;
+ }
+ len -= max;
+ }
+ mOutputPtr = ptr;
+ return -1;
+ }
+
+ @Override
+ protected int writeCDataContent(char[] cbuf, int start, int len)
+ throws IOException
+ {
+ // Note: mSurrogate can not be non-zero at this point, no need to check
+
+ if (!mCheckContent) {
+ writeRaw(cbuf, start, len);
+ return -1;
+ }
+
+ int ptr = mOutputPtr;
+ int offset = start;
+
+ while (len > 0) {
+ int max = mOutputBuffer.length - ptr;
+ if (max < 1) { // output buffer full?
+ mOutputPtr = ptr;
+ flushBuffer();
+ ptr = 0;
+ max = mOutputBuffer.length;
+ }
+ // How much can we output?
+ if (max > len) {
+ max = len;
+ }
+ inner_loop:
+ for (int inEnd = offset + max; offset < inEnd; ) {
+ int c = cbuf[offset++];
+ if (c < 32) {
+ if (c == '\n') {
+ // !!! TBI: line nr
+ } else if (c == '\r') {
+ // !!! TBI: line nr (and skipping \n that may follow)
+ } else if (c != '\t') {
+ mOutputPtr = ptr;
+ c = handleInvalidChar(c);
+ }
+ } else if (c > 0x7E) {
+ if (c > 0xFF) {
+ mOutputPtr = ptr;
+ handleInvalidLatinChar(c);
+ } else if (mXml11) {
+ if (c < 0x9F && c != 0x85) {
+ mOutputPtr = ptr;
+ c = handleInvalidChar(c);
+ }
+ }
+ } else if (c == '>') { // embedded "]]>"?
+ if (offset >= (start+3) && cbuf[offset-2] == ']'
+ && cbuf[offset-3] == ']') {
+ if (!mFixContent) {
+ return offset-3;
+ }
+ /* Relatively easy fix; just need to close this
+ * section, and open a new one...
+ */
+ mOutputPtr = ptr;
+ writeCDataEnd();
+ writeCDataStart();
+ writeAscii(BYTE_GT);
+ ptr = mOutputPtr;
+ /* No guarantees there's as much free room in the
+ * output buffer, thus, need to restart loop:
+ */
+ max -= (inEnd - offset);
+ break inner_loop;
+ }
+ }
+ mOutputBuffer[ptr++] = (byte) c;
+ }
+ len -= max;
+ }
+ mOutputPtr = ptr;
+ return -1;
+ }
+
+ @Override
+ protected int writeCommentContent(String data)
+ throws IOException
+ {
+ // Note: mSurrogate can not be non-zero at this point, no need to check
+
+ int offset = 0;
+ int len = data.length();
+ if (!mCheckContent) {
+ writeRaw(data, offset, len);
+ return -1;
+ }
+
+ int ptr = mOutputPtr;
+
+ while (len > 0) {
+ int max = mOutputBuffer.length - ptr;
+ if (max < 1) { // output buffer full?
+ mOutputPtr = ptr;
+ flushBuffer();
+ ptr = 0;
+ max = mOutputBuffer.length;
+ }
+ // How much can we output?
+ if (max > len) {
+ max = len;
+ }
+ inner_loop:
+ for (int inEnd = offset + max; offset < inEnd; ) {
+ int c = data.charAt(offset++);
+ if (c < 32) {
+ if (c == '\n') {
+ // !!! TBI: line nr
+ } else if (c == '\r') {
+ // !!! TBI: line nr (and skipping \n that may follow)
+ } else if (c != '\t') {
+ mOutputPtr = ptr;
+ c = handleInvalidChar(c);
+ }
+ } else if (c > 0x7E) {
+ if (c > 0xFF) {
+ mOutputPtr = ptr;
+ handleInvalidLatinChar(c);
+ } else if (mXml11) {
+ if (c < 0x9F && c != 0x85) {
+ mOutputPtr = ptr;
+ c = handleInvalidChar(c);
+ }
+ }
+ } else if (c == '-') { // embedded "--"?
+ if (offset > 1 && data.charAt(offset-2) == '-') {
+ if (!mFixContent) {
+ return offset-2;
+ }
+ /* Quite easy to fix: just add an extra space
+ * in front. There will be room for that char;
+ * but may need to take that the following '-'
+ * also fits.
+ */
+ mOutputBuffer[ptr++] = ' ';
+ if (ptr >= mOutputBuffer.length) { // whops. need to flush
+ mOutputPtr = ptr;
+ flushBuffer();
+ ptr = 0;
+ }
+ mOutputBuffer[ptr++] = BYTE_HYPHEN;
+ /* Also, since we did output an extra char, better
+ * restart the loop (since max calculation is now
+ * off)
+ */
+ max -= (inEnd - offset);
+ break inner_loop;
+ }
+ }
+ mOutputBuffer[ptr++] = (byte) c;
+ }
+ len -= max;
+ }
+ mOutputPtr = ptr;
+ return -1;
+ }
+
+ @Override
+ protected int writePIData(String data)
+ throws IOException, XMLStreamException
+ {
+ // Note: mSurrogate can not be non-zero at this point, no need to check
+
+ int offset = 0;
+ int len = data.length();
+ if (!mCheckContent) {
+ writeRaw(data, offset, len);
+ return -1;
+ }
+
+ int ptr = mOutputPtr;
+ while (len > 0) {
+ int max = mOutputBuffer.length - ptr;
+ if (max < 1) { // output buffer full?
+ mOutputPtr = ptr;
+ flushBuffer();
+ ptr = 0;
+ max = mOutputBuffer.length;
+ }
+ // How much can we output?
+ if (max > len) {
+ max = len;
+ }
+ for (int inEnd = offset + max; offset < inEnd; ++offset) {
+ int c = data.charAt(offset);
+ if (c < 32) {
+ if (c == '\n') {
+ // !!! TBI: line nr
+ } else if (c == '\r') {
+ // !!! TBI: line nr (and skipping \n that may follow)
+ } else if (c != '\t') {
+ mOutputPtr = ptr;
+ c = handleInvalidChar(c);
+ }
+ } else if (c > 0x7E) {
+ if (c > 0xFF) {
+ mOutputPtr = ptr;
+ handleInvalidLatinChar(c);
+ } else if (mXml11) {
+ if (c < 0x9F && c != 0x85) {
+ mOutputPtr = ptr;
+ c = handleInvalidChar(c);
+ }
+ }
+ } else if (c == '>') { // enclosed end marker ("?>")?
+ if (offset > 0 && data.charAt(offset-1) == '?') {
+ return offset-2;
+ }
+ }
+ mOutputBuffer[ptr++] = (byte) c;
+ }
+ len -= max;
+ }
+ mOutputPtr = ptr;
+ return -1;
+ }
+
+ @Override
+ protected void writeTextContent(String data)
+ throws IOException
+ {
+ int offset = 0;
+ int len = data.length();
+
+ main_loop:
+ while (len > 0) {
+ int max = mOutputBuffer.length - mOutputPtr;
+ if (max < 1) { // output buffer full?
+ flushBuffer();
+ max = mOutputBuffer.length;
+ }
+ // Do we start with a surrogate?
+ if (mSurrogate != 0) {
+ int sec = data.charAt(offset++);
+ sec = calcSurrogate(sec);
+ writeAsEntity(sec);
+ --len;
+ continue main_loop;
+ }
+ // How much can we output?
+ if (max > len) {
+ max = len;
+ }
+ inner_loop:
+ for (int inEnd = offset + max; offset < inEnd; ) {
+ int c = data.charAt(offset++);
+ if (c < 32) {
+ if (c == '\n' || c == '\t') { // TODO: line count
+ mOutputBuffer[mOutputPtr++] = (byte) c;
+ continue;
+ } else if (c == '\r') {
+ if (!mEscapeCR) {
+ mOutputBuffer[mOutputPtr++] = (byte) c;
+ continue;
+ }
+ } else if (!mXml11 || c == 0) { // ok in xml1.1, as entity
+ if (mCheckContent) {
+ c = handleInvalidChar(c);
+ mOutputBuffer[mOutputPtr++] = (byte) c;
+ continue;
+ }
+ // otherwise... well, I guess we can just escape it
+ }
+ // \r, or xml1.1 + other whitespace, need to escape
+ } else if (c < 0x7F) {
+ if (c != '<' && c != '&') {
+ if (c != '>' || (offset > 1 && data.charAt(offset-2) != ']')) {
+ mOutputBuffer[mOutputPtr++] = (byte) c;
+ continue;
+ }
+ }
+ // otherwise fall back on quoting
+ } else if (c > 0x9F && c <= 0xFF) {
+ mOutputBuffer[mOutputPtr++] = (byte) c;
+ continue; // [WSTX-88]
+ } else {
+ // Surrogate?
+ if (c >= SURR1_FIRST && c <= SURR2_LAST) {
+ mSurrogate = c;
+ // Last char needs special handling:
+ if (offset == inEnd) {
+ break inner_loop;
+ }
+ c = calcSurrogate(data.charAt(offset++));
+ // Let's fall down to entity output
+ }
+ }
+ /* Has to be escaped as char entity; as such, also need
+ * to re-calc max. continguous data we can output
+ */
+ writeAsEntity(c);
+ len = data.length() - offset;
+ continue main_loop;
+ }
+ len -= max;
+ }
+ }
+
+ @Override
+ protected void writeTextContent(char[] cbuf, int offset, int len)
+ throws IOException
+ {
+ main_loop:
+ while (len > 0) {
+ int max = mOutputBuffer.length - mOutputPtr;
+ if (max < 1) { // output buffer full?
+ flushBuffer();
+ max = mOutputBuffer.length;
+ }
+ // Do we start with a surrogate?
+ if (mSurrogate != 0) {
+ int sec = cbuf[offset++];
+ sec = calcSurrogate(sec);
+ writeAsEntity(sec);
+ --len;
+ continue main_loop;
+ }
+ // How much can we output?
+ if (max > len) {
+ max = len;
+ }
+ inner_loop:
+ for (int inEnd = offset + max; offset < inEnd; ) {
+ int c = cbuf[offset++];
+ if (c < 32) {
+ if (c == '\n' || c == '\t') { // TODO: line count
+ mOutputBuffer[mOutputPtr++] = (byte) c;
+ continue;
+ } else if (c == '\r') {
+ if (!mEscapeCR) {
+ mOutputBuffer[mOutputPtr++] = (byte) c;
+ continue;
+ }
+ } else if (!mXml11 || c == 0) { // ok in xml1.1, as entity
+ if (mCheckContent) {
+ c = handleInvalidChar(c);
+ mOutputBuffer[mOutputPtr++] = (byte) c;
+ continue;
+ }
+ // otherwise... well, I guess we can just escape it
+ }
+ // \r, or xml1.1 + other whitespace, need to escape
+ } else if (c < 0x7F) {
+ if (c !='<' && c != '&') {
+ /* Since we can be conservative, it doesn't matter
+ * if second check is not exact
+ */
+ if (c != '>' || (offset > 1 && cbuf[offset-2] != ']')) {
+ mOutputBuffer[mOutputPtr++] = (byte) c;
+ continue;
+ }
+ }
+ // otherwise fall back on quoting
+ } else if (c > 0x9F && c <= 0xFF) {
+ mOutputBuffer[mOutputPtr++] = (byte) c;
+ continue; // [WSTX-88]
+ } else {
+ // Surrogate?
+ if (c >= SURR1_FIRST && c <= SURR2_LAST) {
+ mSurrogate = c;
+ // Last char needs special handling:
+ if (offset == inEnd) {
+ break inner_loop;
+ }
+ c = calcSurrogate(cbuf[offset++]);
+ // Let's fall down to entity output
+ }
+ }
+ /* Has to be escaped as char entity; as such, also need
+ * to re-calc max. continguous data we can output
+ */
+ writeAsEntity(c);
+ max -= (inEnd - offset);
+ break inner_loop;
+ }
+ len -= max;
+ }
+ }
+
+ /*
+ ////////////////////////////////////////////////////
+ // Internal methods
+ ////////////////////////////////////////////////////
+ */
+
+ protected void handleInvalidLatinChar(int c)
+ throws IOException
+ {
+ // First, let's flush any output we may have, to make debugging easier
+ flush();
+
+ /* 17-May-2006, TSa: Would really be useful if we could throw
+ * XMLStreamExceptions; esp. to indicate actual output location.
+ * However, this causes problem with methods that call us and
+ * can only throw IOExceptions (when invoked via Writer proxy).
+ * Need to figure out how to resolve this.
+ */
+ throw new IOException("Invalid XML character (0x"+Integer.toHexString(c)+"); can only be output using character entity when using ISO-8859-1 encoding");
+ }
+}
diff -Nru libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/sw/NonNsStreamWriter.java libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/sw/NonNsStreamWriter.java
--- libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/sw/NonNsStreamWriter.java 1970-01-01 00:00:00.000000000 +0000
+++ libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/sw/NonNsStreamWriter.java 2018-03-31 01:33:28.000000000 +0000
@@ -0,0 +1,564 @@
+/* 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 com.ctc.wstx.sw;
+
+import java.io.IOException;
+import java.util.*;
+
+import javax.xml.XMLConstants;
+import javax.xml.namespace.NamespaceContext;
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLStreamWriter;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.events.Attribute;
+import javax.xml.stream.events.StartElement;
+
+import org.codehaus.stax2.ri.typed.AsciiValueEncoder;
+
+import com.ctc.wstx.api.WriterConfig;
+import com.ctc.wstx.cfg.ErrorConsts;
+import com.ctc.wstx.cfg.XmlConsts;
+import com.ctc.wstx.sr.AttributeCollector;
+import com.ctc.wstx.sr.InputElementStack;
+import com.ctc.wstx.util.EmptyNamespaceContext;
+import com.ctc.wstx.util.StringVector;
+
+/**
+ * Implementation of {@link XMLStreamWriter} used when namespace support
+ * is not enabled. This means that only local names are used for elements
+ * and attributes; and if rudimentary namespace declarations need to be
+ * output, they are output using attribute writing methods.
+ */
+public class NonNsStreamWriter
+ extends TypedStreamWriter
+{
+ /*
+ ////////////////////////////////////////////////////
+ // State information
+ ////////////////////////////////////////////////////
+ */
+
+ /**
+ * Stack of currently open start elements; only local names
+ * are included.
+ */
+ final StringVector mElements;
+
+ /**
+ * Container for attribute names for current element; used only
+ * if uniqueness of attribute names is to be enforced.
+ *
+ * TreeSet is used mostly because clearing it up is faster than
+ * clearing up HashSet, and the only access is done by
+ * adding entries and see if an value was already set.
+ */
+ TreeSet mAttrNames;
+
+ /*
+ ////////////////////////////////////////////////////
+ // Life-cycle (ctors)
+ ////////////////////////////////////////////////////
+ */
+
+ public NonNsStreamWriter(XmlWriter xw, String enc, WriterConfig cfg)
+ {
+ super(xw, enc, cfg);
+ mElements = new StringVector(32);
+ }
+
+ /*
+ ////////////////////////////////////////////////////
+ // XMLStreamWriter API
+ ////////////////////////////////////////////////////
+ */
+
+ @Override
+ public NamespaceContext getNamespaceContext() {
+ return EmptyNamespaceContext.getInstance();
+ }
+
+ @Override
+ public String getPrefix(String uri) {
+ return null;
+ }
+
+ @Override
+ public void setDefaultNamespace(String uri)
+ throws XMLStreamException
+ {
+ reportIllegalArg("Can not set default namespace for non-namespace writer.");
+ }
+
+ @Override
+ public void setNamespaceContext(NamespaceContext context) {
+ reportIllegalArg("Can not set NamespaceContext for non-namespace writer.");
+ }
+
+ @Override
+ public void setPrefix(String prefix, String uri) throws XMLStreamException
+ {
+ reportIllegalArg("Can not set namespace prefix for non-namespace writer.");
+ }
+
+ @Override
+ public void writeAttribute(String localName, String value)
+ throws XMLStreamException
+ {
+ // No need to set mAnyOutput, nor close the element
+ if (!mStartElementOpen && mCheckStructure) {
+ reportNwfStructure(ErrorConsts.WERR_ATTR_NO_ELEM);
+ }
+ if (mCheckAttrs) {
+ /* 11-Dec-2005, TSa: Should use a more efficient Set/Map value
+ * for this in future.
+ */
+ if (mAttrNames == null) {
+ mAttrNames = new TreeSet();
+ }
+ if (!mAttrNames.add(localName)) {
+ reportNwfAttr("Trying to write attribute '"+localName+"' twice");
+ }
+ }
+ if (mValidator != null) {
+ /* No need to get it normalized... even if validator does normalize
+ * it, we don't use that for anything
+ */
+ mValidator.validateAttribute(localName, XmlConsts.ATTR_NO_NS_URI, XmlConsts.ATTR_NO_PREFIX, value);
+ }
+
+ try {
+ mWriter.writeAttribute(localName, value);
+ } catch (IOException ioe) {
+ throwFromIOE(ioe);
+ }
+ }
+
+ @Override
+ public void writeAttribute(String nsURI, String localName, String value)
+ throws XMLStreamException
+ {
+ writeAttribute(localName, value);
+ }
+
+ @Override
+ public void writeAttribute(String prefix, String nsURI,
+ String localName, String value)
+ throws XMLStreamException
+ {
+ writeAttribute(localName, value);
+ }
+
+ @Override
+ public void writeDefaultNamespace(String nsURI) throws XMLStreamException
+ {
+ reportIllegalMethod("Can not call writeDefaultNamespace namespaces with non-namespace writer.");
+ }
+
+ @Override
+ public void writeEmptyElement(String localName) throws XMLStreamException
+ {
+ doWriteStartElement(localName);
+ mEmptyElement = true;
+ }
+
+ @Override
+ public void writeEmptyElement(String nsURI, String localName) throws XMLStreamException
+ {
+ writeEmptyElement(localName);
+ }
+
+ @Override
+ public void writeEmptyElement(String prefix, String localName, String nsURI) throws XMLStreamException
+ {
+ writeEmptyElement(localName);
+ }
+
+ @Override
+ public void writeEndElement() throws XMLStreamException {
+ doWriteEndTag(null, mCfgAutomaticEmptyElems);
+ }
+
+ @Override
+ public void writeNamespace(String prefix, String nsURI) throws XMLStreamException
+ {
+ reportIllegalMethod("Can not set write namespaces with non-namespace writer.");
+ }
+
+ @Override
+ public void writeStartElement(String localName) throws XMLStreamException
+ {
+ doWriteStartElement(localName);
+ mEmptyElement = false;
+ }
+
+ @Override
+ public void writeStartElement(String nsURI, String localName) throws XMLStreamException {
+ writeStartElement(localName);
+ }
+
+ @Override
+ public void writeStartElement(String prefix, String localName, String nsURI)
+ throws XMLStreamException
+ {
+ writeStartElement(localName);
+ }
+
+ /*
+ ////////////////////////////////////////////////////
+ // Remaining XMLStreamWriter2 methods (StAX2)
+ ////////////////////////////////////////////////////
+ */
+
+ /**
+ * Similar to {@link #writeEndElement}, but never allows implicit
+ * creation of empty elements.
+ */
+ @Override
+ public void writeFullEndElement() throws XMLStreamException {
+ doWriteEndTag(null, false);
+ }
+
+ /*
+ ////////////////////////////////////////////////////
+ // Remaining ValidationContext methods (StAX2)
+ ////////////////////////////////////////////////////
+ */
+
+ @Override
+ public QName getCurrentElementName() {
+ if (mElements.isEmpty()) {
+ return null;
+ }
+ return new QName(mElements.getLastString());
+ }
+
+ @Override
+ public String getNamespaceURI(String prefix) {
+ return null;
+ }
+
+ /*
+ ////////////////////////////////////////////////////
+ // Package methods:
+ ////////////////////////////////////////////////////
+ */
+
+ @Override
+ public void writeStartElement(StartElement elem)
+ throws XMLStreamException
+ {
+ QName name = elem.getName();
+ writeStartElement(name.getLocalPart());
+ @SuppressWarnings("unchecked")
+ Iterator it = elem.getAttributes();
+ while (it.hasNext()) {
+ Attribute attr = it.next();
+ name = attr.getName();
+ writeAttribute(name.getLocalPart(), attr.getValue());
+ }
+ }
+
+ /**
+ * Method called by {@link javax.xml.stream.XMLEventWriter} implementation
+ * (instead of the version
+ * that takes no argument), so that we can verify it does match the
+ * start element, if necessary
+ */
+ @Override
+ public void writeEndElement(QName name) throws XMLStreamException
+ {
+ doWriteEndTag(mCheckStructure ? name.getLocalPart() : null,
+ mCfgAutomaticEmptyElems);
+ }
+
+ @Override
+ protected void writeTypedAttribute(String prefix, String nsURI, String localName,
+ AsciiValueEncoder enc)
+ throws XMLStreamException
+ {
+ // note: mostly copied from the other writeAttribute() method..
+ if (!mStartElementOpen && mCheckStructure) {
+ reportNwfStructure(ErrorConsts.WERR_ATTR_NO_ELEM);
+ }
+ if (mCheckAttrs) { // doh. Not good, need to construct non-transient value...
+ if (mAttrNames == null) {
+ mAttrNames = new TreeSet();
+ }
+ if (!mAttrNames.add(localName)) {
+ reportNwfAttr("Trying to write attribute '"+localName+"' twice");
+ }
+ }
+
+ try {
+ if (mValidator == null) {
+ mWriter.writeTypedAttribute(localName, enc);
+ } else {
+ mWriter.writeTypedAttribute(null, localName, null, enc, mValidator, getCopyBuffer());
+ }
+ } catch (IOException ioe) {
+ throwFromIOE(ioe);
+ }
+ }
+
+ /**
+ * Method called to close an open start element, when another
+ * main-level element (not namespace declaration or
+ * attribute) is being output; except for end element which is
+ * handled differently.
+ */
+ @Override
+ protected void closeStartElement(boolean emptyElem)
+ throws XMLStreamException
+ {
+ mStartElementOpen = false;
+ if (mAttrNames != null) {
+ mAttrNames.clear();
+ }
+
+ try {
+ if (emptyElem) {
+ mWriter.writeStartTagEmptyEnd();
+ } else {
+ mWriter.writeStartTagEnd();
+ }
+ } catch (IOException ioe) {
+ throwFromIOE(ioe);
+ }
+
+ if (mValidator != null) {
+ mVldContent = mValidator.validateElementAndAttributes();
+ }
+
+ // Need bit more special handling for empty elements...
+ if (emptyElem) {
+ String localName = mElements.removeLast();
+ if (mElements.isEmpty()) {
+ mState = STATE_EPILOG;
+ }
+ if (mValidator != null) {
+ mVldContent = mValidator.validateElementEnd(localName, XmlConsts.ELEM_NO_NS_URI, XmlConsts.ELEM_NO_PREFIX);
+ }
+ }
+ }
+
+ /**
+ * Element copier method implementation suitable to be used with
+ * non-namespace-aware writers. The only special thing here is that
+ * the copier can convert namespace declarations to equivalent
+ * attribute writes.
+ */
+ @Override
+ public void copyStartElement(InputElementStack elemStack,
+ AttributeCollector attrCollector)
+ throws IOException, XMLStreamException
+ {
+ String ln = elemStack.getLocalName();
+ boolean nsAware = elemStack.isNamespaceAware();
+
+ /* First, since we are not to output namespace stuff as is,
+ * we just need to copy the element:
+ */
+ if (nsAware) { // but reader is ns-aware? Need to add prefix?
+ String prefix = elemStack.getPrefix();
+ if (prefix != null && prefix.length() > 0) { // yup
+ ln = prefix + ":" + ln;
+ }
+ }
+ writeStartElement(ln);
+
+ /* However, if there are any namespace declarations, we probably
+ * better output them just as 'normal' attributes:
+ */
+ if (nsAware) {
+ int nsCount = elemStack.getCurrentNsCount();
+ if (nsCount > 0) {
+ for (int i = 0; i < nsCount; ++i) {
+ String prefix = elemStack.getLocalNsPrefix(i);
+ if (prefix == null || prefix.length() == 0) { // default NS decl
+ prefix = XMLConstants.XML_NS_PREFIX;
+ } else {
+ prefix = "xmlns:"+prefix;
+ }
+ writeAttribute(prefix, elemStack.getLocalNsURI(i));
+ }
+ }
+ }
+
+ /* And then let's just output attributes, if any (whether to copy
+ * implicit, aka "default" attributes, is configurable)
+ */
+ int attrCount = mCfgCopyDefaultAttrs ?
+ attrCollector.getCount() :
+ attrCollector.getSpecifiedCount();
+
+ if (attrCount > 0) {
+ for (int i = 0; i < attrCount; ++i) {
+ attrCollector.writeAttribute(i, mWriter, mValidator);
+ }
+ }
+ }
+
+ @Override
+ protected String getTopElementDesc() {
+ return mElements.isEmpty() ? "#root" : mElements.getLastString();
+ }
+
+ @Override
+ public String validateQNamePrefix(QName name) {
+ // Can either strip prefix out, or return as is
+ return name.getPrefix();
+ }
+
+ /*
+ ////////////////////////////////////////////////////
+ // Internal methods
+ ////////////////////////////////////////////////////
+ */
+
+ private void doWriteStartElement(String localName)
+ throws XMLStreamException
+ {
+ mAnyOutput = true;
+ // Need to finish an open start element?
+ if (mStartElementOpen) {
+ closeStartElement(mEmptyElement);
+ } else if (mState == STATE_PROLOG) {
+ // 20-Dec-2005, TSa: Does this match DOCTYPE declaration?
+ verifyRootElement(localName, null);
+ } else if (mState == STATE_EPILOG) {
+ if (mCheckStructure) {
+ reportNwfStructure(ErrorConsts.WERR_PROLOG_SECOND_ROOT, localName);
+ }
+ // Outputting fragment? Better reset to tree, then...
+ mState = STATE_TREE;
+ }
+
+ /* Note: need not check for CONTENT_ALLOW_NONE here, since the
+ * validator should handle this particular case...
+ */
+ /*if (mVldContent == XMLValidator.CONTENT_ALLOW_NONE) { // EMPTY content
+ reportInvalidContent(START_ELEMENT);
+ }*/
+ if (mValidator != null) {
+ mValidator.validateElementStart(localName, XmlConsts.ELEM_NO_NS_URI, XmlConsts.ELEM_NO_PREFIX);
+ }
+
+ mStartElementOpen = true;
+ mElements.addString(localName);
+ try {
+ mWriter.writeStartTagStart(localName);
+ } catch (IOException ioe) {
+ throwFromIOE(ioe);
+ }
+ }
+
+ /**
+ *
+ * Note: Caller has to do actual removal of the element from element
+ * stack, before calling this method.
+ *
+ * @param expName Name that the closing element should have; null
+ * if whatever is in stack should be used
+ * @param allowEmpty If true, is allowed to create the empty element
+ * if the closing element was truly empty; if false, has to write
+ * the full empty element no matter what
+ */
+ private void doWriteEndTag(String expName, boolean allowEmpty)
+ throws XMLStreamException
+ {
+ /* First of all, do we need to close up an earlier empty element?
+ * (open start element that was not created via call to
+ * writeEmptyElement gets handled later on)
+ */
+ if (mStartElementOpen && mEmptyElement) {
+ mEmptyElement = false;
+ // note: this method guarantees proper updates to validation
+ closeStartElement(true);
+ }
+
+ // Better have something to close... (to figure out what to close)
+ if (mState != STATE_TREE) {
+ // Have to throw an exception always, don't know elem name
+ reportNwfStructure("No open start element, when trying to write end element");
+ }
+
+ /* Now, do we have an unfinished start element (created via
+ * writeStartElement() earlier)?
+ */
+ String localName = mElements.removeLast();
+ if (mCheckStructure) {
+ if (expName != null && !localName.equals(expName)) {
+ /* Only gets called when trying to output an XMLEvent... in
+ * which case names can actually be compared
+ */
+ reportNwfStructure("Mismatching close element name, '"+localName+"'; expected '"+expName+"'.");
+ }
+ }
+
+ /* Can't yet validate, since we have two paths; one for empty
+ * elements, another for non-empty...
+ */
+
+ // Got a half output start element to close?
+ if (mStartElementOpen) {
+ /* Can't/shouldn't call closeStartElement, but need to do same
+ * processing. Thus, this is almost identical to closeStartElement:
+ */
+ if (mValidator != null) {
+ /* Note: return value is not of much use, since the
+ * element will be closed right away...
+ */
+ mVldContent = mValidator.validateElementAndAttributes();
+ }
+ mStartElementOpen = false;
+ if (mAttrNames != null) {
+ mAttrNames.clear();
+ }
+ try {
+ // We could write an empty element, implicitly?
+ if (allowEmpty) {
+ mWriter.writeStartTagEmptyEnd();
+ if (mElements.isEmpty()) {
+ mState = STATE_EPILOG;
+ }
+ if (mValidator != null) {
+ mVldContent = mValidator.validateElementEnd(localName, XmlConsts.ELEM_NO_NS_URI, XmlConsts.ELEM_NO_PREFIX);
+ }
+ return;
+ }
+ // Nah, need to close open elem, and then output close elem
+ mWriter.writeStartTagEnd();
+ } catch (IOException ioe) {
+ throwFromIOE(ioe);
+ }
+ }
+
+ try {
+ mWriter.writeEndTag(localName);
+ } catch (IOException ioe) {
+ throwFromIOE(ioe);
+ }
+
+ if (mElements.isEmpty()) {
+ mState = STATE_EPILOG;
+ }
+
+ // Ok, time to validate...
+ if (mValidator != null) {
+ mVldContent = mValidator.validateElementEnd(localName, XmlConsts.ELEM_NO_NS_URI, XmlConsts.ELEM_NO_PREFIX);
+ }
+ }
+}
diff -Nru libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/sw/OutputElementBase.java libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/sw/OutputElementBase.java
--- libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/sw/OutputElementBase.java 1970-01-01 00:00:00.000000000 +0000
+++ libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/sw/OutputElementBase.java 2018-03-31 01:33:28.000000000 +0000
@@ -0,0 +1,377 @@
+/* Woodstox XML processor
+ *
+ * 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 com.ctc.wstx.sw;
+
+import java.util.*;
+
+import javax.xml.XMLConstants;
+import javax.xml.namespace.NamespaceContext;
+import javax.xml.stream.XMLStreamException;
+
+import com.ctc.wstx.util.BijectiveNsMap;
+import com.ctc.wstx.util.DataUtil;
+
+/**
+ * Class that encapsulates information about a specific element in virtual
+ * output stack for namespace-aware writers.
+ * It provides support for URI-to-prefix mappings as well as namespace
+ * mapping generation.
+ *
+ * One noteworthy feature of the class is that it is designed to allow
+ * "short-term recycling", ie. instances can be reused within context
+ * of a simple document output. While reuse/recycling of such lightweight
+ * object is often useless or even counter productive, here it may
+ * be worth using, due to simplicity of the scheme (basically using
+ * a very simple free-elements linked list).
+ */
+public abstract class OutputElementBase
+ implements NamespaceContext
+{
+ public final static int PREFIX_UNBOUND = 0;
+ public final static int PREFIX_OK = 1;
+ public final static int PREFIX_MISBOUND = 2;
+
+ final static String sXmlNsPrefix = XMLConstants.XML_NS_PREFIX;
+ final static String sXmlNsURI = XMLConstants.XML_NS_URI;
+
+ /*
+ ////////////////////////////////////////////
+ // Namespace binding/mapping information
+ ////////////////////////////////////////////
+ */
+
+ /**
+ * Namespace context end application may have supplied, and that
+ * (if given) should be used to augment explicitly defined bindings.
+ */
+ protected NamespaceContext mRootNsContext;
+
+ protected String mDefaultNsURI;
+
+ /**
+ * Mapping of namespace prefixes to URIs and back.
+ */
+ protected BijectiveNsMap mNsMapping;
+
+ /**
+ * True, if {@link #mNsMapping} is a shared copy from the parent;
+ * false if a local copy was created (which happens when namespaces
+ * get bound etc).
+ */
+ protected boolean mNsMapShared;
+
+ /*
+ ////////////////////////////////////////////
+ // Life-cycle
+ ////////////////////////////////////////////
+ */
+
+ /**
+ * Constructor for the virtual root element
+ */
+ protected OutputElementBase()
+ {
+ mNsMapping = null;
+ mNsMapShared = false;
+ mDefaultNsURI = "";
+ mRootNsContext = null;
+ }
+
+ protected OutputElementBase(OutputElementBase parent, BijectiveNsMap ns)
+ {
+ mNsMapping = ns;
+ mNsMapShared = (ns != null);
+ mDefaultNsURI = parent.mDefaultNsURI;
+ mRootNsContext = parent.mRootNsContext;
+ }
+
+ /**
+ * Method called to reuse a pooled instance.
+ */
+ protected void relink(OutputElementBase parent)
+ {
+ mNsMapping = parent.mNsMapping;
+ mNsMapShared = (mNsMapping != null);
+ mDefaultNsURI = parent.mDefaultNsURI;
+ mRootNsContext = parent.mRootNsContext;
+ }
+
+ protected abstract void setRootNsContext(NamespaceContext ctxt);
+
+ /*
+ ////////////////////////////////////////////
+ // Public API, accessors
+ ////////////////////////////////////////////
+ */
+
+ public abstract boolean isRoot();
+
+ /**
+ * @return String presentation of the fully-qualified name, in
+ * "prefix:localName" format (no URI). Useful for error and
+ * debugging messages.
+ */
+ public abstract String getNameDesc();
+
+ public final String getDefaultNsUri() {
+ return mDefaultNsURI;
+ }
+
+ /*
+ ////////////////////////////////////////////
+ // Public API, ns binding, checking
+ ////////////////////////////////////////////
+ */
+
+ /**
+ * Method similar to {@link #getPrefix}, but one that will not accept
+ * the default namespace, only an explicit one. Usually used when
+ * trying to find a prefix for attributes.
+ */
+ public final String getExplicitPrefix(String uri)
+ {
+ if (mNsMapping != null) {
+ String prefix = mNsMapping.findPrefixByUri(uri);
+ if (prefix != null) {
+ return prefix;
+ }
+ }
+ if (mRootNsContext != null) {
+ String prefix = mRootNsContext.getPrefix(uri);
+ if (prefix != null) {
+ // Hmmh... still can't use the default NS:
+ if (prefix.length() > 0) {
+ return prefix;
+ }
+ // ... should we try to find an explicit one?
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Method that verifies that passed-in prefix indeed maps to the specified
+ * namespace URI; and depending on how it goes returns a status for
+ * caller.
+ *
+ * @param isElement If true, rules for the default NS are those of elements
+ * (ie. empty prefix can map to non-default namespace); if false,
+ * rules are those of attributes (only non-default prefix can map to
+ * a non-default namespace).
+ *
+ * @return PREFIX_OK, if passed-in prefix matches matched-in namespace URI
+ * in current scope; PREFIX_UNBOUND if it's not bound to anything,
+ * and PREFIX_MISBOUND if it's bound to another URI.
+ *
+ * @throws XMLStreamException True if default (no) prefix is allowed to
+ * match a non-default URI (elements); false if not (attributes)
+ */
+ public final int isPrefixValid(String prefix, String nsURI,
+ boolean isElement)
+ throws XMLStreamException
+ {
+ // Hmmm.... caller shouldn't really pass null.
+ if (nsURI == null) {
+ nsURI = "";
+ }
+
+ /* First thing is to see if specified prefix is bound to a namespace;
+ * and if so, verify it matches with data passed in:
+ */
+
+ // Checking default namespace?
+ if (prefix == null || prefix.length() == 0) {
+ if (isElement) {
+ // It's fine for elements only if the URI actually matches:
+ if (nsURI == mDefaultNsURI || nsURI.equals(mDefaultNsURI)) {
+ return PREFIX_OK;
+ }
+ } else {
+ /* Attributes never use the default namespace: "no prefix"
+ * can only mean "no namespace"
+ */
+ if (nsURI.length() == 0) {
+ return PREFIX_OK;
+ }
+ }
+ return PREFIX_MISBOUND;
+ }
+
+ /* Need to handle 'xml' prefix and its associated
+ * URI; they are always declared by default
+ */
+ if (prefix.equals(sXmlNsPrefix)) {
+ // Should we thoroughly verify its namespace matches...?
+ // 01-Apr-2005, TSa: Yes, let's always check this
+ if (!nsURI.equals(sXmlNsURI)) {
+ throwOutputError("Namespace prefix '"+sXmlNsPrefix
+ +"' can not be bound to non-default namespace ('"+nsURI+"'); has to be the default '"
+ +sXmlNsURI+"'");
+ }
+ return PREFIX_OK;
+ }
+
+ // Nope checking some other namespace
+ String act;
+
+ if (mNsMapping != null) {
+ act = mNsMapping.findUriByPrefix(prefix);
+ } else {
+ act = null;
+ }
+
+ if (act == null && mRootNsContext != null) {
+ act = mRootNsContext.getNamespaceURI(prefix);
+ }
+
+ // Not (yet) bound...
+ if (act == null) {
+ return PREFIX_UNBOUND;
+ }
+
+ return (act == nsURI || act.equals(nsURI)) ?
+ PREFIX_OK : PREFIX_MISBOUND;
+ }
+
+ /*
+ ////////////////////////////////////////////
+ // Public API, mutators
+ ////////////////////////////////////////////
+ */
+
+ public abstract void setDefaultNsUri(String uri);
+
+ public final String generateMapping(String prefixBase, String uri, int[] seqArr)
+ {
+ // This is mostly cut'n pasted from addPrefix()...
+ if (mNsMapping == null) {
+ // Didn't have a mapping yet? Need to create one...
+ mNsMapping = BijectiveNsMap.createEmpty();
+ } else if (mNsMapShared) {
+ /* Was shared with parent(s)? Need to create a derivative, to
+ * allow for nesting/scoping of new prefix
+ */
+ mNsMapping = mNsMapping.createChild();
+ mNsMapShared = false;
+ }
+ return mNsMapping.addGeneratedMapping(prefixBase, mRootNsContext,
+ uri, seqArr);
+ }
+
+ public final void addPrefix(String prefix, String uri)
+ {
+ if (mNsMapping == null) {
+ // Didn't have a mapping yet? Need to create one...
+ mNsMapping = BijectiveNsMap.createEmpty();
+ } else if (mNsMapShared) {
+ /* Was shared with parent(s)? Need to create a derivative, to
+ * allow for nesting/scoping of new prefix
+ */
+ mNsMapping = mNsMapping.createChild();
+ mNsMapShared = false;
+ }
+ mNsMapping.addMapping(prefix, uri);
+ }
+
+ /*
+ //////////////////////////////////////////////////
+ // NamespaceContext implementation
+ //////////////////////////////////////////////////
+ */
+
+ @Override
+ public final String getNamespaceURI(String prefix)
+ {
+ if (prefix.length() == 0) { //default NS
+ return mDefaultNsURI;
+ }
+ if (mNsMapping != null) {
+ String uri = mNsMapping.findUriByPrefix(prefix);
+ if (uri != null) {
+ return uri;
+ }
+ }
+ return (mRootNsContext != null) ?
+ mRootNsContext.getNamespaceURI(prefix) : null;
+ }
+
+ @Override
+ public final String getPrefix(String uri)
+ {
+ if (mDefaultNsURI.equals(uri)) {
+ return "";
+ }
+ if (mNsMapping != null) {
+ String prefix = mNsMapping.findPrefixByUri(uri);
+ if (prefix != null) {
+ return prefix;
+ }
+ }
+ return (mRootNsContext != null) ?
+ mRootNsContext.getPrefix(uri) : null;
+ }
+
+ @Override
+ public final Iterator getPrefixes(String uri)
+ {
+ List l = null;
+
+ if (mDefaultNsURI.equals(uri)) {
+ l = new ArrayList();
+ l.add("");
+ }
+ if (mNsMapping != null) {
+ l = mNsMapping.getPrefixesBoundToUri(uri, l);
+ }
+ // How about the root namespace context? (if any)
+ /* Note: it's quite difficult to properly resolve masking, when
+ * combining these things (not impossible, just tricky); for now
+ * let's do best effort without worrying about masking:
+ */
+ if (mRootNsContext != null) {
+ Iterator> it = mRootNsContext.getPrefixes(uri);
+ while (it.hasNext()) {
+ String prefix = (String) it.next();
+ if (prefix.length() == 0) { // default NS already checked
+ continue;
+ }
+ // slow check... but what the heck
+ if (l == null) {
+ l = new ArrayList();
+ } else if (l.contains(prefix)) { // double-defined...
+ continue;
+ }
+ l.add(prefix);
+ }
+ }
+ if (l == null) {
+ return DataUtil.emptyIterator();
+ }
+ return l.iterator();
+ }
+
+ /*
+ ////////////////////////////////////////////
+ // Internal methods
+ ////////////////////////////////////////////
+ */
+
+ protected final void throwOutputError(String msg)
+ throws XMLStreamException
+ {
+ throw new XMLStreamException(msg);
+ }
+}
diff -Nru libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/sw/RepairingNsStreamWriter.java libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/sw/RepairingNsStreamWriter.java
--- libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/sw/RepairingNsStreamWriter.java 1970-01-01 00:00:00.000000000 +0000
+++ libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/sw/RepairingNsStreamWriter.java 2018-03-31 01:33:28.000000000 +0000
@@ -0,0 +1,659 @@
+/* Woodstox XML processor
+ *
+ * Copyright (c) 2004- Tatu Saloranta, tatu.saloranta@iki.fi
+ *
+ * Licensed under the License specified in the 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, softwar
+ * 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 com.ctc.wstx.sw;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLStreamWriter;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.events.Attribute;
+import javax.xml.stream.events.StartElement;
+
+import org.codehaus.stax2.ri.typed.AsciiValueEncoder;
+
+import com.ctc.wstx.api.WriterConfig;
+import com.ctc.wstx.cfg.ErrorConsts;
+import com.ctc.wstx.sr.AttributeCollector;
+import com.ctc.wstx.sr.InputElementStack;
+
+/**
+ * Namespace-aware implementation of {@link XMLStreamWriter}, that does
+ * namespace repairing, ie resolves possible conflicts between prefixes
+ * (add new bindings as necessary), as well as automatically creates
+ * namespace declarations as necessary.
+ */
+public final class RepairingNsStreamWriter
+ extends BaseNsStreamWriter
+{
+ /*
+ ///////////////////////////////////////////////////////////
+ // Configuration (options, features)
+ ///////////////////////////////////////////////////////////
+ */
+
+ // // // Additional specific config flags base class doesn't have
+
+ protected final String mAutomaticNsPrefix;
+
+ /*
+ ///////////////////////////////////////////////////////////
+ // Additional state
+ ///////////////////////////////////////////////////////////
+ */
+
+ /**
+ * Sequence number used for generating dynamic namespace prefixes.
+ * Array used as a wrapper to allow for easy sharing of the sequence
+ * number.
+ */
+ protected int[] mAutoNsSeq = null;
+
+ protected String mSuggestedDefNs = null;
+
+ /**
+ * Map that contains URI-to-prefix entries that point out suggested
+ * prefixes for URIs. These are populated by calls to
+ * {@link #setPrefix}, and they are only used as hints for binding;
+ * if there are conflicts, repairing writer can just use some other
+ * prefix.
+ */
+ protected HashMap mSuggestedPrefixes = null;
+
+ /*
+ ///////////////////////////////////////////////////////////
+ // Life-cycle (ctors)
+ ///////////////////////////////////////////////////////////
+ */
+
+ public RepairingNsStreamWriter(XmlWriter xw, String enc, WriterConfig cfg)
+ {
+ super(xw, enc, cfg, true);
+ mAutomaticNsPrefix = cfg.getAutomaticNsPrefix();
+ }
+
+ /*
+ ///////////////////////////////////////////////////////////
+ // XMLStreamWriter API
+ ///////////////////////////////////////////////////////////
+ */
+
+ //public NamespaceContext getNamespaceContext()
+ //public void setNamespaceContext(NamespaceContext context)
+ //public String getPrefix(String uri)
+ //public void setPrefix(String prefix, String uri)
+ //public void setDefaultNamespace(String uri)
+
+ //public void writeAttribute(String localName, String value)
+
+ @Override
+ public void writeAttribute(String nsURI, String localName, String value)
+ throws XMLStreamException
+ {
+ // No need to set mAnyOutput, nor close the element
+ if (!mStartElementOpen) {
+ throwOutputError(ErrorConsts.WERR_ATTR_NO_ELEM);
+ }
+ doWriteAttr(localName, nsURI,
+ findOrCreateAttrPrefix(null, nsURI, mCurrElem),
+ value);
+ }
+
+ @Override
+ public void writeAttribute(String prefix, String nsURI,
+ String localName, String value)
+ throws XMLStreamException
+ {
+ if (!mStartElementOpen) {
+ throwOutputError(ErrorConsts.WERR_ATTR_NO_ELEM);
+ }
+
+ doWriteAttr(localName, nsURI, findOrCreateAttrPrefix(prefix, nsURI, mCurrElem),
+ value);
+ }
+
+ @Override
+ public void writeDefaultNamespace(String nsURI)
+ throws XMLStreamException
+ {
+ /* 01-Sep-2006, TSa: The use case for calling this method is that
+ * of caller may wanting to 'suggest' that
+ * such a namespace should indeed be bound at this level. This
+ * may be necessary for canonicalization, or for minimizing number
+ * of binding declarations (all children need the ns, but root
+ * itself not).
+ */
+ if (!mStartElementOpen) {
+ throwOutputError(ERR_NSDECL_WRONG_STATE);
+ }
+ /* ... We have one complication though: if the current element
+ * uses default namespace, can not change it (attributes don't
+ * matter -- they never use the default namespace, but either don't
+ * belong to a namespace, or belong to one using explicit prefix)
+ */
+ String prefix = mCurrElem.getPrefix();
+ if (prefix != null && prefix.length() > 0) { // ok, can change it
+ mCurrElem.setDefaultNsUri(nsURI);
+ doWriteDefaultNs(nsURI);
+ }
+ }
+
+ //public void writeEmptyElement(String localName) throws XMLStreamException
+
+ @Override
+ public void writeNamespace(String prefix, String nsURI)
+ throws XMLStreamException
+ {
+ /* (see discussion in 'writeDefaultNamespace()' for details on
+ * if and how this method may get called in repairing mode)
+ */
+ if (prefix == null || prefix.length() == 0) {
+ writeDefaultNamespace(nsURI);
+ return;
+ }
+ if (!mStartElementOpen) {
+ throwOutputError(ERR_NSDECL_WRONG_STATE);
+ }
+ /* 01-Sep-2006, TSa: Let's only add the declaration if the prefix
+ * is as of yet unbound. If we have to re-bind things in future,
+ * so be it -- for now, this should suffice (and if we have to
+ * add re-binding, must verify that no attribute, nor element
+ * itself, is using overridden prefix)
+ */
+ int value = mCurrElem.isPrefixValid(prefix, nsURI, true);
+ if (value == SimpleOutputElement.PREFIX_UNBOUND) {
+ mCurrElem.addPrefix(prefix, nsURI);
+ doWriteNamespace(prefix, nsURI);
+ }
+ }
+
+ /*
+ ///////////////////////////////////////////////////////////
+ // Package methods:
+ ///////////////////////////////////////////////////////////
+ */
+
+ /**
+ * With repairing writer, this is only taken as a suggestion as to how
+ * the caller would prefer prefixes to be mapped.
+ */
+ @Override
+ public void setDefaultNamespace(String uri)
+ throws XMLStreamException
+ {
+ mSuggestedDefNs = (uri == null || uri.length() == 0) ? null : uri;
+ }
+
+ @Override
+ public void doSetPrefix(String prefix, String uri)
+ throws XMLStreamException
+ {
+ /* Ok; let's assume that passing in a null or empty String as
+ * the URI means that we don't want passed prefix to be preferred
+ * for any URI.
+ */
+ if (uri == null || uri.length() == 0) {
+ if (mSuggestedPrefixes != null) {
+ for (Iterator> it = mSuggestedPrefixes.entrySet().iterator();
+ it.hasNext(); ) {
+ Map.Entry en = it.next();
+ String thisP = en.getValue();
+ if (thisP.equals(prefix)) {
+ it.remove();
+ }
+ }
+ }
+ } else {
+ if (mSuggestedPrefixes == null) {
+ mSuggestedPrefixes = new HashMap(16);
+ }
+ mSuggestedPrefixes.put(uri, prefix);
+ }
+ }
+
+ @Override
+ public void writeStartElement(StartElement elem)
+ throws XMLStreamException
+ {
+ /* In repairing mode this is simple: let's just pass info
+ * we have, and things should work... a-may-zing!
+ */
+ QName name = elem.getName();
+ writeStartElement(name.getPrefix(), name.getLocalPart(),
+ name.getNamespaceURI());
+ @SuppressWarnings("unchecked")
+ Iterator it = elem.getAttributes();
+ while (it.hasNext()) {
+ Attribute attr = it.next();
+ name = attr.getName();
+ writeAttribute(name.getPrefix(), name.getNamespaceURI(),
+ name.getLocalPart(), attr.getValue());
+ }
+ }
+
+ //public void writeEndElement(QName name) throws XMLStreamException
+
+ @Override
+ protected void writeTypedAttribute(String prefix, String nsURI, String localName,
+ AsciiValueEncoder enc)
+ throws XMLStreamException
+ {
+ super.writeTypedAttribute(findOrCreateAttrPrefix(prefix, nsURI, mCurrElem),
+ nsURI, localName, enc);
+ }
+
+ @Override
+ protected void writeStartOrEmpty(String localName, String nsURI)
+ throws XMLStreamException
+ {
+ checkStartElement(localName, "");
+
+ // First, need to find prefix matching URI, if any:
+ String prefix = findElemPrefix(nsURI, mCurrElem);
+ /* Then need to create the element, since it'll have to
+ * contain the new namespace binding, if one needed
+ * (changed to resolve [WSTX-135] as reported by Y-J Choi,
+ * who also proposed the solution)
+ */
+ if (mOutputElemPool != null) {
+ SimpleOutputElement newCurr = mOutputElemPool;
+ mOutputElemPool = newCurr.reuseAsChild(mCurrElem, prefix, localName, nsURI);
+ --mPoolSize;
+ mCurrElem = newCurr;
+ } else {
+ mCurrElem = mCurrElem.createChild(prefix, localName, nsURI);
+ }
+
+ if (prefix != null) { // prefix ok, easy, no need to overwrite
+ if (mValidator != null) {
+ mValidator.validateElementStart(localName, nsURI, prefix);
+ }
+ doWriteStartTag(prefix, localName);
+ } else { // no prefix, more work
+ prefix = generateElemPrefix(null, nsURI, mCurrElem);
+ if (mValidator != null) {
+ mValidator.validateElementStart(localName, nsURI, prefix);
+ }
+ mCurrElem.setPrefix(prefix);
+ doWriteStartTag(prefix, localName);
+ if (prefix == null || prefix.length() == 0) { // def NS
+ mCurrElem.setDefaultNsUri(nsURI);
+ doWriteDefaultNs(nsURI);
+ } else { // explicit NS
+ mCurrElem.addPrefix(prefix, nsURI);
+ doWriteNamespace(prefix, nsURI);
+ }
+ }
+ }
+
+ @Override
+ protected void writeStartOrEmpty(String suggPrefix, String localName, String nsURI)
+ throws XMLStreamException
+ {
+ checkStartElement(localName, suggPrefix);
+
+ // In repairing mode, better ensure validity:
+ String actPrefix = validateElemPrefix(suggPrefix, nsURI, mCurrElem);
+ if (actPrefix != null) { // fine, an existing binding we can use:
+ if (mValidator != null) {
+ mValidator.validateElementStart(localName, nsURI, actPrefix);
+ }
+ if (mOutputElemPool != null) {
+ SimpleOutputElement newCurr = mOutputElemPool;
+ mOutputElemPool = newCurr.reuseAsChild(mCurrElem, actPrefix, localName, nsURI);
+ --mPoolSize;
+ mCurrElem = newCurr;
+ } else {
+ mCurrElem = mCurrElem.createChild(actPrefix, localName, nsURI);
+ }
+ doWriteStartTag(actPrefix, localName);
+ } else { // nah, need to create a new binding...
+ /* Need to ensure that we'll pass "" as prefix, not null, so
+ * that it is understood as "I want to use the default NS", not
+ * as "whatever prefix, I don't care"
+ */
+ if (suggPrefix == null) {
+ suggPrefix = "";
+ }
+ actPrefix = generateElemPrefix(suggPrefix, nsURI, mCurrElem);
+ if (mValidator != null) {
+ mValidator.validateElementStart(localName, nsURI, actPrefix);
+ }
+ if (mOutputElemPool != null) {
+ SimpleOutputElement newCurr = mOutputElemPool;
+ mOutputElemPool = newCurr.reuseAsChild(mCurrElem, actPrefix, localName, nsURI);
+ --mPoolSize;
+ mCurrElem = newCurr;
+ } else {
+ mCurrElem = mCurrElem.createChild(actPrefix, localName, nsURI);
+ }
+ mCurrElem.setPrefix(actPrefix);
+ doWriteStartTag(actPrefix, localName);
+ if (actPrefix == null || actPrefix.length() == 0) { // def NS
+ mCurrElem.setDefaultNsUri(nsURI);
+ doWriteDefaultNs(nsURI);
+ } else { // explicit NS
+ mCurrElem.addPrefix(actPrefix, nsURI);
+ doWriteNamespace(actPrefix, nsURI);
+ }
+ }
+ }
+
+ /**
+ * Element copier method implementation suitable for use with
+ * namespace-aware writers in repairing mode.
+ * The trickiest thing is having to properly
+ * order calls to setPrefix
, writeNamespace
+ * and writeStartElement
; the order writers expect is
+ * bit different from the order in which element information is
+ * passed in.
+ */
+ @Override
+ public final void copyStartElement(InputElementStack elemStack, AttributeCollector ac)
+ throws IOException, XMLStreamException
+ {
+ /* In case of repairing stream writer, we can actually just
+ * go ahead and first output the element: stream writer should
+ * be able to resolve namespace mapping for the element
+ * automatically, as necessary.
+ */
+ String prefix = elemStack.getPrefix();
+ String uri = elemStack.getNsURI();
+ writeStartElement(prefix, elemStack.getLocalName(), uri);
+
+ /* 04-Sep-2006, TSa: Although we could really just ignore all
+ * namespace declarations, some apps prefer (or even expect...)
+ * that ns bindings are preserved as much as possible. So, let's
+ * just try to output them as they are (could optimize and skip
+ * ones related to the start element [same prefix or URI], but
+ * for now let's not bother)
+ */
+ int nsCount = elemStack.getCurrentNsCount();
+ if (nsCount > 0) { // yup, got some...
+ for (int i = 0; i < nsCount; ++i) {
+ writeNamespace(elemStack.getLocalNsPrefix(i), elemStack.getLocalNsURI(i));
+ }
+ }
+
+ /* And then let's just output attributes, if any (whether to copy
+ * implicit, aka "default" attributes, is configurable)
+ */
+ int attrCount = mCfgCopyDefaultAttrs ? ac.getCount() : ac.getSpecifiedCount();
+
+ /* Unlike in non-ns and simple-ns modes, we can not simply literally
+ * copy the attributes here. It is possible that some namespace
+ * prefixes have been remapped... so need to be bit more careful.
+ */
+ if (attrCount > 0) {
+ for (int i = 0; i < attrCount; ++i) {
+ // First; need to make sure that the prefix-to-ns mapping
+ // attribute has is valid... and can not output anything
+ // before that's done (since remapping will output a namespace
+ // declaration!)
+ uri = ac.getURI(i);
+ prefix = ac.getPrefix(i);
+
+ // With attributes, missing/empty prefix always means 'no
+ // namespace', can take a shortcut:
+ if (prefix == null || prefix.length() == 0) {
+ ;
+ } else {
+ // and otherwise we'll always have a prefix as attributes
+ // can not make use of the def. namespace...
+ prefix = findOrCreateAttrPrefix(prefix, uri, mCurrElem);
+ }
+ /* Hmmh. Since the prefix we use may be different from what
+ * collector has, we can not use pass-through method of
+ * the collector, but need to call XmlWriter directly:
+ */
+ if (prefix == null || prefix.length() == 0) {
+ mWriter.writeAttribute(ac.getLocalName(i), ac.getValue(i));
+ } else {
+ mWriter.writeAttribute(prefix, ac.getLocalName(i), ac.getValue(i));
+ }
+ }
+ }
+ }
+
+ @Override
+ public String validateQNamePrefix(QName name)
+ throws XMLStreamException
+ {
+ /* Gets bit more complicated: we need to ensure that given URI
+ * is properly bound...
+ */
+ String uri = name.getNamespaceURI();
+ String suggPrefix = name.getPrefix();
+ String actPrefix = validateElemPrefix(suggPrefix, uri, mCurrElem);
+ if (actPrefix == null) { // no suitable prefix, must bind
+ /* Need to ensure that we'll pass "" as prefix, not null, so
+ * that it is understood as "I want to use the default NS", not
+ * as "whatever prefix, I don't care"
+ */
+ if (suggPrefix == null) {
+ suggPrefix = "";
+ }
+ actPrefix = generateElemPrefix(suggPrefix, uri, mCurrElem);
+ if (actPrefix == null || actPrefix.length() == 0) { // def NS
+ writeDefaultNamespace(uri);
+ } else {
+ writeNamespace(actPrefix, uri);
+ }
+ }
+ return actPrefix;
+ }
+
+ /*
+ ///////////////////////////////////////////////////////////
+ // Internal methods
+ ///////////////////////////////////////////////////////////
+ */
+
+ /**
+ * Method called to find an existing prefix for the given namespace,
+ * if any exists in the scope. If one is found, it's returned (including
+ * "" for the current default namespace); if not, null is returned.
+ *
+ * @param nsURI URI of namespace for which we need a prefix
+ */
+ protected final String findElemPrefix(String nsURI, SimpleOutputElement elem)
+ throws XMLStreamException
+ {
+ /* Special case: empty NS URI can only be bound to the empty
+ * prefix...
+ */
+ if (nsURI == null || nsURI.length() == 0) {
+ String currDefNsURI = elem.getDefaultNsUri();
+ if (currDefNsURI != null && currDefNsURI.length() > 0) {
+ // Nope; won't do... has to be re-bound, but not here:
+ return null;
+ }
+ return "";
+ }
+ return mCurrElem.getPrefix(nsURI);
+ }
+
+ /**
+ * Method called after {@link #findElemPrefix} has returned null,
+ * to create and bind a namespace mapping for specified namespace.
+ */
+ protected final String generateElemPrefix(String suggPrefix, String nsURI,
+ SimpleOutputElement elem)
+ throws XMLStreamException
+ {
+ /* Ok... now, since we do not have an existing mapping, let's
+ * see if we have a preferred prefix to use.
+ */
+ /* Except if we need the empty namespace... that can only be
+ * bound to the empty prefix:
+ */
+ if (nsURI == null || nsURI.length() == 0) {
+ return "";
+ }
+
+ /* Ok; with elements this is easy: the preferred prefix can
+ * ALWAYS be used, since it can mask preceding bindings:
+ */
+ if (suggPrefix == null) {
+ // caller wants this URI to map as the default namespace?
+ if (mSuggestedDefNs != null && mSuggestedDefNs.equals(nsURI)) {
+ suggPrefix = "";
+ } else {
+ suggPrefix = (mSuggestedPrefixes == null) ? null:
+ mSuggestedPrefixes.get(nsURI);
+ if (suggPrefix == null) {
+ /* 16-Oct-2005, TSa: We have 2 choices here, essentially;
+ * could make elements always try to override the def
+ * ns... or can just generate new one. Let's do latter
+ * for now.
+ */
+ if (mAutoNsSeq == null) {
+ mAutoNsSeq = new int[1];
+ mAutoNsSeq[0] = 1;
+ }
+ suggPrefix = elem.generateMapping(mAutomaticNsPrefix, nsURI,
+ mAutoNsSeq);
+ }
+ }
+ }
+
+ // Ok; let's let the caller deal with bindings
+ return suggPrefix;
+ }
+
+ /**
+ * Method called to somehow find a prefix for given namespace, to be
+ * used for a new start element; either use an existing one, or
+ * generate a new one. If a new mapping needs to be generated,
+ * it will also be automatically bound, and necessary namespace
+ * declaration output.
+ *
+ * @param suggPrefix Suggested prefix to bind, if any; may be null
+ * to indicate "no preference"
+ * @param nsURI URI of namespace for which we need a prefix
+ * @param elem Currently open start element, on which the attribute
+ * will be added.
+ */
+ protected final String findOrCreateAttrPrefix(String suggPrefix, String nsURI,
+ SimpleOutputElement elem)
+ throws XMLStreamException
+ {
+ if (nsURI == null || nsURI.length() == 0) {
+ /* Attributes never use the default namespace; missing
+ * prefix always leads to the empty ns... so nothing
+ * special is needed here.
+ */
+ return null;
+ }
+ // Maybe the suggested prefix is properly bound?
+ if (suggPrefix != null) {
+ int status = elem.isPrefixValid(suggPrefix, nsURI, false);
+ if (status == SimpleOutputElement.PREFIX_OK) {
+ return suggPrefix;
+ }
+ /* Otherwise, if the prefix is unbound, let's just bind
+ * it -- if caller specified a prefix, it probably prefers
+ * binding that prefix even if another prefix already existed?
+ * The remaining case (already bound to another URI) we don't
+ * want to touch, at least not yet: it may or not be safe
+ * to change binding, so let's just not try it.
+ */
+ if (status == SimpleOutputElement.PREFIX_UNBOUND) {
+ elem.addPrefix(suggPrefix, nsURI);
+ doWriteNamespace(suggPrefix, nsURI);
+ return suggPrefix;
+ }
+ }
+
+ // If not, perhaps there's another existing binding available?
+ String prefix = elem.getExplicitPrefix(nsURI);
+ if (prefix != null) { // already had a mapping for the URI... cool.
+ return prefix;
+ }
+
+ /* Nope, need to create one. First, let's see if there's a
+ * preference...
+ */
+ if (suggPrefix != null) {
+ prefix = suggPrefix;
+ } else if (mSuggestedPrefixes != null) {
+ prefix = mSuggestedPrefixes.get(nsURI);
+ // note: def ns is never added to suggested prefix map
+ }
+
+ if (prefix != null) {
+ /* Can not use default namespace for attributes.
+ * Also, re-binding is tricky for attributes; can't
+ * re-bind anything that's bound on this scope... or
+ * used in this scope. So, to simplify life, let's not
+ * re-bind anything for attributes.
+ */
+ if (prefix.length() == 0
+ || (elem.getNamespaceURI(prefix) != null)) {
+ prefix = null;
+ }
+ }
+
+ if (prefix == null) {
+ if (mAutoNsSeq == null) {
+ mAutoNsSeq = new int[1];
+ mAutoNsSeq[0] = 1;
+ }
+ prefix = mCurrElem.generateMapping(mAutomaticNsPrefix, nsURI,
+ mAutoNsSeq);
+ }
+
+ // Ok; so far so good: let's now bind and output the namespace:
+ elem.addPrefix(prefix, nsURI);
+ doWriteNamespace(prefix, nsURI);
+ return prefix;
+ }
+
+ private final String validateElemPrefix(String prefix, String nsURI,
+ SimpleOutputElement elem)
+ throws XMLStreamException
+ {
+ /* 06-Feb-2005, TSa: Special care needs to be taken for the
+ * "empty" (or missing) namespace:
+ * (see comments from findOrCreatePrefix())
+ */
+ if (nsURI == null || nsURI.length() == 0) {
+ String currURL = elem.getDefaultNsUri();
+ if (currURL == null || currURL.length() == 0) {
+ // Ok, good:
+ return "";
+ }
+ // Nope, needs to be re-bound:
+ return null;
+ }
+
+ int status = elem.isPrefixValid(prefix, nsURI, true);
+ if (status == SimpleOutputElement.PREFIX_OK) {
+ return prefix;
+ }
+
+ /* Hmmh... now here's bit of dilemma: that particular prefix is
+ * either not bound, or is masked... but it is possible some other
+ * prefix would be bound. Should we search for another one, or
+ * try to re-define suggested one? Let's do latter, for now;
+ * caller can then (try to) bind the preferred prefix:
+ */
+ return null;
+ }
+}
diff -Nru libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/sw/SimpleNsStreamWriter.java libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/sw/SimpleNsStreamWriter.java
--- libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/sw/SimpleNsStreamWriter.java 1970-01-01 00:00:00.000000000 +0000
+++ libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/sw/SimpleNsStreamWriter.java 2018-03-31 01:33:28.000000000 +0000
@@ -0,0 +1,346 @@
+/* Woodstox XML processor
+ *
+ * Copyright (c) 2004- Tatu Saloranta, tatu.saloranta@iki.fi
+ *
+ * Licensed under the License specified in the 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 com.ctc.wstx.sw;
+
+import java.io.IOException;
+import java.util.Iterator;
+
+import javax.xml.XMLConstants;
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLStreamWriter;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.events.Attribute;
+import javax.xml.stream.events.Namespace;
+import javax.xml.stream.events.StartElement;
+
+import com.ctc.wstx.api.WriterConfig;
+import com.ctc.wstx.cfg.ErrorConsts;
+import com.ctc.wstx.sr.AttributeCollector;
+import com.ctc.wstx.sr.InputElementStack;
+
+/**
+ * Namespace-aware implementation of {@link XMLStreamWriter}, that does
+ * not do namespace repairing, ie doesn't try to resolve possible
+ * conflicts between prefixes and namespace URIs, or automatically
+ * create namespace bindings.
+ */
+public class SimpleNsStreamWriter
+ extends BaseNsStreamWriter
+{
+ /*
+ ////////////////////////////////////////////////////
+ // Life-cycle (ctors)
+ ////////////////////////////////////////////////////
+ */
+
+ public SimpleNsStreamWriter(XmlWriter xw, String enc, WriterConfig cfg)
+ {
+ super(xw, enc, cfg, false);
+ }
+
+ /*
+ ////////////////////////////////////////////////////
+ // XMLStreamWriter API
+ ////////////////////////////////////////////////////
+ */
+
+ //public NamespaceContext getNamespaceContext()
+ //public void setNamespaceContext(NamespaceContext context)
+ //public String getPrefix(String uri)
+ //public void setPrefix(String prefix, String uri)
+
+ //public void writeAttribute(String localName, String value)
+
+ @Override
+ public void writeAttribute(String nsURI, String localName, String value)
+ throws XMLStreamException
+ {
+ // No need to set mAnyOutput, nor close the element
+ if (!mStartElementOpen) {
+ throwOutputError(ErrorConsts.WERR_ATTR_NO_ELEM);
+ }
+ String prefix = mCurrElem.getExplicitPrefix(nsURI);
+ if (!mReturnNullForDefaultNamespace && prefix == null) {
+ throwOutputError("Unbound namespace URI '" + nsURI + "'");
+ }
+ doWriteAttr(localName, nsURI, prefix, value);
+ }
+
+ @Override
+ public void writeAttribute(String prefix, String nsURI,
+ String localName, String value)
+ throws XMLStreamException
+ {
+ if (!mStartElementOpen) {
+ throwOutputError(ErrorConsts.WERR_ATTR_NO_ELEM);
+ }
+ doWriteAttr(localName, nsURI, prefix, value);
+ }
+
+ //public void writeEmptyElement(String localName) throws XMLStreamException
+ //public void writeEmptyElement(String nsURI, String localName) throws XMLStreamException
+ //public void writeEmptyElement(String prefix, String localName, String nsURI) throws XMLStreamException
+
+ //public void writeEndElement() throws XMLStreamException
+
+ @Override
+ public void writeDefaultNamespace(String nsURI)
+ throws XMLStreamException
+ {
+ if (!mStartElementOpen) {
+ throwOutputError(ERR_NSDECL_WRONG_STATE);
+ }
+ // 27-Mar-2007, TSa: Apparently TCK expects a binding to be added
+ setDefaultNamespace(nsURI);
+ doWriteDefaultNs(nsURI);
+ }
+
+ @Override
+ public void writeNamespace(String prefix, String nsURI)
+ throws XMLStreamException
+ {
+ if (prefix == null || prefix.length() == 0
+ || prefix.equals(XMLConstants.XMLNS_ATTRIBUTE)) {
+ writeDefaultNamespace(nsURI);
+ return;
+ }
+
+ // No need to set mAnyOutput, and shouldn't close the element.
+ // But element needs to be open, obviously.
+ if (!mStartElementOpen) {
+ throwOutputError(ERR_NSDECL_WRONG_STATE);
+ }
+ /* 05-Feb-2005, TSa: Also, as per namespace specs; the 'empty'
+ * namespace URI can not be bound as a non-default namespace
+ * (ie. for any actual prefix)
+ */
+ /* 04-Feb-2005, TSa: Namespaces 1.1 does allow this, though,
+ * so for xml 1.1 documents we need to allow it
+ */
+ if (!mXml11) {
+ if (nsURI.length() == 0) {
+ throwOutputError(ErrorConsts.ERR_NS_EMPTY);
+ }
+ // 01-Apr-2005, TSa: Can we (and do we want to) verify NS consistency?
+ }
+ // 27-Mar-2007, TSa: Apparently TCK expects a binding to be added
+ setPrefix(prefix, nsURI);
+ doWriteNamespace(prefix, nsURI);
+ }
+
+ /*
+ ////////////////////////////////////////////////////
+ // Package methods:
+ ////////////////////////////////////////////////////
+ */
+
+ @Override
+ public void setDefaultNamespace(String uri) throws XMLStreamException
+ {
+ mCurrElem.setDefaultNsUri(uri);
+ }
+
+ @Override
+ public void doSetPrefix(String prefix, String uri) throws XMLStreamException
+ {
+ mCurrElem.addPrefix(prefix, uri);
+ }
+
+ @Override
+ public void writeStartElement(StartElement elem) throws XMLStreamException
+ {
+ QName name = elem.getName();
+ @SuppressWarnings("unchecked")
+ Iterator it = elem.getNamespaces();
+
+ while (it.hasNext()) {
+ Namespace ns = it.next();
+ // First need to 'declare' namespace:
+ String prefix = ns.getPrefix();
+ if (prefix == null || prefix.length() == 0) {
+ setDefaultNamespace(ns.getNamespaceURI());
+ } else {
+ setPrefix(prefix, ns.getNamespaceURI());
+ }
+ }
+
+ /* Outputting element itself is fairly easy. The main question
+ * is whether namespaces match. Let's use simple heuristics:
+ * if writer is to do automatic prefix matching, let's only
+ * pass explicit prefix (not default one); otherwise we'll
+ * pass all parameters as is.
+ */
+ /* Quick check first though: if URI part of QName is null, it's
+ * assumed element will just use whatever is current default
+ * namespace....
+ */
+ String nsURI = name.getNamespaceURI();
+ if (nsURI == null) {
+ writeStartElement(name.getLocalPart());
+ } else {
+ String prefix = name.getPrefix();
+ writeStartElement(prefix, name.getLocalPart(), nsURI);
+ }
+
+ // And now we need to output namespaces (including default), if any:
+ @SuppressWarnings("unchecked")
+ Iterator it2 = elem.getNamespaces();
+ while (it2.hasNext()) {
+ Namespace ns = it2.next();
+ String prefix = ns.getPrefix();
+ if (prefix == null || prefix.length() == 0) {
+ writeDefaultNamespace(ns.getNamespaceURI());
+ } else {
+ writeNamespace(prefix, ns.getNamespaceURI());
+ }
+ }
+
+
+ // And finally, need to output attributes as well:
+ @SuppressWarnings("unchecked")
+ Iterator ait = elem.getAttributes();
+ while (ait.hasNext()) {
+ Attribute attr = ait.next();
+ name = attr.getName();
+ nsURI = name.getNamespaceURI();
+ // In non-default/empty namespace?
+ if (nsURI != null && nsURI.length() > 0) {
+ writeAttribute(name.getPrefix(), nsURI,
+ name.getLocalPart(), attr.getValue());
+ } else {
+ writeAttribute(name.getLocalPart(), attr.getValue());
+ }
+ }
+ }
+
+ //public void writeEndElement(QName name) throws XMLStreamException
+
+ @Override
+ protected void writeStartOrEmpty(String localName, String nsURI)
+ throws XMLStreamException
+ {
+ // Need a prefix...
+ String prefix = mCurrElem.getPrefix(nsURI);
+ if (prefix == null) {
+ throw new XMLStreamException("Unbound namespace URI '"+nsURI+"'");
+ }
+ checkStartElement(localName, prefix);
+ if (mValidator != null) {
+ mValidator.validateElementStart(localName, nsURI, prefix);
+ }
+
+ if (mOutputElemPool != null) {
+ SimpleOutputElement newCurr = mOutputElemPool;
+ mOutputElemPool = newCurr.reuseAsChild(mCurrElem, prefix, localName, nsURI);
+ --mPoolSize;
+ mCurrElem = newCurr;
+ } else {
+ mCurrElem = mCurrElem.createChild(prefix, localName, nsURI);
+ }
+ doWriteStartTag(prefix, localName);
+ }
+
+ @Override
+ protected void writeStartOrEmpty(String prefix, String localName, String nsURI)
+ throws XMLStreamException
+ {
+ checkStartElement(localName, prefix);
+ if (mValidator != null) {
+ mValidator.validateElementStart(localName, nsURI, prefix);
+ }
+
+ if (mOutputElemPool != null) {
+ SimpleOutputElement newCurr = mOutputElemPool;
+ mOutputElemPool = newCurr.reuseAsChild(mCurrElem, prefix, localName, nsURI);
+ --mPoolSize;
+ mCurrElem = newCurr;
+ } else {
+ mCurrElem = mCurrElem.createChild(prefix, localName, nsURI);
+ }
+ doWriteStartTag(prefix, localName);
+ }
+
+ /**
+ * Element copier method implementation suitable to be used with
+ * namespace-aware writers in non-repairing (explicit namespaces) mode.
+ * The trickiest thing is having to properly
+ * order calls to setPrefix
, writeNamespace
+ * and writeStartElement
; the order writers expect is
+ * bit different from the order in which element information is
+ * passed in.
+ */
+ @Override
+ public final void copyStartElement(InputElementStack elemStack,
+ AttributeCollector attrCollector)
+ throws IOException, XMLStreamException
+ {
+ // Any namespace declarations/bindings?
+ int nsCount = elemStack.getCurrentNsCount();
+ 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 = elemStack.getLocalNsPrefix(i);
+ String uri = elemStack.getLocalNsURI(i);
+ if (prefix == null || prefix.length() == 0) { // default NS
+ setDefaultNamespace(uri);
+ } else {
+ setPrefix(prefix, uri);
+ }
+ }
+ }
+
+ writeStartElement(elemStack.getPrefix(),
+ elemStack.getLocalName(),
+ elemStack.getNsURI());
+
+ if (nsCount > 0) {
+ // And then output actual namespace declarations:
+ for (int i = 0; i < nsCount; ++i) {
+ String prefix = elemStack.getLocalNsPrefix(i);
+ String uri = elemStack.getLocalNsURI(i);
+
+ if (prefix == null || prefix.length() == 0) { // default NS
+ writeDefaultNamespace(uri);
+ } else {
+ writeNamespace(prefix, uri);
+ }
+ }
+ }
+
+ /* And then let's just output attributes, if any (whether to copy
+ * implicit, aka "default" attributes, is configurable)
+ */
+ int attrCount = mCfgCopyDefaultAttrs ?
+ attrCollector.getCount() :
+ attrCollector.getSpecifiedCount();
+
+ if (attrCount > 0) {
+ for (int i = 0; i < attrCount; ++i) {
+ attrCollector.writeAttribute(i, mWriter, mValidator);
+ }
+ }
+ }
+
+ @Override
+ public String validateQNamePrefix(QName name)
+ {
+ // Good as is, let's not complicate things
+ return name.getPrefix();
+ }
+}
diff -Nru libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/sw/SimpleOutputElement.java libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/sw/SimpleOutputElement.java
--- libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/sw/SimpleOutputElement.java 1970-01-01 00:00:00.000000000 +0000
+++ libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/sw/SimpleOutputElement.java 2018-03-31 01:33:28.000000000 +0000
@@ -0,0 +1,374 @@
+/* Woodstox XML processor
+ *
+ * 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 com.ctc.wstx.sw;
+
+import java.util.*;
+
+import javax.xml.namespace.NamespaceContext;
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLStreamException;
+
+import com.ctc.wstx.compat.QNameCreator;
+import com.ctc.wstx.util.BijectiveNsMap;
+
+/**
+ * Class that encapsulates information about a specific element in virtual
+ * output stack for namespace-aware writers.
+ * It provides support for URI-to-prefix mappings as well as namespace
+ * mapping generation.
+ *
+ * One noteworthy feature of the class is that it is designed to allow
+ * "short-term recycling", ie. instances can be reused within context
+ * of a simple document output. While reuse/recycling of such lightweight
+ * object is often useless or even counter productive, here it may
+ * be worth using, due to simplicity of the scheme (basically using
+ * a very simple free-elements linked list).
+ */
+public final class SimpleOutputElement
+ extends OutputElementBase
+{
+ /*
+ ///////////////////////////////////////////////////////////////////////
+ // Information about element itself:
+ ///////////////////////////////////////////////////////////////////////
+ */
+
+ /**
+ * Reference to the parent element, element enclosing this element.
+ * Null for root element.
+ * Non-final only to allow temporary pooling
+ * (on per-writer basis, to keep these short-lived).
+ */
+ protected SimpleOutputElement mParent;
+
+ /**
+ * Prefix that is used for the element. Can not be final, since sometimes
+ * it needs to be dynamically generated and bound after creating the
+ * element instance.
+ */
+ protected String mPrefix;
+
+ /**
+ * Local name of the element.
+ * Non-final only to allow reuse.
+ */
+ protected String mLocalName;
+
+ /**
+ * Namespace of the element, whatever {@link #mPrefix} maps to.
+ * Non-final only to allow reuse.
+ */
+ protected String mURI;
+
+ /*
+ ///////////////////////////////////////////////////////////////////////
+ // Attribute information
+ ///////////////////////////////////////////////////////////////////////
+ */
+
+ /**
+ * Map used to check for duplicate attribute declarations, if
+ * feature is enabled.
+ */
+ protected HashSet mAttrSet = null;
+
+ /*
+ ///////////////////////////////////////////////////////////////////////
+ // Life-cycle
+ ///////////////////////////////////////////////////////////////////////
+ */
+
+ /**
+ * Constructor for the virtual root element
+ */
+ private SimpleOutputElement()
+ {
+ super();
+ mParent = null;
+ mPrefix = null;
+ mLocalName = "";
+ mURI = null;
+ }
+
+ private SimpleOutputElement(SimpleOutputElement parent,
+ String prefix, String localName, String uri,
+ BijectiveNsMap ns)
+ {
+ super(parent, ns);
+ mParent = parent;
+ mPrefix = prefix;
+ mLocalName = localName;
+ mURI = uri;
+ }
+
+ /**
+ * Method called to reuse a pooled instance.
+ *
+ * @returns Chained pooled instance that should now be head of the
+ * reuse chain
+ */
+ private void relink(SimpleOutputElement parent,
+ String prefix, String localName, String uri)
+ {
+ super.relink(parent);
+ mParent = parent;
+ mPrefix = prefix;
+ mLocalName = localName;
+ mURI = uri;
+ mNsMapping = parent.mNsMapping;
+ mNsMapShared = (mNsMapping != null);
+ mDefaultNsURI = parent.mDefaultNsURI;
+ mRootNsContext = parent.mRootNsContext;
+ }
+
+ public static SimpleOutputElement createRoot()
+ {
+ return new SimpleOutputElement();
+ }
+
+ /**
+ * Simplest factory method, which gets called when a 1-argument
+ * element output method is called. It is, then, assumed to
+ * use the default namespce.
+ */
+ protected SimpleOutputElement createChild(String localName)
+ {
+ /* At this point we can also discard attribute Map; it is assumed
+ * that when a child element has been opened, no more attributes
+ * can be output.
+ */
+ mAttrSet = null;
+ return new SimpleOutputElement(this, null, localName,
+ mDefaultNsURI, mNsMapping);
+ }
+
+ /**
+ * @return New head of the recycle pool
+ */
+ protected SimpleOutputElement reuseAsChild(SimpleOutputElement parent,
+ String localName)
+ {
+ mAttrSet = null;
+ SimpleOutputElement poolHead = mParent;
+ relink(parent, null, localName, mDefaultNsURI);
+ return poolHead;
+ }
+
+ protected SimpleOutputElement reuseAsChild(SimpleOutputElement parent,
+ String prefix, String localName,
+ String uri)
+ {
+ mAttrSet = null;
+ SimpleOutputElement poolHead = mParent;
+ relink(parent, prefix, localName, uri);
+ return poolHead;
+ }
+
+ /**
+ * Full factory method, used for 'normal' namespace qualified output
+ * methods.
+ */
+ protected SimpleOutputElement createChild(String prefix, String localName,
+ String uri)
+ {
+ /* At this point we can also discard attribute Map; it is assumed
+ * that when a child element has been opened, no more attributes
+ * can be output.
+ */
+ mAttrSet = null;
+ return new SimpleOutputElement(this, prefix, localName, uri, mNsMapping);
+ }
+
+ /**
+ * Method called to temporarily link this instance to a pool, to
+ * allow reusing of instances with the same reader.
+ */
+ protected void addToPool(SimpleOutputElement poolHead)
+ {
+ mParent = poolHead;
+ }
+
+ /*
+ ///////////////////////////////////////////////////////////////////////
+ // Public API, accessors
+ ///////////////////////////////////////////////////////////////////////
+ */
+
+ public SimpleOutputElement getParent() {
+ return mParent;
+ }
+
+ @Override
+ public boolean isRoot() {
+ // (Virtual) Root element has no parent...
+ return (mParent == null);
+ }
+
+ /**
+ * @return String presentation of the fully-qualified name, in
+ * "prefix:localName" format (no URI). Useful for error and
+ * debugging messages.
+ */
+ @Override
+ public String getNameDesc() {
+ if (mPrefix != null && mPrefix.length() > 0) {
+ return mPrefix + ":" +mLocalName;
+ }
+ if (mLocalName != null && mLocalName.length() > 0) {
+ return mLocalName;
+ }
+ return "#error"; // unexpected case
+ }
+
+ public String getPrefix() {
+ return mPrefix;
+ }
+
+ public String getLocalName() {
+ return mLocalName;
+ }
+
+ public String getNamespaceURI() {
+ return mURI;
+ }
+
+ public QName getName() {
+ return QNameCreator.create(mURI, mLocalName, mPrefix);
+ }
+
+ /*
+ ///////////////////////////////////////////////////////////////////////
+ // Public API, ns binding, checking
+ ///////////////////////////////////////////////////////////////////////
+ */
+
+ public void checkAttrWrite(String nsURI, String localName)
+ throws XMLStreamException
+ {
+ AttrName an = new AttrName(nsURI, localName);
+ if (mAttrSet == null) {
+ /* 13-Dec-2005, TSa: Should use a more efficient Set/Map value
+ * for this in future -- specifically one that could use
+ * ns/local-name pairs without intermediate objects
+ */
+ mAttrSet = new HashSet();
+ }
+ if (!mAttrSet.add(an)) {
+ throw new XMLStreamException("Duplicate attribute write for attribute '"+an+"'");
+ }
+ }
+
+ /*
+ ///////////////////////////////////////////////////////////////////////
+ // Public API, mutators
+ ///////////////////////////////////////////////////////////////////////
+ */
+
+ public void setPrefix(String prefix) {
+ mPrefix = prefix;
+ }
+
+ @Override
+ public void setDefaultNsUri(String uri) {
+ mDefaultNsURI = uri;
+ }
+
+ /**
+ * Note: this method can and will only be called before outputting
+ * the root element.
+ */
+ @Override
+ protected final void setRootNsContext(NamespaceContext ctxt)
+ {
+ mRootNsContext = ctxt;
+ // Let's also figure out the default ns binding, if any:
+ String defURI = ctxt.getNamespaceURI("");
+ if (defURI != null && defURI.length() > 0) {
+ mDefaultNsURI = defURI;
+ }
+ }
+
+ /*
+ ///////////////////////////////////////////////////////////////////////
+ // Helper classes:
+ ///////////////////////////////////////////////////////////////////////
+ */
+
+ /**
+ * Simple key class used to represent two-piece (attribute) names;
+ * first part being optional (URI), and second non-optional (local name).
+ */
+ final static class AttrName
+ implements Comparable
+ {
+ final String mNsURI;
+ final String mLocalName;
+
+ /**
+ * Let's cache the hash code, since although hash calculation is
+ * fast, hash code is needed a lot as this is always used as a
+ * HashSet/TreeMap key.
+ */
+ final int mHashCode;
+
+ public AttrName(String nsURI, String localName) {
+ mNsURI = (nsURI == null) ? "" : nsURI;
+ mLocalName = localName;
+ mHashCode = mNsURI.hashCode() * 31 ^ mLocalName.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (o == this) {
+ return true;
+ }
+ if (!(o instanceof AttrName)) {
+ return false;
+ }
+ AttrName other = (AttrName) o;
+ String otherLN = other.mLocalName;
+ // Local names are shorter, more varying:
+ if (otherLN != mLocalName && !otherLN.equals(mLocalName)) {
+ return false;
+ }
+ String otherURI = other.mNsURI;
+ return (otherURI == mNsURI || otherURI.equals(mNsURI));
+ }
+
+ @Override
+ public String toString() {
+ if (mNsURI.length() > 0) {
+ return "{"+mNsURI + "} " +mLocalName;
+ }
+ return mLocalName;
+ }
+
+ @Override
+ public int hashCode() {
+ return mHashCode;
+ }
+
+ @Override
+ public int compareTo(AttrName other) {
+ // Let's first order by namespace:
+ int result = mNsURI.compareTo(other.mNsURI);
+ if (result == 0) {
+ result = mLocalName.compareTo(other.mLocalName);
+ }
+ return result;
+ }
+ }
+}
diff -Nru libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/sw/TypedStreamWriter.java libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/sw/TypedStreamWriter.java
--- libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/sw/TypedStreamWriter.java 1970-01-01 00:00:00.000000000 +0000
+++ libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/sw/TypedStreamWriter.java 2018-03-31 01:33:28.000000000 +0000
@@ -0,0 +1,358 @@
+/* Woodstox XML processor
+ *
+ * Copyright (c) 2004- 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 com.ctc.wstx.sw;
+
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLStreamException;
+
+import org.codehaus.stax2.typed.Base64Variant;
+import org.codehaus.stax2.typed.Base64Variants;
+import org.codehaus.stax2.ri.typed.AsciiValueEncoder;
+import org.codehaus.stax2.ri.typed.ValueEncoderFactory;
+import org.codehaus.stax2.validation.XMLValidator;
+
+import com.ctc.wstx.api.WriterConfig;
+import com.ctc.wstx.cfg.ErrorConsts;
+import com.ctc.wstx.exc.WstxIOException;
+
+/**
+ * Intermediate base class that implements Typed Access API (Stax2 v3)
+ * for all (repairing, non-repairing, non-namespace) native stream
+ * writer implementations.
+ */
+public abstract class TypedStreamWriter
+ extends BaseStreamWriter
+{
+ /**
+ * When outputting using Typed Access API, we will need
+ * encoders. If so, they will created by lazily-constructed
+ * factory
+ */
+ protected ValueEncoderFactory mValueEncoderFactory;
+
+ /*
+ ////////////////////////////////////////////////////
+ // Life-cycle
+ ////////////////////////////////////////////////////
+ */
+
+ protected TypedStreamWriter(XmlWriter xw, String enc, WriterConfig cfg)
+ {
+ super(xw, enc, cfg);
+ }
+
+ protected final ValueEncoderFactory valueEncoderFactory()
+ {
+ if (mValueEncoderFactory == null) {
+ mValueEncoderFactory = new ValueEncoderFactory();
+ }
+ return mValueEncoderFactory;
+ }
+
+ /*
+ /////////////////////////////////////////////////
+ // TypedXMLStreamWriter2 implementation
+ // (Typed Access API, Stax v3.0)
+ /////////////////////////////////////////////////
+ */
+
+ // // // Typed element content write methods
+
+ @Override
+ public void writeBoolean(boolean value)
+ throws XMLStreamException
+ {
+ writeTypedElement(valueEncoderFactory().getEncoder(value));
+ }
+
+ @Override
+ public void writeInt(int value)
+ throws XMLStreamException
+ {
+ writeTypedElement(valueEncoderFactory().getEncoder(value));
+ }
+
+ @Override
+ public void writeLong(long value)
+ throws XMLStreamException
+ {
+ writeTypedElement(valueEncoderFactory().getEncoder(value));
+ }
+
+ @Override
+ public void writeFloat(float value)
+ throws XMLStreamException
+ {
+ writeTypedElement(valueEncoderFactory().getEncoder(value));
+ }
+
+ @Override
+ public void writeDouble(double value)
+ throws XMLStreamException
+ {
+ writeTypedElement(valueEncoderFactory().getEncoder(value));
+
+ }
+
+ @Override
+ public void writeInteger(BigInteger value)
+ throws XMLStreamException
+ {
+ /* No really efficient method exposed by JDK, keep it simple
+ * (esp. considering that length is actually not bound)
+ */
+ writeTypedElement(valueEncoderFactory().getScalarEncoder(value.toString()));
+ }
+
+ @Override
+ public void writeDecimal(BigDecimal value)
+ throws XMLStreamException
+ {
+ /* No really efficient method exposed by JDK, keep it simple
+ * (esp. considering that length is actually not bound)
+ */
+ writeTypedElement(valueEncoderFactory().getScalarEncoder(value.toString()));
+ }
+
+ @Override
+ public void writeQName(QName name)
+ throws XMLStreamException
+ {
+ /* Can't use AsciiValueEncoder, since QNames can contain
+ * non-ascii characters
+ */
+ writeCharacters(serializeQName(name));
+ }
+
+ @Override
+ public final void writeIntArray(int[] value, int from, int length)
+ throws XMLStreamException
+ {
+ writeTypedElement(valueEncoderFactory().getEncoder(value, from, length));
+ }
+
+ @Override
+ public void writeLongArray(long[] value, int from, int length)
+ throws XMLStreamException
+ {
+ writeTypedElement(valueEncoderFactory().getEncoder(value, from, length));
+ }
+
+ @Override
+ public void writeFloatArray(float[] value, int from, int length)
+ throws XMLStreamException
+ {
+ writeTypedElement(valueEncoderFactory().getEncoder(value, from, length));
+ }
+
+ @Override
+ public void writeDoubleArray(double[] value, int from, int length)
+ throws XMLStreamException
+ {
+ writeTypedElement(valueEncoderFactory().getEncoder(value, from, length));
+ }
+
+ @Override
+ public void writeBinary(byte[] value, int from, int length)
+ throws XMLStreamException
+ {
+ Base64Variant v = Base64Variants.getDefaultVariant();
+ writeTypedElement(valueEncoderFactory().getEncoder(v, value, from, length));
+ }
+
+ @Override
+ public void writeBinary(Base64Variant v, byte[] value, int from, int length)
+ throws XMLStreamException
+ {
+ writeTypedElement(valueEncoderFactory().getEncoder(v, value, from, length));
+ }
+
+ protected final void writeTypedElement(AsciiValueEncoder enc)
+ throws XMLStreamException
+ {
+ if (mStartElementOpen) {
+ closeStartElement(mEmptyElement);
+ }
+ // How about well-formedness?
+ if (mCheckStructure) {
+ if (inPrologOrEpilog()) {
+ reportNwfStructure(ErrorConsts.WERR_PROLOG_NONWS_TEXT);
+ }
+ }
+ // Or validity?
+ if (mVldContent <= XMLValidator.CONTENT_ALLOW_WS) {
+ reportInvalidContent(CHARACTERS);
+ }
+
+ // So far so good: let's serialize
+ try {
+ XMLValidator vld = (mVldContent == XMLValidator.CONTENT_ALLOW_VALIDATABLE_TEXT) ?
+ mValidator : null;
+ if (vld == null) {
+ mWriter.writeTypedElement(enc);
+ } else {
+ mWriter.writeTypedElement(enc, vld, getCopyBuffer());
+ }
+ } catch (IOException ioe) {
+ throw new WstxIOException(ioe);
+ }
+ }
+
+ // // // Typed attribute value write methods
+
+ @Override
+ public void writeBooleanAttribute(String prefix, String nsURI, String localName, boolean value)
+ throws XMLStreamException
+ {
+ writeTypedAttribute(prefix, nsURI, localName,
+ valueEncoderFactory().getEncoder(value));
+ }
+
+ @Override
+ public void writeIntAttribute(String prefix, String nsURI, String localName, int value)
+ throws XMLStreamException
+ {
+ writeTypedAttribute(prefix, nsURI, localName,
+ valueEncoderFactory().getEncoder(value));
+ }
+
+ @Override
+ public void writeLongAttribute(String prefix, String nsURI, String localName, long value)
+ throws XMLStreamException
+ {
+ writeTypedAttribute(prefix, nsURI, localName,
+ valueEncoderFactory().getEncoder(value));
+ }
+
+ @Override
+ public void writeFloatAttribute(String prefix, String nsURI, String localName, float value)
+ throws XMLStreamException
+ {
+ writeTypedAttribute(prefix, nsURI, localName,
+ valueEncoderFactory().getEncoder(value));
+ }
+
+ @Override
+ public void writeDoubleAttribute(String prefix, String nsURI, String localName, double value)
+ throws XMLStreamException
+ {
+ writeTypedAttribute(prefix, nsURI, localName,
+ valueEncoderFactory().getEncoder(value));
+ }
+
+ @Override
+ public void writeIntegerAttribute(String prefix, String nsURI, String localName, BigInteger value)
+ throws XMLStreamException
+ {
+ // not optimal, but has to do:
+ writeTypedAttribute(prefix, nsURI, localName,
+ valueEncoderFactory().getScalarEncoder(value.toString()));
+ }
+
+ @Override
+ public void writeDecimalAttribute(String prefix, String nsURI, String localName, BigDecimal value)
+ throws XMLStreamException
+ {
+ // not optimal, but has to do:
+ writeTypedAttribute(prefix, nsURI, localName,
+ valueEncoderFactory().getScalarEncoder(value.toString()));
+ }
+
+ @Override
+ public void writeQNameAttribute(String prefix, String nsURI, String localName, QName name)
+ throws XMLStreamException
+ {
+ /* Can't use AsciiValueEncoder, since QNames can contain
+ * non-ascii characters
+ */
+ writeAttribute(prefix, nsURI, localName, serializeQName(name));
+ }
+
+ @Override
+ public void writeIntArrayAttribute(String prefix, String nsURI, String localName, int[] value)
+ throws XMLStreamException
+ {
+ writeTypedAttribute(prefix, nsURI, localName,
+ valueEncoderFactory().getEncoder(value, 0, value.length));
+ }
+
+ @Override
+ public void writeLongArrayAttribute(String prefix, String nsURI, String localName, long[] value)
+ throws XMLStreamException
+ {
+ writeTypedAttribute(prefix, nsURI, localName,
+ valueEncoderFactory().getEncoder(value, 0, value.length));
+ }
+
+ @Override
+ public void writeFloatArrayAttribute(String prefix, String nsURI, String localName, float[] value)
+ throws XMLStreamException
+ {
+ writeTypedAttribute(prefix, nsURI, localName,
+ valueEncoderFactory().getEncoder(value, 0, value.length));
+ }
+
+ @Override
+ public void writeDoubleArrayAttribute(String prefix, String nsURI, String localName, double[] value)
+ throws XMLStreamException
+ {
+ writeTypedAttribute(prefix, nsURI, localName,
+ valueEncoderFactory().getEncoder(value, 0, value.length));
+ }
+
+ @Override
+ public void writeBinaryAttribute(String prefix, String nsURI, String localName, byte[] value)
+ throws XMLStreamException
+ {
+ Base64Variant v = Base64Variants.getDefaultVariant();
+ writeTypedAttribute(prefix, nsURI, localName,
+ valueEncoderFactory().getEncoder(v, value, 0, value.length));
+ }
+
+ @Override
+ public void writeBinaryAttribute(Base64Variant v, String prefix, String nsURI, String localName, byte[] value)
+ throws XMLStreamException
+ {
+ writeTypedAttribute(prefix, nsURI, localName,
+ valueEncoderFactory().getEncoder(v, value, 0, value.length));
+ }
+
+ /**
+ * Method that will write attribute with value that is known not to
+ * require additional escaping.
+ */
+ protected abstract void writeTypedAttribute(String prefix, String nsURI,
+ String localName,
+ AsciiValueEncoder enc)
+ throws XMLStreamException;
+
+ private String serializeQName(QName name)
+ throws XMLStreamException
+ {
+ String vp = validateQNamePrefix(name);
+ String local = name.getLocalPart();
+ if (vp == null || vp.length() == 0) {
+ return local;
+ }
+
+ // Not efficient... but should be ok
+ return vp + ":" + local;
+ }
+}
diff -Nru libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/sw/XmlWriter.java libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/sw/XmlWriter.java
--- libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/sw/XmlWriter.java 1970-01-01 00:00:00.000000000 +0000
+++ libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/sw/XmlWriter.java 2018-03-31 01:33:28.000000000 +0000
@@ -0,0 +1,631 @@
+/* Woodstox XML processor
+ *
+ * Copyright (c) 2004- 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 com.ctc.wstx.sw;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.Writer;
+import java.text.MessageFormat;
+
+import javax.xml.stream.XMLStreamException;
+
+import org.codehaus.stax2.io.EscapingWriterFactory;
+import org.codehaus.stax2.ri.typed.AsciiValueEncoder;
+import org.codehaus.stax2.validation.XMLValidator;
+
+import com.ctc.wstx.api.InvalidCharHandler;
+import com.ctc.wstx.api.WriterConfig;
+import com.ctc.wstx.api.WstxOutputProperties;
+import com.ctc.wstx.cfg.ErrorConsts;
+import com.ctc.wstx.cfg.OutputConfigFlags;
+import com.ctc.wstx.exc.WstxIOException;
+import com.ctc.wstx.io.WstxInputData;
+
+/**
+ * This is the base class for actual physical xml outputters. These
+ * instances will only handle actual writing (possibly including
+ * encoding) of the serialized textual xml, and will in general
+ * not verify content being output. The exception are the
+ * character-by-character checks that are most efficiently done
+ * at encoding level (such as character escaping, and checks for
+ * illegal character combinations), which are handled at this
+ * level.
+ *
+ * Note that implementations can have different operating modes:
+ * specifically, when dealing with illegal content (such as "--"
+ * in a comment, "?>" in processing instruction, or "]]>" within
+ * CDATA section), implementations can do one of 3 things:
+ *
+ * - Fix the problem, by splitting the section (which can be done
+ * for CDATA sections, and to some degree, comments)
+ *
+ * - Stop outputting, and return an index to the illegal piece
+ * of data (if there is no easy way to fix the problem: for
+ * example, for processing instruction)
+ *
+ * - Just output content even though it will not result in
+ * well-formed output. This should only be done if the calling
+ * application has specifically requested verifications to be
+ * disabled.
+ *
+ *
+ */
+public abstract class XmlWriter
+{
+ protected final static int SURR1_FIRST = 0xD800;
+ protected final static int SURR1_LAST = 0xDBFF;
+ protected final static int SURR2_FIRST = 0xDC00;
+ protected final static int SURR2_LAST = 0xDFFF;
+
+ protected final static char DEFAULT_QUOTE_CHAR = '"';
+
+ protected final WriterConfig mConfig;
+ protected final String mEncoding;
+
+ // // // Operating mode: base class needs to know whether
+ // // // namespaces are support (for entity/PI target validation)
+
+ protected final boolean mNsAware;
+
+ protected final boolean mCheckStructure;
+ protected final boolean mCheckContent;
+ protected final boolean mCheckNames;
+ protected final boolean mFixContent;
+
+ /**
+ * Whether to escape CR (\r) character.
+ */
+ final boolean mEscapeCR;
+
+ /**
+ * Whether to add a space after empty element (before closing "/>")
+ * or not.
+ */
+ final boolean mAddSpaceAfterEmptyElem;
+
+ /**
+ * Whether to use double quotes in XML declaration or not.
+ */
+ final boolean mUseDoubleQuotesInXmlDecl;
+
+ /**
+ * Flag that defines whether close() on this writer should call
+ * close on the underlying output object (stream, writer)
+ */
+ protected final boolean mAutoCloseOutput;
+
+ /**
+ * Optional escaping writer used for escaping characters like '<'
+ * '&' and '>' in textual content.
+ * Constructed if calling code has
+ * installed a special escaping writer factory for text content.
+ * Null if the default escaper is to be used.
+ */
+ protected Writer mTextWriter;
+
+ /**
+ * Optional escaping writer used for escaping characters like '"'
+ * '&' and '<' in attribute values.
+ * Constructed if calling code has
+ * installed a special escaping writer factory for text content.
+ * Null if the default escaper is to be used.
+ */
+ protected Writer mAttrValueWriter;
+
+ /**
+ * Indicates whether output is to be compliant; if false, is to be
+ * xml 1.0 compliant, if true, xml 1.1 compliant.
+ */
+ protected boolean mXml11 = false;
+
+ /**
+ * Lazy-constructed wrapper object, which will route all calls to
+ * Writer API, to matching writeRaw
methods of this
+ * XmlWriter instance.
+ */
+ protected XmlWriterWrapper mRawWrapper = null;
+
+ /**
+ * Lazy-constructed wrapper object, which will route all calls to
+ * Writer API, to matching writeCharacters
methods of this
+ * XmlWriter instance.
+ */
+ protected XmlWriterWrapper mTextWrapper = null;
+
+ /*
+ ///////////////////////////////////////////////////////
+ // Output location info
+ ///////////////////////////////////////////////////////
+ */
+
+ /**
+ * Number of characters output prior to currently buffered output
+ */
+ protected int mLocPastChars = 0;
+
+ protected int mLocRowNr = 1;
+
+ /**
+ * Offset of the first character on this line. May be negative, if
+ * the offset was in a buffer that has been flushed out.
+ */
+ protected int mLocRowStartOffset = 0;
+
+ /*
+ ///////////////////////////////////////////////////////
+ // Life-cycle
+ ///////////////////////////////////////////////////////
+ */
+
+ protected XmlWriter(WriterConfig cfg, String encoding, boolean autoclose)
+ throws IOException
+ {
+ mConfig = cfg;
+ mEncoding = encoding;
+ mAutoCloseOutput = autoclose;
+ int flags = cfg.getConfigFlags();
+ mNsAware = (flags & OutputConfigFlags.CFG_ENABLE_NS) != 0;
+ mCheckStructure = (flags & OutputConfigFlags.CFG_VALIDATE_STRUCTURE) != 0;
+ mCheckContent = (flags & OutputConfigFlags.CFG_VALIDATE_CONTENT) != 0;
+ mCheckNames = (flags & OutputConfigFlags.CFG_VALIDATE_NAMES) != 0;
+ mFixContent = (flags & OutputConfigFlags.CFG_FIX_CONTENT) != 0;
+ mEscapeCR = (flags & OutputConfigFlags.CFG_ESCAPE_CR) != 0;
+ mAddSpaceAfterEmptyElem = (flags & OutputConfigFlags.CFG_ADD_SPACE_AFTER_EMPTY_ELEM) != 0;
+ mUseDoubleQuotesInXmlDecl = (flags & OutputConfigFlags.CFG_USE_DOUBLE_QUOTES_IN_XML_DECL) != 0;
+
+ // Has caller requested any custom text or attr value escaping?
+
+ EscapingWriterFactory f = mConfig.getTextEscaperFactory();
+ if (f == null) {
+ mTextWriter = null;
+ } else {
+ String enc = (mEncoding == null || mEncoding.length() == 0) ?
+ WstxOutputProperties.DEFAULT_OUTPUT_ENCODING : mEncoding;
+ mTextWriter = f.createEscapingWriterFor(wrapAsRawWriter(), enc);
+ }
+
+ f = mConfig.getAttrValueEscaperFactory();
+ if (f == null) {
+ mAttrValueWriter = null;
+ } else {
+ String enc = (mEncoding == null || mEncoding.length() == 0) ?
+ WstxOutputProperties.DEFAULT_OUTPUT_ENCODING : mEncoding;
+ mAttrValueWriter = f.createEscapingWriterFor(wrapAsRawWriter(), enc);
+ }
+ }
+
+ /*
+ ////////////////////////////////////////////////////
+ // Extra configuration
+ ////////////////////////////////////////////////////
+ */
+
+ public void enableXml11() {
+ mXml11 = true;
+ }
+
+ /*
+ ////////////////////////////////////////////////////
+ // Access to underlying physical output destinations
+ ////////////////////////////////////////////////////
+ */
+
+ /**
+ * @return Underlying OutputStream used for physical output,
+ * if the writer was constructed using one
+ */
+ protected abstract OutputStream getOutputStream();
+
+ /**
+ * @return Underlying Writer used for physical output,
+ * if the writer was constructed with one, or one was
+ * created to be used with an OutputStream.
+ */
+ protected abstract Writer getWriter();
+
+ /*
+ ////////////////////////////////////////////////////
+ // Basic methods for communicating with underlying
+ // stream or writer
+ ////////////////////////////////////////////////////
+ */
+
+ /**
+ * Method called to flush the buffer(s), and close the output
+ * sink (stream or writer) if enabled (auto-closing) or
+ * forced.
+ */
+ public abstract void close(boolean forceRealClose) throws IOException;
+
+ public abstract void flush()
+ throws IOException;
+
+ public abstract void writeRaw(String str, int offset, int len)
+ throws IOException;
+
+ public void writeRaw(String str)
+ throws IOException
+ {
+ writeRaw(str, 0, str.length());
+ }
+
+ public abstract void writeRaw(char[] cbuf, int offset, int len)
+ throws IOException;
+
+ /**
+ * Like {@link #writeRaw}, but caller guarantees that the contents
+ * additionally are known to be in 7-bit ascii range.
+ */
+ public abstract void writeRawAscii(char[] cbuf, int offset, int len)
+ throws IOException;
+
+ /*
+ ////////////////////////////////////////////////////
+ // Raw, non-verifying write methods; used when
+ // directly copying trusted content
+ ////////////////////////////////////////////////////
+ */
+
+ public abstract void writeCDataStart()
+ throws IOException;
+
+ public abstract void writeCDataEnd()
+ throws IOException;
+
+ public abstract void writeCommentStart()
+ throws IOException;
+
+ public abstract void writeCommentEnd()
+ throws IOException;
+
+ public abstract void writePIStart(String target, boolean addSpace)
+ throws IOException;
+
+ public abstract void writePIEnd()
+ throws IOException;
+
+ /*
+ ////////////////////////////////////////////////////
+ // Write methods, textual:
+ ////////////////////////////////////////////////////
+ */
+
+ /**
+ * @param data Contents of the CDATA section to write out
+
+ * @return offset of the (first) illegal content segment ("]]>") in
+ * passed content and not in repairing mode; or -1 if none or is
+ * repairing
+ */
+ public abstract int writeCData(String data)
+ throws IOException, XMLStreamException;
+
+ public abstract int writeCData(char[] cbuf, int offset, int len)
+ throws IOException, XMLStreamException;
+
+ public abstract void writeCharacters(String data)
+ throws IOException;
+
+ public abstract void writeCharacters(char[] cbuf, int offset, int len)
+ throws IOException;
+
+ /*
+ ////////////////////////////////////////////////////
+ // Write methods, non-textual, non-elem/attr:
+ ////////////////////////////////////////////////////
+ */
+
+ /**
+ * Method that will try to output the content as specified. If
+ * the content passed in has embedded "--" in it, it will either
+ * add an intervening space between consequtive hyphens (if content
+ * fixing is enabled), or return the offset of the first hyphen in
+ * multi-hyphen sequence.
+ */
+ public abstract int writeComment(String data)
+ throws IOException, XMLStreamException;
+
+ /**
+ * Older "legacy" output method for outputting DOCTYPE declaration.
+ * Assumes that the passed-in String contains a complete DOCTYPE
+ * declaration properly quoted.
+ */
+ public abstract void writeDTD(String data)
+ throws IOException, XMLStreamException;
+
+ public abstract void writeDTD(String rootName,
+ String systemId, String publicId,
+ String internalSubset)
+ throws IOException, XMLStreamException;
+
+ public abstract void writeEntityReference(String name)
+ throws IOException, XMLStreamException;
+
+ public abstract int writePI(String target, String data)
+ throws IOException, XMLStreamException;
+
+ public abstract void writeXmlDeclaration(String version, String enc, String standalone)
+ throws IOException;
+
+ /*
+ ////////////////////////////////////////////////////
+ // Write methods, elements
+ ////////////////////////////////////////////////////
+ */
+
+ /**
+ *
+ * Note: can throw XMLStreamException, if name checking is enabled,
+ * and name is invalid (name check has to be in this writer, not
+ * caller, since it depends not only on xml limitations, but also
+ * on encoding limitations)
+ */
+ public abstract void writeStartTagStart(String localName)
+ throws IOException, XMLStreamException;
+
+ /**
+ *
+ * Note: can throw XMLStreamException, if name checking is enabled,
+ * and name is invalid (name check has to be in this writer, not
+ * caller, since it depends not only on xml limitations, but also
+ * on encoding limitations)
+ */
+ public abstract void writeStartTagStart(String prefix, String localName)
+ throws IOException, XMLStreamException;
+
+ public abstract void writeStartTagEnd()
+ throws IOException;
+
+ public abstract void writeStartTagEmptyEnd()
+ throws IOException;
+
+ public abstract void writeEndTag(String localName)
+ throws IOException;
+
+ public abstract void writeEndTag(String prefix, String localName)
+ throws IOException;
+
+ /*
+ ////////////////////////////////////////////////////
+ // Write methods, attributes/ns
+ ////////////////////////////////////////////////////
+ */
+
+ /**
+ *
+ * Note: can throw XMLStreamException, if name checking is enabled,
+ * and name is invalid (name check has to be in this writer, not
+ * caller, since it depends not only on xml limitations, but also
+ * on encoding limitations)
+ */
+ public abstract void writeAttribute(String localName, String value)
+ throws IOException, XMLStreamException;
+
+ public abstract void writeAttribute(String localName, char[] value, int offset, int len)
+ throws IOException, XMLStreamException;
+
+ /**
+ *
+ * Note: can throw XMLStreamException, if name checking is enabled,
+ * and name is invalid (name check has to be in this writer, not
+ * caller, since it depends not only on xml limitations, but also
+ * on encoding limitations)
+ */
+ public abstract void writeAttribute(String prefix, String localName, String value)
+ throws IOException, XMLStreamException;
+
+ public abstract void writeAttribute(String prefix, String localName, char[] value, int offset, int len)
+ throws IOException, XMLStreamException;
+
+ /*
+ ////////////////////////////////////////////////////
+ // Write methods, Typed Access API support
+ ////////////////////////////////////////////////////
+ */
+
+ /**
+ * Like {@link #writeRaw}, but caller guarantees that the contents
+ * additionally are known to be in 7-bit ascii range, and also
+ * passes an encoder object that will encode values only when
+ * being handed a buffer to append to.
+ *
+ * @param enc Encoder that will produce content
+ */
+ public abstract void writeTypedElement(AsciiValueEncoder enc)
+ throws IOException;
+
+ /**
+ * Like {@link #writeRaw}, but caller guarantees that the contents
+ * additionally are known to be in 7-bit ascii range, and also
+ * passes an encoder object that will encode values only when
+ * being handed a buffer to append to.
+ *
+ * @param enc Encoder that will produce content
+ * @param validator Validator to use for validating serialized textual
+ * content (can not be null)
+ * @param copyBuffer Temporary buffer that writer can use for temporary
+ * copies as necessary
+ */
+ public abstract void writeTypedElement(AsciiValueEncoder enc,
+ XMLValidator validator, char[] copyBuffer)
+ throws IOException, XMLStreamException;
+
+ /**
+ * Method similar to {@link #writeAttribute(String,String,char[],int,int)}
+ * but where is known not to require escaping.
+ * No validation needs to be performed.
+ */
+ public abstract void writeTypedAttribute(String localName, AsciiValueEncoder enc)
+ throws IOException, XMLStreamException;
+
+ /**
+ * Method similar to {@link #writeAttribute(String,String,char[],int,int)}
+ * but where is known not to require escaping.
+ * No validation needs to be performed.
+ */
+ public abstract void writeTypedAttribute(String prefix, String localName, AsciiValueEncoder enc)
+ throws IOException, XMLStreamException;
+
+ /**
+ * Method similar to {@link #writeAttribute(String,String,char[],int,int)}
+ * but where is known not to require escaping.
+ * Validation of the attribute value must be done by calling given
+ * validator appropriately.
+ */
+ public abstract void writeTypedAttribute(String prefix, String localName, String nsURI,
+ AsciiValueEncoder enc,
+ XMLValidator validator, char[] copyBuffer)
+ throws IOException, XMLStreamException;
+
+ /*
+ ////////////////////////////////////////////////////
+ // Location information
+ ////////////////////////////////////////////////////
+ */
+
+ protected abstract int getOutputPtr();
+
+ public int getRow() {
+ return mLocRowNr;
+ }
+
+ public int getColumn() {
+ return (getOutputPtr() - mLocRowStartOffset) + 1;
+ }
+
+ public int getAbsOffset() {
+ return mLocPastChars +getOutputPtr();
+ }
+
+ /*
+ ////////////////////////////////////////////////////
+ // Wrapper methods, semi-public
+ ////////////////////////////////////////////////////
+ */
+
+ /**
+ * Method that can be called to get a wrapper instance that
+ * can be used to essentially call the writeRaw
+ * method.
+ */
+ public final Writer wrapAsRawWriter()
+ {
+ if (mRawWrapper == null) {
+ mRawWrapper = XmlWriterWrapper.wrapWriteRaw(this);
+ }
+ return mRawWrapper;
+ }
+
+ public final Writer wrapAsTextWriter()
+ {
+ if (mTextWrapper == null) {
+ mTextWrapper = XmlWriterWrapper.wrapWriteCharacters(this);
+ }
+ return mTextWrapper;
+ }
+
+ /*
+ ////////////////////////////////////////////////////
+ // Helper methods for sub-classes
+ ////////////////////////////////////////////////////
+ */
+
+ /**
+ * Method called to verify that the name is a legal XML name.
+ */
+ public final void verifyNameValidity(String name, boolean checkNs)
+ throws XMLStreamException
+ {
+ /* No empty names... caller must have dealt with optional arguments
+ * prior to calling this method
+ */
+ if (name == null || name.length() == 0) {
+ reportNwfName(ErrorConsts.WERR_NAME_EMPTY);
+ }
+ int illegalIx = WstxInputData.findIllegalNameChar(name, checkNs, mXml11);
+ if (illegalIx >= 0) {
+ if (illegalIx == 0) {
+ reportNwfName(ErrorConsts.WERR_NAME_ILLEGAL_FIRST_CHAR,
+ WstxInputData.getCharDesc(name.charAt(0)));
+ }
+ reportNwfName(ErrorConsts.WERR_NAME_ILLEGAL_CHAR,
+ WstxInputData.getCharDesc(name.charAt(illegalIx)));
+ }
+ }
+
+ /**
+ * This is the method called when an output method call violates
+ * name well-formedness checks
+ * and {@link WstxOutputProperties#P_OUTPUT_VALIDATE_NAMES} is
+ * is enabled.
+ */
+ protected void reportNwfName(String msg)
+ throws XMLStreamException
+ {
+ throwOutputError(msg);
+ }
+
+ protected void reportNwfName(String msg, Object arg)
+ throws XMLStreamException
+ {
+ throwOutputError(msg, arg);
+ }
+
+ protected void reportNwfContent(String msg)
+ throws XMLStreamException
+ {
+ throwOutputError(msg);
+ }
+
+ protected void throwOutputError(String msg)
+ throws XMLStreamException
+ {
+ // First, let's flush any output we may have, to make debugging easier
+ try {
+ flush();
+ } catch (IOException ioe) {
+ throw new WstxIOException(ioe);
+ }
+
+ throw new XMLStreamException(msg);
+ }
+
+ protected void throwOutputError(String format, Object arg)
+ throws XMLStreamException
+ {
+ String msg = MessageFormat.format(format, new Object[] { arg });
+ throwOutputError(msg);
+ }
+
+ /**
+ * Method called to handle invalid character in textual content requested
+ * to be output. Content may be part of textual events (CHARACTER, CDATA),
+ * attribute value, COMMENT content or PROCESSING_INSTRUCTION data.
+ * The default behavior is to just throw an exception, but this can
+ * be configured via property {@link WstxOutputProperties#P_OUTPUT_INVALID_CHAR_HANDLER}.
+ */
+ protected char handleInvalidChar(int c)
+ throws IOException
+ {
+ // First, let's flush any output we may have, to make debugging easier
+ flush();
+ InvalidCharHandler h = mConfig.getInvalidCharHandler();
+ if (h == null) {
+ h = InvalidCharHandler.FailingHandler.getInstance();
+ }
+ return h.convertInvalidChar(c);
+ }
+}
diff -Nru libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/sw/XmlWriterWrapper.java libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/sw/XmlWriterWrapper.java
--- libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/sw/XmlWriterWrapper.java 1970-01-01 00:00:00.000000000 +0000
+++ libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/sw/XmlWriterWrapper.java 2018-03-31 01:33:28.000000000 +0000
@@ -0,0 +1,167 @@
+/* Woodstox XML processor
+ *
+ * Copyright (c) 2004- 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 com.ctc.wstx.sw;
+
+import java.io.*;
+
+/**
+ * This is a simple wrapper class, which decorates an {@link XmlWriter}
+ * to look like a Writer. This is necessary to implement a (legacy)
+ * character quoting system introduced for Woodstox 2.0, which relies
+ * on having a Writer to use for outputting.
+ */
+public abstract class XmlWriterWrapper
+ extends Writer
+{
+ protected final XmlWriter mWriter;
+
+ private char[] mBuffer = null;
+
+ public static XmlWriterWrapper wrapWriteRaw(XmlWriter xw)
+ {
+ return new RawWrapper(xw);
+ }
+
+ public static XmlWriterWrapper wrapWriteCharacters(XmlWriter xw)
+ {
+ return new TextWrapper(xw);
+ }
+
+ protected XmlWriterWrapper(XmlWriter writer)
+ {
+ mWriter = writer;
+ }
+
+ @Override
+ public final void close() throws IOException
+ {
+ mWriter.close(false);
+ }
+
+ @Override
+ public final void flush() throws IOException
+ {
+ mWriter.flush();
+ }
+
+ /* !!! 30-Nov-2006, TSa: Due to co-variance between Appendable and
+ * Writer, this would not compile with javac 1.5, in 1.4 mode
+ * (source and target set to "1.4". Not a huge deal, but since
+ * the base impl is just fine, no point in overriding it.
+ */
+ /*
+ public final Writer append(char c)
+ throws IOException
+ {
+ if (mBuffer == null) {
+ mBuffer = new char[1];
+ }
+ mBuffer[0] = (char) c;
+ write(mBuffer, 0, 1);
+ return this;
+ }
+ */
+
+ @Override
+ public final void write(char[] cbuf) throws IOException {
+ write(cbuf, 0, cbuf.length);
+ }
+
+ @Override
+ public abstract void write(char[] cbuf, int off, int len) throws IOException;
+
+ @Override
+ public final void write(int c) throws IOException
+ {
+ if (mBuffer == null) {
+ mBuffer = new char[1];
+ }
+ mBuffer[0] = (char) c;
+ write(mBuffer, 0, 1);
+ }
+
+ @Override
+ public abstract void write(String str) throws IOException;
+
+ @Override
+ public abstract void write(String str, int off, int len) throws IOException;
+
+ /*
+ //////////////////////////////////////////////////
+ // Implementation classes
+ //////////////////////////////////////////////////
+ */
+
+ /**
+ * This wrapper directs calls to writeRaw
methods. Thus,
+ * it is a "vanilla" writer, and no escaping is done.
+ */
+ private final static class RawWrapper
+ extends XmlWriterWrapper
+ {
+ protected RawWrapper(XmlWriter writer)
+ {
+ super(writer);
+ }
+
+ @Override
+ public void write(char[] cbuf, int off, int len) throws IOException
+ {
+ mWriter.writeRaw(cbuf, off, len);
+ }
+
+ @Override
+ public void write(String str, int off, int len) throws IOException
+ {
+ mWriter.writeRaw(str, off, len);
+ }
+
+ @Override
+ public final void write(String str) throws IOException
+ {
+ mWriter.writeRaw(str, 0, str.length());
+ }
+ }
+
+ /**
+ * This wrapper directs calls to writeCharacters
methods.
+ * This means that text content escaping (and, possibly, validation)
+ * is done, using default or custom escaping code.
+ */
+ private static class TextWrapper
+ extends XmlWriterWrapper
+ {
+ protected TextWrapper(XmlWriter writer) {
+ super(writer);
+ }
+
+ @Override
+ public void write(char[] cbuf, int off, int len) throws IOException {
+ mWriter.writeCharacters(cbuf, off, len);
+ }
+
+ @Override
+ public void write(String str) throws IOException {
+ mWriter.writeCharacters(str);
+ }
+
+ @Override
+ public void write(String str, int off, int len) throws IOException {
+ mWriter.writeCharacters(str.substring(off, off+len));
+ }
+ }
+}
+
diff -Nru libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/util/ArgUtil.java libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/util/ArgUtil.java
--- libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/util/ArgUtil.java 1970-01-01 00:00:00.000000000 +0000
+++ libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/util/ArgUtil.java 2018-03-31 01:33:28.000000000 +0000
@@ -0,0 +1,83 @@
+package com.ctc.wstx.util;
+
+/**
+ * Simple static utility class that contains (static) utility methods useful
+ * when parsing non-typesafe arguments (String-only configuration, command
+ * line args).
+ */
+public final class ArgUtil
+{
+ private ArgUtil() { }
+
+ public static boolean convertToBoolean(String prop, Object value)
+ {
+ if (value == null) {
+ return false;
+ }
+ if (value instanceof Boolean) {
+ return ((Boolean) value).booleanValue();
+ }
+ if (value instanceof String) {
+ String str = (String) value;
+ if (str.equalsIgnoreCase("false")) {
+ return false;
+ }
+ if (str.equalsIgnoreCase("true")) {
+ return true;
+ }
+ throw new IllegalArgumentException("Invalid String value for property '"+prop+"': expected Boolean value.");
+ }
+ throw new IllegalArgumentException("Invalid value type ("+value.getClass()+") for property '"+prop+"': expected Boolean value.");
+ }
+
+ public static int convertToInt(String prop, Object value, int minValue)
+ {
+ int i;
+
+ if (value == null) {
+ i = 0;
+ } else if (value instanceof Number) {
+ i = ((Number) value).intValue();
+ } else if (value instanceof String) {
+ try {
+ i = Integer.parseInt((String) value);
+ } catch (NumberFormatException nex) {
+ throw new IllegalArgumentException("Invalid String value for property '"+prop+"': expected a number (Integer).");
+ }
+ } else {
+ throw new IllegalArgumentException("Invalid value type ("+value.getClass()+") for property '"+prop+"': expected Integer value.");
+ }
+
+ if (i < minValue) {
+ throw new IllegalArgumentException("Invalid numeric value ("+i
+ +") for property '"+prop
+ +"': minimum is "+minValue+".");
+ }
+ return i;
+ }
+ public static long convertToLong(String prop, Object value, long minValue)
+ {
+ long i;
+
+ if (value == null) {
+ i = 0;
+ } else if (value instanceof Number) {
+ i = ((Number) value).longValue();
+ } else if (value instanceof String) {
+ try {
+ i = Long.parseLong((String) value);
+ } catch (NumberFormatException nex) {
+ throw new IllegalArgumentException("Invalid String value for property '"+prop+"': expected a number (Long).");
+ }
+ } else {
+ throw new IllegalArgumentException("Invalid value type ("+value.getClass()+") for property '"+prop+"': expected Long value.");
+ }
+
+ if (i < minValue) {
+ throw new IllegalArgumentException("Invalid numeric value ("+i
+ +") for property '"+prop
+ +"': minimum is "+minValue+".");
+ }
+ return i;
+ }
+}
diff -Nru libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/util/BaseNsContext.java libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/util/BaseNsContext.java
--- libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/util/BaseNsContext.java 1970-01-01 00:00:00.000000000 +0000
+++ libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/util/BaseNsContext.java 2018-03-31 01:33:28.000000000 +0000
@@ -0,0 +1,134 @@
+/* Woodstox XML processor
+ *
+ * Copyright (c) 2004 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 com.ctc.wstx.util;
+
+import java.io.IOException;
+import java.io.Writer;
+import java.util.Iterator;
+
+import javax.xml.XMLConstants;
+import javax.xml.namespace.NamespaceContext;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamWriter;
+import javax.xml.stream.events.Namespace;
+
+import com.ctc.wstx.cfg.ErrorConsts;
+
+/**
+ * Abstract base class that defines extra features defined by most
+ * NamespaceContext implementations Wodstox uses.
+ */
+public abstract class BaseNsContext
+ implements NamespaceContext
+{
+ /**
+ * This is the URI returned for default namespace, when it hasn't
+ * been explicitly declared; could be either "" or null.
+ */
+ protected final static String UNDECLARED_NS_URI = "";
+
+ /*
+ /////////////////////////////////////////////
+ // NamespaceContext API
+ /////////////////////////////////////////////
+ */
+
+ @Override
+ public final String getNamespaceURI(String prefix)
+ {
+ /* First the known offenders; invalid args, 2 predefined xml namespace
+ * prefixes
+ */
+ if (prefix == null) {
+ throw new IllegalArgumentException(ErrorConsts.ERR_NULL_ARG);
+ }
+ 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 doGetNamespaceURI(prefix);
+ }
+
+ @Override
+ public final String getPrefix(String nsURI)
+ {
+ /* First the known offenders; invalid args, 2 predefined xml namespace
+ * prefixes
+ */
+ if (nsURI == null || nsURI.length() == 0) {
+ throw new IllegalArgumentException("Illegal to pass null/empty prefix 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 doGetPrefix(nsURI);
+ }
+
+ @Override
+ public final Iterator getPrefixes(String nsURI)
+ {
+ /* First the known offenders; invalid args, 2 predefined xml namespace
+ * prefixes
+ */
+ if (nsURI == null || nsURI.length() == 0) {
+ throw new IllegalArgumentException("Illegal to pass null/empty prefix as argument.");
+ }
+ if (nsURI.equals(XMLConstants.XML_NS_URI)) {
+ return DataUtil.singletonIterator(XMLConstants.XML_NS_PREFIX);
+ }
+ if (nsURI.equals(XMLConstants.XMLNS_ATTRIBUTE_NS_URI)) {
+ return DataUtil.singletonIterator(XMLConstants.XMLNS_ATTRIBUTE);
+ }
+
+ return doGetPrefixes(nsURI);
+ }
+
+ /*
+ /////////////////////////////////////////////
+ // Extended API
+ /////////////////////////////////////////////
+ */
+
+ public abstract Iterator getNamespaces();
+
+ /**
+ * Method called by the matching start element class to
+ * output all namespace declarations active in current namespace
+ * scope, if any.
+ */
+ public abstract void outputNamespaceDeclarations(Writer w) throws IOException;
+
+ public abstract void outputNamespaceDeclarations(XMLStreamWriter w) throws XMLStreamException;
+
+ /*
+ /////////////////////////////////////////////////
+ // Template methods sub-classes need to implement
+ /////////////////////////////////////////////////
+ */
+
+ public abstract String doGetNamespaceURI(String prefix);
+
+ public abstract String doGetPrefix(String nsURI);
+
+ public abstract Iterator doGetPrefixes(String nsURI);
+}
diff -Nru libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/util/BijectiveNsMap.java libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/util/BijectiveNsMap.java
--- libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/util/BijectiveNsMap.java 1970-01-01 00:00:00.000000000 +0000
+++ libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/util/BijectiveNsMap.java 2018-03-31 01:33:28.000000000 +0000
@@ -0,0 +1,320 @@
+/* Woodstox XML processor
+ *
+ * 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 com.ctc.wstx.util;
+
+import java.util.*;
+
+import javax.xml.XMLConstants;
+import javax.xml.namespace.NamespaceContext;
+
+import com.ctc.wstx.util.DataUtil;
+
+/**
+ * Helper class that implements "bijective map" (Map that allows use of values
+ * as keys and vice versa, bidirectional access), and is specifically
+ * used for storing namespace binding information.
+ * One thing worth noting is that Strings stored are NOT assumed to have
+ * been unified (interned) -- if they were, different implementation would
+ * be more optimal.
+ *
+ * Currently only used by stream writers, but could be more generally useful
+ * too.
+ */
+
+public final class BijectiveNsMap
+{
+ /*
+ ///////////////////////////////////////////////
+ // Constants
+ ///////////////////////////////////////////////
+ */
+
+ /**
+ * Let's plan for having up to 14 explicit namespace declarations (2
+ * defaults, for 'xml' and 'xmlns', are pre-populated)
+ */
+ final static int DEFAULT_ARRAY_SIZE = 2 * 16;
+
+ /*
+ ///////////////////////////////////////////////
+ // Member vars
+ ///////////////////////////////////////////////
+ */
+
+ final int mScopeStart;
+
+ /**
+ * Array that contains { prefix, ns-uri } pairs, up to (but not including)
+ * index {@link #mScopeEnd}.
+ */
+ String[] mNsStrings;
+
+ int mScopeEnd;
+
+ /*
+ ///////////////////////////////////////////////
+ // Life-cycle
+ ///////////////////////////////////////////////
+ */
+
+ private BijectiveNsMap(int scopeStart, String[] strs)
+ {
+ mScopeStart = mScopeEnd = scopeStart;
+ mNsStrings = strs;
+ }
+
+ public static BijectiveNsMap createEmpty()
+ {
+ String[] strs = new String[DEFAULT_ARRAY_SIZE];
+
+ strs[0] = XMLConstants.XML_NS_PREFIX;
+ strs[1] = XMLConstants.XML_NS_URI;
+ strs[2] = XMLConstants.XMLNS_ATTRIBUTE;
+ strs[3] = XMLConstants.XMLNS_ATTRIBUTE_NS_URI;
+
+ /* Let's consider pre-defined ones to be 'out of scope', i.e.
+ * conceptually be part of (missing) parent's mappings.
+ */
+ return new BijectiveNsMap(4, strs);
+ }
+
+ public BijectiveNsMap createChild() {
+ return new BijectiveNsMap(mScopeEnd, mNsStrings);
+ }
+
+ /*
+ ///////////////////////////////////////////////
+ // Public API, accessors
+ ///////////////////////////////////////////////
+ */
+
+ public String findUriByPrefix(String prefix)
+ {
+ /* This is quite simple: just need to locate the last mapping
+ * for the prefix, if any:
+ */
+ String[] strs = mNsStrings;
+ int phash = prefix.hashCode();
+
+ for (int ix = mScopeEnd - 2; ix >= 0; ix -= 2) {
+ String thisP = strs[ix];
+ if (thisP == prefix ||
+ (thisP.hashCode() == phash && thisP.equals(prefix))) {
+ return strs[ix+1];
+ }
+ }
+ return null;
+ }
+
+ public String findPrefixByUri(String uri)
+ {
+ /* Finding a valid binding for the given URI is trickier, since
+ * mappings can be masked by others... so, we need to first find
+ * most recent binding, from the freshest one, and then verify
+ * it's still unmasked; if not, continue with the first loop,
+ * and so on.
+ */
+
+ String[] strs = mNsStrings;
+ int uhash = uri.hashCode();
+
+ main_loop:
+ for (int ix = mScopeEnd - 1; ix > 0; ix -= 2) {
+ String thisU = strs[ix];
+ if (thisU == uri ||
+ (thisU.hashCode() == uhash && thisU.equals(uri))) {
+ // match, but has it been masked?
+ String prefix = strs[ix-1];
+ /* only need to check, if it wasn't within current scope
+ * (no masking allowed within scopes)
+ */
+ if (ix < mScopeStart) {
+ int phash = prefix.hashCode();
+ for (int j = ix+1, end = mScopeEnd; j < end; j += 2) {
+ String thisP = strs[j];
+ if (thisP == prefix ||
+ (thisP.hashCode() == phash && thisP.equals(prefix))) {
+ // Masking... got to continue the main loop:
+ continue main_loop;
+ }
+ }
+ }
+ // Ok, unmasked one, can return
+ return prefix;
+ }
+ }
+ return null;
+ }
+
+ public List getPrefixesBoundToUri(String uri, List l)
+ {
+ /* Same problems (masking) apply here, as well as with
+ * findPrefixByUri...
+ */
+ String[] strs = mNsStrings;
+ int uhash = uri.hashCode();
+
+ main_loop:
+ for (int ix = mScopeEnd - 1; ix > 0; ix -= 2) {
+ String thisU = strs[ix];
+ if (thisU == uri ||
+ (thisU.hashCode() == uhash && thisU.equals(uri))) {
+ // match, but has it been masked?
+ String prefix = strs[ix-1];
+ /* only need to check, if it wasn't within current scope
+ * (no masking allowed within scopes)
+ */
+ if (ix < mScopeStart) {
+ int phash = prefix.hashCode();
+ for (int j = ix+1, end = mScopeEnd; j < end; j += 2) {
+ String thisP = strs[j];
+ if (thisP == prefix ||
+ (thisP.hashCode() == phash && thisP.equals(prefix))) {
+ // Masking... got to continue the main loop:
+ continue main_loop;
+ }
+ }
+ }
+ // Ok, unmasked one, can add
+ if (l == null) {
+ l = new ArrayList();
+ }
+ l.add(prefix);
+ }
+ }
+ return l;
+ }
+
+ public int size() {
+ return (mScopeEnd >> 1);
+ }
+
+ public int localSize() {
+ return ((mScopeEnd - mScopeStart) >> 1);
+ }
+
+ /*
+ ///////////////////////////////////////////////
+ // Public API, mutators
+ ///////////////////////////////////////////////
+ */
+
+ /**
+ * Method to add a new prefix-to-URI mapping for the current scope.
+ * Note that it should NOT be used for the default namespace
+ * declaration
+ *
+ * @param prefix Prefix to bind
+ * @param uri URI to bind to the prefix
+ *
+ * @return If the prefix was already bound, the URI it was bound to:
+ * null if it's a new binding for the current scope.
+ */
+ public String addMapping(String prefix, String uri)
+ {
+ String[] strs = mNsStrings;
+ int phash = prefix.hashCode();
+
+ for (int ix = mScopeStart, end = mScopeEnd; ix < end; ix += 2) {
+ String thisP = strs[ix];
+ if (thisP == prefix ||
+ (thisP.hashCode() == phash && thisP.equals(prefix))) {
+ // Overriding an existing mapping
+ String old = strs[ix+1];
+ strs[ix+1] = uri;
+ return old;
+ }
+ }
+ // no previous binding, let's just add it at the end
+ if (mScopeEnd >= strs.length) {
+ // let's just double the array sizes...
+ strs = DataUtil.growArrayBy(strs, strs.length);
+ mNsStrings = strs;
+ }
+ strs[mScopeEnd++] = prefix;
+ strs[mScopeEnd++] = uri;
+
+ return null;
+ }
+
+ /**
+ * Method used to add a dynamic binding, and return the prefix
+ * used to bind the specified namespace URI.
+ */
+ public String addGeneratedMapping(String prefixBase, NamespaceContext ctxt,
+ String uri, int[] seqArr)
+ {
+ String[] strs = mNsStrings;
+ int seqNr = seqArr[0];
+ String prefix;
+
+ main_loop:
+ while (true) {
+ /* We better intern the resulting prefix? Or not?
+ * TODO: maybe soft cache these for other docs?
+ */
+ prefix = (prefixBase + seqNr).intern();
+ ++seqNr;
+
+ /* Ok, let's see if we have a mapping (masked or not) for
+ * the prefix. If we do, let's just not use it: we could
+ * of course mask it (unless it's in current scope), but
+ * it's easier to just get a "virgin" prefix...
+ */
+ int phash = prefix.hashCode();
+
+ for (int ix = mScopeEnd - 2; ix >= 0; ix -= 2) {
+ String thisP = strs[ix];
+ if (thisP == prefix ||
+ (thisP.hashCode() == phash && thisP.equals(prefix))) {
+ continue main_loop;
+ }
+ }
+ /* So far so good... but do we have a root context that might
+ * have something too?
+ */
+
+ if (ctxt != null && ctxt.getNamespaceURI(prefix) != null) {
+ continue;
+ }
+ break;
+ }
+ seqArr[0] = seqNr;
+
+ // Ok, good; then let's just add it in...
+ if (mScopeEnd >= strs.length) {
+ // let's just double the array sizes...
+ strs = DataUtil.growArrayBy(strs, strs.length);
+ mNsStrings = strs;
+ }
+ strs[mScopeEnd++] = prefix;
+ strs[mScopeEnd++] = uri;
+
+ return prefix;
+ }
+
+ /*
+ ///////////////////////////////////////////////
+ // Standard overridden methods
+ ///////////////////////////////////////////////
+ */
+
+ @Override
+ public String toString() {
+ return "["+getClass().toString()+"; "+size()+" entries; of which "
+ +localSize()+" local]";
+ }
+}
diff -Nru libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/util/DataUtil.java libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/util/DataUtil.java
--- libwoodstox-java-4.1.3/src/main/java/com/ctc/wstx/util/DataUtil.java 1970-01-01 00:00:00.000000000 +0000
+++ libwoodstox-java-5.1.0/src/main/java/com/ctc/wstx/util/DataUtil.java 2018-03-31 01:33:28.000000000 +0000
@@ -0,0 +1,128 @@
+package com.ctc.wstx.util;
+
+import java.lang.reflect.Array;
+import java.util.*;
+
+import org.codehaus.stax2.ri.EmptyIterator;
+import org.codehaus.stax2.ri.SingletonIterator;
+
+public final class DataUtil
+{
+ final static char[] EMPTY_CHAR_ARRAY = new char[0];
+
+ final static Long MAX_LONG = new Long(Long.MAX_VALUE);
+
+ private DataUtil() { }
+
+ /*
+ ////////////////////////////////////////////////////////////
+ // Pooling for immutable objects
+ ////////////////////////////////////////////////////////////
+ */
+
+ public static char[] getEmptyCharArray() {
+ return EMPTY_CHAR_ARRAY;
+ }
+
+ // TODO: deprecate, not really needed post-JDK-1.4
+ public static Integer Integer(int i) {
+ return Integer.valueOf(i);
+ }
+
+ /*
+ ////////////////////////////////////////////////////////////
+ // Empty/singleton thingies
+ ////////////////////////////////////////////////////////////
+ */
+
+ public static Iterator singletonIterator(T item) {
+ // TODO: with JDK 1.7, can use method from Collections
+ // TODO: alternatively, with Woodstox 5.1, can fix deprecation marker
+ return SingletonIterator.create(item);
+ }
+
+ public static Iterator