Class SyntheticXMLReader
- All Implemented Interfaces:
XMLReader
- Direct Known Subclasses:
ByteBufferXMLReader
XMLReader
whose
XML content is synthesized on the fly.
An implementing class provides parse(InputSource)
(which might do as
little as ignoring its argument and calling super.parse()
), and the
workhorse next()
, which should return an SyntheticXMLReader.EventCarrier
on
every call, then null
when no parse events remain. An
EventCarrier
is a closure that can disgorge one or more SAX events
onto SAX handlers (provided by this framework) when its
toSAX()
method is called. Start- and
end-document events are synthesized here, so only the events in between
should be generated by EventCarrier
s.
An implementing class could return a single EventCarrier
that will
provide all of the XML content, or a sequence of EventCarrier
s each
supplying one event or more, at the discretion of the implementor; if the
content might be large or complex to generate, breaking it into multiple
EventCarrier
s can provide a StAX-like ability to pull it in smaller
pieces.
This odd hybrid based on SAX is used, rather than simply basing a synthetic
XML source directly on StAX, because of the numerous bugs in the Java
runtime's implementation of StAX-to-TRAX bridging. Those are not so much in
StAX itself (a tidy API), nor in the TRAX transformer implementations, but in
the JRE classes added to bridge the two when StAX was added. The worst are in
the handling of XML 'content' fragments, which are explicitly permitted by
SQL/XML. A look at the bridge classes' code does not show a complete lack of
attention to that case, but the code is broken and, after so many years,
will probably not have its behavior changed. Because the
java.sql.SQLXML
API is expressly designed to allow easily obtaining a
default Source
to pass to a TRAX transformation, and to handle
SQL/XML content that can be fragmentary, it follows that the default flavor
of Source
to return (and to implement synthetically here) must not be
StAX. SAX is well supported and plays well with TRAX, even for content
fragments.
-
Nested Class Summary
Modifier and TypeClassDescriptionstatic enum
static class
An immutable and empty collection of attributes.class
Base class for a closure carrying one or more SAX events.static class
Subclass ofAttributes2Impl
that also provides chainable methods so attribute information can be supplied in a fluent style.static enum
static enum
-
Field Summary
Modifier and TypeFieldDescriptionA per-instance, pre-allocatedFluentAttributes2
that can be re-used (but not across threads) for convenience instartElement
calls for elements with attributes.static final Attributes2
A final, pre-allocated, read-onlyAttributes2
that is empty, for convenience instartElement
calls for elements with no attributes. -
Constructor Summary
-
Method Summary
Modifier and TypeMethodDescriptionprotected SyntheticXMLReader.EventCarrier
Produce anEventCarrier
that wraps a checked exception and will rethrow it when used, which can be returned by thenext()
method, which is not declared to throw any checked exceptions itself.boolean
getFeature
(String uri) getProperty
(String uri) protected abstract SyntheticXMLReader.EventCarrier
next()
The workhorse method for an implementing class to supply.protected final void
parse()
Where the work happens.void
If not overridden, callsparse(InputSource)
with the system-id wrapped in anInputSource
.abstract void
parse
(InputSource input) The onlyparse
variant that the implementing class needs to supply.void
setContentHandler
(ContentHandler handler) void
setDTDHandler
(DTDHandler handler) void
setEntityResolver
(EntityResolver resolver) void
setErrorHandler
(ErrorHandler handler) void
setFeature
(String uri, boolean value) void
setProperty
(String uri, Object value) protected Reader
sourceToReader
(InputSource input) Obtain aReader
given anInputSource
.protected InputStream
sysIdToInputStream
(URI sysId) Obtain anInputStream
given a system-id.protected Reader
sysIdToReader
(URI sysId, Charset cs) Obtain aReader
given a system-id and a character set.
-
Field Details
-
NO_ATTRIBUTES
A final, pre-allocated, read-onlyAttributes2
that is empty, for convenience instartElement
calls for elements with no attributes. -
m_attributes
A per-instance, pre-allocatedFluentAttributes2
that can be re-used (but not across threads) for convenience instartElement
calls for elements with attributes.
-
-
Constructor Details
-
SyntheticXMLReader
public SyntheticXMLReader()
-
-
Method Details
-
getFeature
- Specified by:
getFeature
in interfaceXMLReader
- Throws:
SAXNotRecognizedException
SAXNotSupportedException
-
setFeature
public void setFeature(String uri, boolean value) throws SAXNotRecognizedException, SAXNotSupportedException - Specified by:
setFeature
in interfaceXMLReader
- Throws:
SAXNotRecognizedException
SAXNotSupportedException
-
getProperty
- Specified by:
getProperty
in interfaceXMLReader
- Throws:
SAXNotRecognizedException
SAXNotSupportedException
-
setProperty
public void setProperty(String uri, Object value) throws SAXNotRecognizedException, SAXNotSupportedException - Specified by:
setProperty
in interfaceXMLReader
- Throws:
SAXNotRecognizedException
SAXNotSupportedException
-
setEntityResolver
- Specified by:
setEntityResolver
in interfaceXMLReader
-
getEntityResolver
- Specified by:
getEntityResolver
in interfaceXMLReader
-
setDTDHandler
- Specified by:
setDTDHandler
in interfaceXMLReader
-
getDTDHandler
- Specified by:
getDTDHandler
in interfaceXMLReader
-
setContentHandler
- Specified by:
setContentHandler
in interfaceXMLReader
-
getContentHandler
- Specified by:
getContentHandler
in interfaceXMLReader
-
setErrorHandler
- Specified by:
setErrorHandler
in interfaceXMLReader
-
getErrorHandler
- Specified by:
getErrorHandler
in interfaceXMLReader
-
next
The workhorse method for an implementing class to supply.It should return
null
when no more events are available, and until then, on each call should return anSyntheticXMLReader.EventCarrier
subclass whosetoSAX()
method will disgorge one or more SAX events.- Returns:
- An EventCarrier, or null when no more events are to be returned.
-
parse
The onlyparse
variant that the implementing class needs to supply.An implementation could do as little as ignoring its
InputSource
argument and calling the zero-argumentsuper.parse()
.- Specified by:
parse
in interfaceXMLReader
- Throws:
IOException
SAXException
-
parse
If not overridden, callsparse(InputSource)
with the system-id wrapped in anInputSource
.- Specified by:
parse
in interfaceXMLReader
- Throws:
IOException
SAXException
-
parse
Where the work happens.Synthesizes a
startDocument
, then loops callingnext()
until it returns null, callingtoSAX
on every returnedEventCarrier
, and finally synthesizes anendDocument
.- Throws:
IOException
SAXException
-
exceptionCarrier
Produce anEventCarrier
that wraps a checked exception and will rethrow it when used, which can be returned by thenext()
method, which is not declared to throw any checked exceptions itself.To simplify callers, the exception parameter is allowed to be a
RuntimeException
, in which case it will simply be rethrown here rather than wrapped.- Parameters:
e
- An Exception, which may be a RuntimeException or checked.- Returns:
- An EventCarrier wrapping the exception, if it is checked.
-
sysIdToReader
Obtain aReader
given a system-id and a character set.If not overridden, this method delegates to
sysIdToInputStream(java.net.URI)
and wraps the result in aReader
for the specified character set.- Throws:
IOException
SAXException
-
sysIdToInputStream
Obtain anInputStream
given a system-id.If not overridden, this method tries
toURL().openStream()
on the supplied system-id, wrapping exceptions as needed to throw only those appropriate in a SAX method.- Throws:
IOException
SAXException
-
sourceToReader
Obtain aReader
given anInputSource
.If not overridden, this method returns the
Reader
directly contained in the source if there is one, or one that wraps the source's byte stream and character encoding if available, or the result ofsysIdToReader
on the source's system-id if available.- Throws:
IOException
SAXException
-