Class Adjusting.XML

  • Enclosing class:

    public static final class Adjusting.XML
    extends Object
    Class that collects adjustment APIs for affecting the behavior of PL/Java's XML support.

    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.


    SAXSource src1 = sqx1.getSource(SAXSource.class);
    SAXSource src2 = sqx2.getSource(Adjusting.XML.SAXSource.class)
    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.