Package groovy.xml

# Class FactorySupport

java.lang.Object
groovy.xml.FactorySupport

public class FactorySupport extends Object
Support class for creating hardened JAXP factories.

Every `create*` method returns a factory pre-configured to resist common XML attack vectors (XXE, billion laughs, external resource resolution). Overloads accepting flags let callers relax specific defaults when they legitimately need DOCTYPE support or external resource resolution.

- ## Field Summary

  Fields
  Modifier and Type
  Field
  Description
  `static final int`
  `DEFAULT_MAX_ELEMENT_DEPTH`
  Default bound on how deeply elements may nest in a parsed document.

- ## Constructor Summary

  Constructors
  Constructor
  Description
  `FactorySupport()`

- ## Method Summary

  Modifier and Type
  Method
  Description
  `static DocumentBuilderFactory`
  `createDocumentBuilderFactory()`
  Creates a new hardened `DocumentBuilderFactory`.
  `static DocumentBuilderFactory`
  `createDocumentBuilderFactory(boolean allowDocTypeDeclaration)`
  Creates a new hardened `DocumentBuilderFactory`.
  `static SAXParser`
  `createSaxParser(SAXParserFactory factory)`
  Creates a `SAXParser` from the supplied factory, bounded by `DEFAULT_MAX_ELEMENT_DEPTH`.
  `static SAXParserFactory`
  `createSaxParserFactory()`
  Creates a new hardened `SAXParserFactory`.
  `static SAXParserFactory`
  `createSaxParserFactory(boolean allowDocTypeDeclaration)`
  Creates a new hardened `SAXParserFactory`.
  `static SchemaFactory`
  `createSchemaFactory(String schemaLanguage)`
  Creates a new hardened `SchemaFactory` for the requested schema language.
  `static TransformerFactory`
  `createTransformerFactory(boolean allowDocTypeDeclaration, boolean allowExternalResources)`
  Creates a new hardened `TransformerFactory`.
  `static XMLInputFactory`
  `createXMLInputFactory()`
  Creates a new hardened `XMLInputFactory` for StAX parsing.
  `static XMLInputFactory`
  `createXMLInputFactory(boolean allowDocTypeDeclaration)`
  Creates a new hardened `XMLInputFactory` for StAX parsing.
  `static XPathFactory`
  `createXPathFactory()`
  Creates a new hardened `XPathFactory`.

  ### Methods inherited from class java.lang.Object

  `clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

- ## Field Details

  - ### DEFAULT_MAX_ELEMENT_DEPTH

    public static final int DEFAULT_MAX_ELEMENT_DEPTH
    Default bound on how deeply elements may nest in a parsed document.

    `XMLConstants.FEATURE_SECURE_PROCESSING` does not bound element depth: the JAXP `jdk.xml.maxElementDepth` limit defaults to `0`, meaning unlimited. The parse itself survives an arbitrarily deep document, because SAX tracks nesting on the heap, but the first consumer to walk the result recursively — `Node.text()`, `XmlNodePrinter`, `GPathResult.toString()`, `XmlUtil.serialize` — runs one stack frame per level and dies with a `StackOverflowError`. That is an `Error`, so it escapes the `catch (Exception)` an application would reasonably use to handle a malformed document. Bounding the depth at parse time turns it into an ordinary parse failure, at one check point, before any of those consumers is reached.

    The value matches `groovy.json`'s nesting bound, and sits far above any realistic document.

    Since:
      6.0.0
    See Also:
      - Constant Field Values

- ## Constructor Details

  - ### FactorySupport

    public FactorySupport()

- ## Method Details

  - ### createDocumentBuilderFactory

    public static DocumentBuilderFactory createDocumentBuilderFactory() throws ParserConfigurationException
    Creates a new hardened `DocumentBuilderFactory`.

    Equivalent to `createDocumentBuilderFactory(false)`: DOCTYPE declarations are rejected and `XMLConstants.FEATURE_SECURE_PROCESSING` is enabled. Pass `true` to `createDocumentBuilderFactory(boolean)` if DOCTYPE support is required.

    Note: prior to Groovy 6.0.0 this method returned a bare JDK factory with no hardening applied. Callers that previously parsed DOCTYPE-bearing documents through the returned factory must switch to `createDocumentBuilderFactory(true)`.

    Returns:
      a newly created, hardened document builder factory
    Throws:
      `ParserConfigurationException` - if the factory cannot be created

  - ### createDocumentBuilderFactory

    public static DocumentBuilderFactory createDocumentBuilderFactory(boolean allowDocTypeDeclaration) throws ParserConfigurationException
    Creates a new hardened `DocumentBuilderFactory`.

    The returned factory has `XMLConstants.FEATURE_SECURE_PROCESSING` enabled, the Apache `disallow-doctype-decl` feature toggled according to the `allowDocTypeDeclaration` flag, XInclude disabled, and entity reference expansion disabled.

    Parameters:
      `allowDocTypeDeclaration` - whether `DOCTYPE` declarations are allowed in parsed documents (defaults should be `false` for untrusted input)
    Returns:
      a newly created, hardened document builder factory
    Throws:
      `ParserConfigurationException` - if the factory cannot be created
    Since:
      6.0.0

  - ### createSaxParserFactory

    public static SAXParserFactory createSaxParserFactory() throws ParserConfigurationException
    Creates a new hardened `SAXParserFactory`.

    Equivalent to `createSaxParserFactory(false)`: DOCTYPE declarations are rejected and `XMLConstants.FEATURE_SECURE_PROCESSING` is enabled. Pass `true` to `createSaxParserFactory(boolean)` if DOCTYPE support is required.

    Note: prior to Groovy 6.0.0 this method returned a bare JDK factory with no hardening applied. Callers that previously parsed DOCTYPE-bearing documents through the returned factory must switch to `createSaxParserFactory(true)`.

    Returns:
      a newly created, hardened SAX parser factory
    Throws:
      `ParserConfigurationException` - if the factory cannot be created

  - ### createSaxParserFactory

    public static SAXParserFactory createSaxParserFactory(boolean allowDocTypeDeclaration) throws ParserConfigurationException
    Creates a new hardened `SAXParserFactory`.

    The returned factory has `XMLConstants.FEATURE_SECURE_PROCESSING` enabled and the Apache `disallow-doctype-decl` feature toggled according to the `allowDocTypeDeclaration` flag.

    Parameters:
      `allowDocTypeDeclaration` - whether `DOCTYPE` declarations are allowed in parsed documents (defaults should be `false` for untrusted input)
    Returns:
      a newly created, hardened SAX parser factory
    Throws:
      `ParserConfigurationException` - if the factory cannot be created
    Since:
      6.0.0

  - ### createXMLInputFactory

    public static XMLInputFactory createXMLInputFactory()
    Creates a new hardened `XMLInputFactory` for StAX parsing.

    Equivalent to `createXMLInputFactory(false)`: DTD support and external entity resolution are disabled.

    Returns:
      a newly created, hardened StAX input factory
    Since:
      6.0.0

  - ### createXMLInputFactory

    public static XMLInputFactory createXMLInputFactory(boolean allowDocTypeDeclaration)
    Creates a new hardened `XMLInputFactory` for StAX parsing.

    The returned factory disables external entity resolution unconditionally and toggles `XMLInputFactory.SUPPORT_DTD` according to the `allowDocTypeDeclaration` flag.

    Parameters:
      `allowDocTypeDeclaration` - whether `DOCTYPE` declarations are allowed in parsed documents (defaults should be `false` for untrusted input)
    Returns:
      a newly created, hardened StAX input factory
    Since:
      6.0.0

  - ### createTransformerFactory

    public static TransformerFactory createTransformerFactory(boolean allowDocTypeDeclaration, boolean allowExternalResources)
    Creates a new hardened `TransformerFactory`.

    The returned factory has `XMLConstants.FEATURE_SECURE_PROCESSING` enabled and the Apache `disallow-doctype-decl` feature toggled according to the `allowDocTypeDeclaration` flag. Access to external DTDs and stylesheets is blocked unless `allowExternalResources` is `true`.

    Parameters:
      `allowDocTypeDeclaration` - whether `DOCTYPE` declarations are allowed in transformed documents
      `allowExternalResources` - whether `<xsl:import>`/`<xsl:include>` may resolve external DTDs or stylesheets
    Returns:
      a newly created, hardened transformer factory
    Since:
      6.0.0

  - ### createSchemaFactory

    public static SchemaFactory createSchemaFactory(String schemaLanguage)
    Creates a new hardened `SchemaFactory` for the requested schema language.

    The returned factory has `XMLConstants.FEATURE_SECURE_PROCESSING` enabled, which by default already restricts resolution of external schemas and DTDs. That default can be widened by a global `javax.xml.accessExternalSchema`/`javax.xml.accessExternalDTD` system property or a `jaxp.properties` entry; if you need external access denied regardless of such global configuration, set `XMLConstants.ACCESS_EXTERNAL_SCHEMA` and `XMLConstants.ACCESS_EXTERNAL_DTD` to `""` on the returned factory (a property set directly on the factory takes precedence over the global configuration).

    Parameters:
      `schemaLanguage` - the schema language URI (see `XMLConstants`)
    Returns:
      a newly created, hardened schema factory
    Since:
      6.0.0

  - ### createXPathFactory

    public static XPathFactory createXPathFactory()
    Creates a new hardened `XPathFactory`.

    The returned factory has `XMLConstants.FEATURE_SECURE_PROCESSING` enabled.

    Returns:
      a newly created, hardened XPath factory
    Since:
      6.0.0

  - ### createSaxParser

    public static SAXParser createSaxParser(SAXParserFactory factory) throws ParserConfigurationException, SAXException
    Creates a `SAXParser` from the supplied factory, bounded by `DEFAULT_MAX_ELEMENT_DEPTH`.

    The depth limit cannot be set on a `SAXParserFactory` — it is a parser property — so SAX callers should obtain their parser here rather than calling `SAXParserFactory.newSAXParser()` directly, or the bound will not be applied.

    Parameters:
      `factory` - the factory to create the parser from
    Returns:
      a newly created parser with the element-depth bound applied
    Throws:
      `ParserConfigurationException` - if the parser cannot be created
      `SAXException` - if the parser cannot be created
    Since:
      6.0.0