- Enclosing class:
Adjusting
XML parser behavior adjustments
Retrieving or verifying the XML content in a JDBC SQLXML
object
can involve applying an XML parser. The full XML specification includes
features that can require an XML parser to retrieve external resources or
consume unexpected amounts of memory. The full feature support may be an
asset in an environment where the XML content will always be from a
known, trusted source, or a liability if less is known about the XML
content being processed.
The Open Web Application Security Project (OWASP) advocates for the default use of settings that strictly limit the related features of Java XML parsers, as outlined in a "cheat sheet" the organization publishes. The strict default settings can then be selectively relaxed in applications where the features are needed and the content is sufficiently trusted.
However, the recommended defaults really are severely restrictive (for
example, disabling document-type declarations by default will cause
PL/Java's SQLXML
implementation to reject all XML values that
contain DTDs). Therefore, there must be a simple and clear way for code
to selectively adjust the settings, or adopting the strictest settings by
default would pose an unacceptable burden to developers.
The usual way that Java XML parsers expose their settings for adjustment
is through setFeature
or setProperty
methods that must be
passed particular URIs that identify adjustable features, and objects of
appropriate types (often boolean) as the values for those properties. The
supported properties and the URIs that identify them can be different
from one parser implementation to another or one version to another. That
is not the "simple and clear" adjustment mechanism needed here.
Furthermore, the JDBC SQLXML
API conceals much of the complexity
of configuring any underlying XML parser behind a simple
getSource
method whose result can be used directly with other
Java APIs expecting some flavor of Source
object, and for some of
those flavors, the returned object does not even expose the methods one
would need to call to adjust the underlying parser, if any.
Hence this adjustment API. JDBC already provides for extensibility of the
SQLXML.getSource
method; it is passed the class object for a
desired subtype of Source
and, if the implementation supports it,
returns an object of that type. The subtypes that every conformant
implementation must support are StreamSource
, SAXSource
,
StAXSource
, and DOMSource
. If null
is passed, the
implementation will choose which flavor to return, often based on
internal implementation details making one most natural or efficient.
The types Adjusting.XML.SAXSource
, Adjusting.XML.StAXSource
, and Adjusting.XML.DOMSource
are used the same way, by passing the corresponding class literal to
SQLXML
's getSource
method, which will return an object
providing the chainable adjustment methods of Adjusting.XML.Source
, with the
chain ending in a get
method that returns the
corresponding Java Source
object, configured as adjusted.
Example:
SAXSource src1 = sqx1.getSource(SAXSource.class); SAXSource src2 = sqx2.getSource(Adjusting.XML.SAXSource.class) .allowDTD(true).get();
src1
would be assigned a SAXSource
object configured with
the OWASP-recommended defaults, which will not allow the content to have
a DTD, among other restrictions, while src2
would be assigned a
SAXSource
object configured with the other default restrictions
(as if the allowDTD(true)
is preceded by an implied
defaults()
), but with DTD parsing enabled.
No Adjusting.XML.StreamSource
is needed or provided, as any
application code that requests a StreamSource
will have to
provide and configure its own parser anyway.
Like passing null
to getSource
, passing the parent
interface Adjusting.XML.Source.class
will allow the
implementation to choose which subtype of Adjusting.XML.Source
to
return. The object returned by get
can then be passed
directly to Java APIs like Transformer
that accept several
flavors of Source
, or examined to see of what class it is.
-
Nested Class Summary
Modifier and TypeClassDescriptionstatic interface
Adjusting version of aDOMSource
.static interface
Adjusting.XML.Parsing<T extends Adjusting.XML.Parsing<T>>
Interface with methods to adjust the restrictions on XML parsing that are commonly considered when XML content might be from untrusted sources.static interface
Adjusting.XML.Result<T extends Result>
Adjusting version ofjavax.xml.transform.Result
, offering the adjustment methods ofAdjusting.XML.Parsing
, chiefly so that there is a way to apply those adjustments to any implicitly-created parser used to verify the content that will be written to theResult
.static interface
Adjusting version of aSAXResult
.static interface
Adjusting version of aSAXSource
.static interface
A functional interface fitting varioussetFeature
orsetProperty
methods in Java XML APIs.static interface
Adjusting.XML.Source<T extends Source>
Adjusting version ofjavax.xml.transform.Source
, allowing various parser features to be configured before callingget()
to obtain the usableSource
object.static interface
SpecializedResult
type for setting a new PL/JavaSQLXML
instance's content from an arbitrarySource
object of any of the types JDBC requires theSQLXML
type to support.static interface
Adjusting version of aStAXSource
.static interface
Adjusting version of aStreamResult
. -
Method Summary
Modifier and TypeMethodDescriptionstatic <T,
V extends T>
ExceptionsetFirstSupported
(Adjusting.XML.SetMethod<? super T> setter, V value, List<Class<? extends Exception>> expected, Consumer<? super Exception> onUnexpected, String... names) Attempts a given action (typically to set something) using a given value, trying one or more supplied keys in order until the action succeeds with no exception.
-
Method Details
-
setFirstSupported
public static <T,V extends T> Exception setFirstSupported(Adjusting.XML.SetMethod<? super T> setter, V value, List<Class<? extends Exception>> expected, Consumer<? super Exception> onUnexpected, String... names) Attempts a given action (typically to set something) using a given value, trying one or more supplied keys in order until the action succeeds with no exception.This logic is common to the
setFirstSupportedFeature
andsetFirstSupportedProperty
methods, and is exposed here because it may be useful for other tasks in Java's XML APIs, such as configuringTransformer
s.If any attempt succeeds, null is returned. If no attempt succeeds, the first exception caught is returned, with any exceptions from the subsequent attempts retrievable from it with
getSuppressed
. The return is immediate, without any remaining names being tried, if an exception is caught that is not assignable to a class in the expected list. Such an exception will be passed to the onUnexpected handler if that is non-null; otherwise, it will be returned (or added to the suppressed list of the exception to be returned) just as expected exceptions are.- Parameters:
setter
- typically a method reference for a method that takes a string key and some value.value
- the value to pass to the setterexpected
- a list of exception classes that can be foreseen to indicate that a key was not recognized, and the operation should be retried with the next possible key.onUnexpected
- invoked, if non-null, on anException
that is caught and matches nothing in the expected list, instead of returning it. If this parameter is null, such an exception is returned (or added to the suppressed list of the exception to be returned), just as for expected exceptions, but the return is immediate, without trying remaining names, if any.names
- one or more String keys to be tried in order until the action succeeds.- Returns:
- null if any attempt succeeded, otherwise an exception, which may have further exceptions in its suppressed list.
-