Class SyntheticXMLReader
- java.lang.Object
-
- org.postgresql.pljava.internal.SyntheticXMLReader
-
- All Implemented Interfaces:
XMLReader
- Direct Known Subclasses:
ByteBufferXMLReader
public abstract class SyntheticXMLReader extends Object implements XMLReader
Base class implementing the tedious parts of a SAXXMLReader
whose XML content is synthesized on the fly.An implementing class provides
parse(InputSource)
(which might do as little as ignoring its argument and callingsuper.parse()
), and the workhorsenext()
, which should return anSyntheticXMLReader.EventCarrier
on every call, thennull
when no parse events remain. AnEventCarrier
is a closure that can disgorge one or more SAX events onto SAX handlers (provided by this framework) when itstoSAX()
method is called. Start- and end-document events are synthesized here, so only the events in between should be generated byEventCarrier
s.An implementing class could return a single
EventCarrier
that will provide all of the XML content, or a sequence ofEventCarrier
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 multipleEventCarrier
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 defaultSource
to pass to a TRAX transformation, and to handle SQL/XML content that can be fragmentary, it follows that the default flavor ofSource
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
Nested Classes Modifier and Type Class Description static class
SyntheticXMLReader.ApacheFeature
static class
SyntheticXMLReader.EmptyAttributes2
An immutable and empty collection of attributes.class
SyntheticXMLReader.EventCarrier
Base class for a closure carrying one or more SAX events.static class
SyntheticXMLReader.FluentAttributes2
Subclass ofAttributes2Impl
that also provides chainable methods so attribute information can be supplied in a fluent style.static class
SyntheticXMLReader.SAX2FEATURE
static class
SyntheticXMLReader.SAX2PROPERTY
-
Field Summary
Fields Modifier and Type Field Description SyntheticXMLReader.FluentAttributes2
m_attributes
A per-instance, pre-allocatedFluentAttributes2
that can be re-used (but not across threads) for convenience instartElement
calls for elements with attributes.static Attributes2
NO_ATTRIBUTES
A final, pre-allocated, read-onlyAttributes2
that is empty, for convenience instartElement
calls for elements with no attributes.
-
Constructor Summary
Constructors Constructor Description SyntheticXMLReader()
-
Method Summary
Modifier and Type Method Description protected SyntheticXMLReader.EventCarrier
exceptionCarrier(Exception e)
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.ContentHandler
getContentHandler()
DTDHandler
getDTDHandler()
EntityResolver
getEntityResolver()
ErrorHandler
getErrorHandler()
boolean
getFeature(String uri)
Object
getProperty(String uri)
protected abstract SyntheticXMLReader.EventCarrier
next()
The workhorse method for an implementing class to supply.protected void
parse()
Where the work happens.void
parse(String systemId)
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 Detail
-
NO_ATTRIBUTES
public static final Attributes2 NO_ATTRIBUTES
A final, pre-allocated, read-onlyAttributes2
that is empty, for convenience instartElement
calls for elements with no attributes.
-
m_attributes
public final SyntheticXMLReader.FluentAttributes2 m_attributes
A per-instance, pre-allocatedFluentAttributes2
that can be re-used (but not across threads) for convenience instartElement
calls for elements with attributes.
-
-
Method Detail
-
getFeature
public boolean getFeature(String uri) throws SAXNotRecognizedException, SAXNotSupportedException
- 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
public Object getProperty(String uri) throws SAXNotRecognizedException, SAXNotSupportedException
- 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
public void setEntityResolver(EntityResolver resolver)
- Specified by:
setEntityResolver
in interfaceXMLReader
-
getEntityResolver
public EntityResolver getEntityResolver()
- Specified by:
getEntityResolver
in interfaceXMLReader
-
setDTDHandler
public void setDTDHandler(DTDHandler handler)
- Specified by:
setDTDHandler
in interfaceXMLReader
-
getDTDHandler
public DTDHandler getDTDHandler()
- Specified by:
getDTDHandler
in interfaceXMLReader
-
setContentHandler
public void setContentHandler(ContentHandler handler)
- Specified by:
setContentHandler
in interfaceXMLReader
-
getContentHandler
public ContentHandler getContentHandler()
- Specified by:
getContentHandler
in interfaceXMLReader
-
setErrorHandler
public void setErrorHandler(ErrorHandler handler)
- Specified by:
setErrorHandler
in interfaceXMLReader
-
getErrorHandler
public ErrorHandler getErrorHandler()
- Specified by:
getErrorHandler
in interfaceXMLReader
-
next
protected abstract SyntheticXMLReader.EventCarrier 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
public abstract void parse(InputSource input) throws IOException, SAXException
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
public void parse(String systemId) throws IOException, SAXException
If not overridden, callsparse(InputSource)
with the system-id wrapped in anInputSource
.- Specified by:
parse
in interfaceXMLReader
- Throws:
IOException
SAXException
-
parse
protected final void parse() throws IOException, SAXException
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
protected SyntheticXMLReader.EventCarrier exceptionCarrier(Exception e)
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
protected Reader sysIdToReader(URI sysId, Charset cs) throws IOException, SAXException
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
protected InputStream sysIdToInputStream(URI sysId) throws IOException, SAXException
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
protected Reader sourceToReader(InputSource input) throws IOException, SAXException
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
-
-