This is an automated email from the ASF dual-hosted git repository.

garydgregory pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/commons-xml.git

commit d559440417151b54fccabbafec0e6e2bad95901f
Author: Gary Gregory <[email protected]>
AuthorDate: Sun Aug 30 07:48:52 2026 -0400

    Move documentation to Javadoc to sync with the version documented.
---
 .../java/org/apache/commons/xml/doc-files/leaf.svg |  45 +++
 .../java/org/apache/commons/xml/doc-files/logo.png | Bin 0 -> 9454 bytes
 .../java/org/apache/commons/xml/package-info.java  |  23 +-
 src/main/javadoc/overview.html                     | 319 +++++++++++++++++++++
 src/site/markdown/index.md                         | 230 +--------------
 5 files changed, 381 insertions(+), 236 deletions(-)

diff --git a/src/main/java/org/apache/commons/xml/doc-files/leaf.svg 
b/src/main/java/org/apache/commons/xml/doc-files/leaf.svg
new file mode 100644
index 0000000..71de588
--- /dev/null
+++ b/src/main/java/org/apache/commons/xml/doc-files/leaf.svg
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       https://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+<svg id="Layer_1" xmlns="http://www.w3.org/2000/svg"; viewBox="0 0 650 1000">
+  <defs>
+    <style>
+      .cls-1 {
+        fill: #7c297d;
+      }
+
+      .cls-2 {
+        fill: #f79a23;
+      }
+
+      .cls-3 {
+        fill: #dd552c;
+      }
+
+      .cls-4 {
+        fill: #d22128;
+      }
+    </style>
+  </defs>
+  <path class="cls-3" 
d="M276.7092915,398.1515795c25.5279479-63.1242453,54.0110775-126.1246793,84.5729347-181.9636035-45.6212286-33.8852148-89.4276433-106.9534674-107.4259055-139.3268803-6.4642564,7.3439687-10.6608099,15.8022396-12.563595,22.6835448-16.9556402,61.2214602,43.4023987,135.1498759-5.21311,108.1394499-40.5058645-22.5076023-131.7157397-71.797557-166.5067324-22.8073561,38.9647388,50.0654049,140.8777805,176.0271745,207.1364082,213.2748452Z"/>
+  <path class="cls-2" 
d="M361.2822261,216.187976c29.6137228-54.1055651,61.1725873-101.4927347,93.8913687-135.6320886,0,0-32.6340684,47.2372927-79.2457879,141.6662634,28.2289905,7.7740502,108.6249208,23.7261667,220.6090393-5.2000772,2.7531737-20.350678-10.9279818-42.734469-79.1056856-50.2283145-44.5101845-4.8872906,53.4246026-106.2822795-17.5225659-154.2363748-2.2905102-1.5509002-4.5419221-2.9193416-6.7477192-4.1444224-2.3784814-.8536468-4.8905488-1.6356133-7.5720422-2.3328667-82.8591248-
 [...]
+  <path class="cls-4" 
d="M210.0661969,580.0239535c18.7052902-56.0344158,41.2063761-118.989235,66.6430946-181.872374-66.2586277-37.2476707-168.1716694-163.2094403-207.1364082-213.2748452-6.9562436,9.787614-11.7099483,23.4394457-13.2934304,42.1088958-8.4973692,100.2806866,94.9567981,174.521889,74.3324318,188.0824913-27.2808561,17.9396147-81.5786546-43.0928703-102.978471-4.3138485,31.0180043,39.8477093,94.2008971,111.8472744,182.4327833,169.2696807Z"/>
+  <path class="cls-3" 
d="M496.7155649,363.7515701c-52.3819806-18.6824828,54.7376547-68.786986,89.5221309-121.9411586,4.4506926-6.7965921,9.0512622-15.5806824,10.2991504-24.7883379-111.9841185,28.9262439-192.3800488,12.9741274-220.6090393,5.2000772-24.1301828,48.8924551-51.9942555,110.5048986-81.0540854,184.7917156,30.2653616,12.9415455,153.8421334,60.7457639,328.3900879,60.9933866,29.3465509-76.4372249-76.8347245-86.5311091-126.5482445-104.255683Z"/>
+  <path class="cls-4" 
d="M230.3060964,590.1113213c30.7801562,9.5921223,132.7681363,38.244678,241.0835287,33.9308295,14.5510932-39.3980786-39.8509675-43.2427472-44.282111-74.84071-3.430878-24.4494858,143.1682907,20.5461697,190.3371613-68.3569045,2.3849978-4.4963073,4.2454264-8.7384756,5.819134-12.8372833-174.5479545-.2476227-298.1247263-48.0518411-328.3900879-60.9933866-21.2369067,54.2880239-43.0830957,115.2162467-64.5676252,183.0974549Z"/>
+  <path class="cls-1" 
d="M230.3060964,590.1113213c-13.8310324,43.6923779-27.4763477,90.3692613-40.7209052,139.6983144-4.6983154,17.4899839-9.3412414,35.3057873-13.9190036,53.5125738,102.8057868,33.9373459,197.4726056.0781966,200.6819264-41.8873386.0260655-.3323358-.0358401-.5799585-.016291-.8992615,2.4469035-44.4482789-64.1733837-19.8098179-62.5964179-46.5335229,1.5834822-26.9191966,116.3077416-.1563933,151.7862131-57.872037,2.7205918-4.4246271,4.4930492-8.3540087,5.8680069-12.0878987-10
 [...]
+  <path class="cls-1" 
d="M27.6334136,410.7542728c-1.4987691,2.7173336-2.8509195,5.8582323-4.0043201,9.6116715-19.9238547,64.7533422,120.9604422,151.7405984,101.7924885,170.7032859-17.2782014,17.0859679-39.7955782-21.9602257-67.5619052-5.8321668-3.0431529,1.7724574-6.1319206,4.0075783-9.3021431,7.2592556-31.4024712,32.1714049-.4919873,124.8539837,88.6033203,174.3263973-20.7905342,69.8100589-41.489839,147.8047004-61.7525458,229.3703222,7.3504851-2.573973,16.1476081-5.1544625,18.3371143-12.
 [...]
+</svg>
\ No newline at end of file
diff --git a/src/main/java/org/apache/commons/xml/doc-files/logo.png 
b/src/main/java/org/apache/commons/xml/doc-files/logo.png
new file mode 100644
index 0000000..0c32a3e
Binary files /dev/null and 
b/src/main/java/org/apache/commons/xml/doc-files/logo.png differ
diff --git a/src/main/java/org/apache/commons/xml/package-info.java 
b/src/main/java/org/apache/commons/xml/package-info.java
index 6f9b5ba..f41921d 100644
--- a/src/main/java/org/apache/commons/xml/package-info.java
+++ b/src/main/java/org/apache/commons/xml/package-info.java
@@ -14,21 +14,21 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 /**
- * Apache Commons Secure XML provides secure-by-default JAXP factory creation 
for Java. A single method call returns a secure JAXP factory that can be used to
- * <em>safely</em> parse XML files.
+ * <a href="https://commons.apache.org/xml";>Apache Commons Secure XML</a> 
provides secure-by-default JAXP factory creation for Java. A single method call
+ * returns a secure JAXP factory that can be used to <em>safely</em> parse XML 
files.
  * <p>
- * Every method returns <em>new, secure</em> factory instances. No caching or 
pooling is performed; callers on a hot path are responsible for their own
- * caching.
+ * Every method returns <em>new, secure</em> factory instances. No caching or 
pooling is performed; callers on a hot path are responsible for their own 
caching.
  * </p>
  * <p>
- * A returned factory is not necessarily an instance of the underlying 
implementation. It might be (and usually is) a wrapper around it, so it cannot 
be cast
- * to the implementation's own class. Everything else about the 
implementation's behavior is preserved: features, properties, and attributes 
delegate to it,
- * and only the security behavior is secure.
+ * A returned factory is not necessarily an instance of the underlying 
implementation. It might be (and usually is) a wrapper around it, so it cannot 
be cast to
+ * the implementation's own class. Everything else about the implementation's 
behavior is preserved: features, properties, and attributes delegate to it, and
+ * only the security behavior is secure.
  * </p>
  * <p>
- * Preserved behavior includes the choice of internal parsers. Each TrAX, 
XPath, or schema implementation has its own way of instantiating them, and the
- * library respects it:
+ * Preserved behavior includes the choice of internal parsers. Each TrAX, 
XPath, or schema implementation has its own way of instantiating them, and the 
library
+ * respects it:
  * </p>
  * <ul>
  * <li>Stock JDK factories use the JDK parsers by default, and expose the 
{@code jdk.xml.overrideDefaultParser} feature (and Java system property of the 
same
@@ -83,8 +83,8 @@
  * <h2>Caller-supplied URIs</h2>
  * <p>
  * A top-level URI passed directly by the caller is fetched as-is: {@code 
StreamSource(systemId)}, {@code DocumentBuilder.parse(String)}, or a {@code 
SAXSource}
- * built from a system id all cause the JAXP implementation to open that URI 
without consulting the secure layer. Use a
- * {@link javax.xml.transform.URIResolver} or {@link 
org.xml.sax.EntityResolver} if you need to restrict the top-level fetch.
+ * built from a system id all cause the JAXP implementation to open that URI 
without consulting the secure layer. Use a {@link 
javax.xml.transform.URIResolver}
+ * or {@link org.xml.sax.EntityResolver} if you need to restrict the top-level 
fetch.
  * </p>
  * <h2>Thread safety</h2>
  * <p>
@@ -92,4 +92,5 @@
  * be thread-safe</strong>. Create a new factory per thread or synchronize 
externally.
  * </p>
  */
+
 package org.apache.commons.xml;
diff --git a/src/main/javadoc/overview.html b/src/main/javadoc/overview.html
new file mode 100644
index 0000000..b780a87
--- /dev/null
+++ b/src/main/javadoc/overview.html
@@ -0,0 +1,319 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+     https://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+<html>
+<head>
+<title>Apache Commons Secure XML Overview</title>
+</head>
+<body>
+  <a href="https://commons.apache.org/xml";><img 
src="org/apache/commons/xml/doc-files/logo.png" alt="Apache Commons Secure XML">
+  </a>
+  <section id="apache-commons-secure-xml">
+    <h1>
+      <img src="org/apache/commons/xml/doc-files/leaf.svg" style="height: 1em; 
padding-right: 0.25em" alt="leaf">Apache Commons Secure XML
+    </h1>
+    <p>
+      <a href="https://commons.apache.org/xml";>Apache Commons Secure XML</a> 
is part of the <a href="https://commons.apache.org/index.html";>Apache 
Commons</a> project.
+    </p>
+    <p>Apache Commons Secure XML provides secure-by-default JAXP factory 
creation, abstracting over implementation-specific XXE securing differences 
between
+      the stock JDK and external JAXP implementations.</p>
+  </section>
+  <section id="why">
+    <h1>
+      <img src="org/apache/commons/xml/doc-files/leaf.svg" style="height: 1em; 
padding-right: 0.25em" alt="leaf">Why
+    </h1>
+    <p>Any Java library that parses XML has to secure JAXP before handing a 
factory to user code, and every library ends up copy-pasting the same securing
+      snippet. The snippet is fragile: the attributes and features needed to 
secure a factory are not standardized, each JAXP implementation exposes a 
slightly
+      different set, and setting an unknown one throws an exception that 
callers routinely swallow. Writing this block correctly for every 
implementation is
+      real work, and duplicating it across projects means every project owns 
the maintenance burden on its own.</p>
+    <p>
+      Defaults are also uneven. The stock JDK SAX and DOM parsers already 
prevent external entity resolution through
+      <code>FEATURE_SECURE_PROCESSING</code>
+      , and JAXP 1.5 conformant implementations ship reasonable defaults for 
most attacks. Others, such as standalone Xerces, Woodstox, or Saxon’s TrAX, need
+      further configuration before they reach the same baseline. A library 
author has no control over which implementation is on the classpath at runtime, 
so
+      the effective security posture of their code depends on a deployment 
decision made elsewhere.
+    </p>
+    <p>
+      This library provides that baseline. Each
+      <code>org.apache.commons.xml</code>
+      factory call returns a new factory secured by an implementation-specific 
recipe, so the returned object behaves the same way security-wise regardless of
+      which JAXP implementation resolved. Security becomes a property of the 
call, not of the classpath, and there is one place to update when a new securing
+      setting becomes available or a default changes.
+    </p>
+  </section>
+  <section id="usage">
+    <h1>
+      <img src="org/apache/commons/xml/doc-files/leaf.svg" style="height: 1em; 
padding-right: 0.25em" alt="leaf">Usage
+    </h1>
+    <p>
+      To add the library to your build, see <a 
href="dependency-info.html">Maven Coordinates</a>. (Maven 
Coordinates)[dependency-info.html]
+    </p>
+    <p>
+      Every factory method in
+      <code>org.apache.commons.xml</code>
+      returns a new, secured factory. Pick the one that matches the API you 
already use; no other configuration is required. On secured factories an 
external
+      resource reference (DTD, entity, schema, stylesheet) is never fetched: 
it resolves to empty content, so the parse continues without it (see 
Configuration
+      below).
+    </p>
+    <section id="supported-runtimes">
+      <h2>Supported Runtimes</h2>
+      <p>The library requires OpenJDK 8 or later (or a JDK distribution built 
from it), or Android API level 26 or later.</p>
+      <p>
+        The security guarantees are defined only on the OpenJDK family (see 
the <a href="threat_model.html">Threat Model</a>). No version of Android 
supports
+        <code>FEATURE_SECURE_PROCESSING</code>
+        (so states <a 
href="https://developer.android.com/reference/javax/xml/parsers/DocumentBuilderFactory#setFeature%28java.lang.String,%20boolean%29";>Android’s
+          own documentation</a>), so the library secures the platform’s 
parsers as best-effort. Android’s
+        <code>XmlPullParser</code>
+        API is not supported: it is not a JAXP API.
+      </p>
+    </section>
+    <section id="supported-implementations">
+      <h2>Supported Implementations</h2>
+      <p>
+        Out of the box the library recognizes the stock JDK JAXP 
implementations, Apache Xerces 2.x, Woodstox, and Saxon-HE. If a factory 
resolves to an
+        implementation not covered by any bundled securing recipe, every
+        <code>org.apache.commons.xml</code>
+        factory method throws
+        <code>IllegalStateException</code>
+        with a message naming the unsupported class. Adding support for a new 
JAXP implementation requires a code change to this library.
+      </p>
+      <p>
+        <strong>DOM Parsing</strong> via
+        <code>DocumentBuilderFactory</code>
+        :
+      </p>
+      <div class="sourceCode" id="cb1">
+        <pre class="sourceCode java">
+      <code class="sourceCode java">
+import org.w3c.dom.Document;
+import org.apache.commons.xml.SecureDocumentBuilderFactory;
+
+Document doc = 
SecureDocumentBuilderFactory.newInstance().newDocumentBuilder().parse(inputStream);
+      </code>
+    </pre>
+      </div>
+      <p>
+        <strong>SAX Parsing</strong> via
+        <code>SAXParserFactory</code>
+        :
+      </p>
+      <div class="sourceCode" id="cb2">
+        <pre class="sourceCode java">
+      <code class="sourceCode java">
+import org.apache.commons.xml.SecureSAXParserFactory;
+
+SecureSAXParserFactory.newInstance().newSAXParser().parse(inputStream, 
myDefaultHandler);
+      </code>
+    </pre>
+      </div>
+      <p>
+        <strong>Streaming (StAX) Parsing</strong> via
+        <code>XMLInputFactory</code>
+        :
+      </p>
+      <div class="sourceCode" id="cb3">
+        <pre class="sourceCode java">
+      <code class="sourceCode java">
+import javax.xml.stream.XMLStreamReader;
+import org.apache.commons.xml.SecureXMLInputFactory;
+
+XMLStreamReader reader = 
SecureXMLInputFactory.newInstance().createXMLStreamReader(inputStream);
+      </code>
+    </pre>
+      </div>
+      <p>
+        <strong>XSLT Transforms</strong> via
+        <code>TransformerFactory</code>
+        :
+      </p>
+      <div class="sourceCode" id="cb4">
+        <pre class="sourceCode java">
+      <code class="sourceCode java">
+import javax.xml.transform.stream.StreamSource;
+import javax.xml.transform.stream.StreamResult;
+import org.apache.commons.xml.SecureTransformerFactory;
+
+SecureTransformerFactory.newInstance()
+        .newTransformer(new StreamSource(stylesheet))
+        .transform(new StreamSource(inputStream), new 
StreamResult(outputStream));
+      </code>
+    </pre>
+      </div>
+      <p>
+        <strong>XPath Queries</strong> via
+        <code>XPathFactory</code>
+        :
+      </p>
+      <div class="sourceCode" id="cb5">
+        <pre class="sourceCode java">
+      <code class="sourceCode java">
+import javax.xml.xpath.XPathConstants;
+import org.w3c.dom.NodeList;
+import org.apache.commons.xml.SecureXPathFactory;
+
+NodeList hits = (NodeList) SecureXPathFactory.newInstance()
+        .newXPath()
+        .evaluate("//item", doc, XPathConstants.NODESET);
+      </code>
+    </pre>
+      </div>
+      <p>
+        <strong>W3C XML Schema Validation</strong> via
+        <code>SchemaFactory</code>
+        :
+      </p>
+      <div class="sourceCode" id="cb6">
+        <pre class="sourceCode java">
+      <code class="sourceCode java">
+import javax.xml.XMLConstants;
+import javax.xml.transform.stream.StreamSource;
+import org.apache.commons.xml.SecureSchemaFactory;
+
+SecureSchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI)
+        .newSchema(new StreamSource(xsdStream))
+        .newValidator()
+        .validate(new StreamSource(inputStream));
+      </code>
+    </pre>
+      </div>
+    </section>
+    <section id="wrappers-not-the-original-factories">
+      <h2>Wrappers, not the Original Factories</h2>
+      <p>A returned factory is not necessarily an instance of the underlying 
implementation. It might be (and usually is) a wrapper around it, so it cannot
+        be cast to the implementation’s own class. Everything else about the 
implementation’s behavior is preserved: features, properties, and attributes
+        delegate to it, and only the security behavior is applied.</p>
+      <p>Preserved behavior includes the choice of internal parsers. Each 
TrAX, XPath, or schema implementation has its own way of instantiating them, and
+        the library respects it:</p>
+      <ul>
+        <li>Stock JDK factories use the JDK parsers by default, and expose the 
<code>jdk.xml.overrideDefaultParser</code> feature (and Java system property
+          of the same name) to switch to parsers instantiated through 
<code>ServiceLoader</code>.
+        </li>
+        <li>Saxon selects its parsers through its own configuration.</li>
+      </ul>
+      <p>Whichever parser is selected, it is secured.</p>
+    </section>
+    <section id="factory-methods">
+      <h2>Factory Methods</h2>
+      <p>
+        Each factory class mirrors every static factory method its JAXP 
counterpart offers, so a secured factory is a drop-in replacement at any 
construction
+        site: the class-name/class-loader overloads and the StAX
+        <code>newFactory</code>
+        family (JDK 8),
+        <code>newDefaultInstance()</code>
+        (Java 9, <a 
href="https://bugs.openjdk.org/browse/JDK-8169778";>JDK-8169778</a>), and the 
namespace-aware
+        <code>newNSInstance()</code>
+        family (Java 13, <a 
href="https://bugs.openjdk.org/browse/JDK-8223423";>JDK-8223423</a>).
+      </p>
+      <p>
+        All of these methods work on every supported runtime, including Java 
8: - The
+        <code>newNSInstance</code>
+        methods enable namespace awareness on their non-NS counterpart, the 
behavior the JAXP methods are specified to have. - The
+        <code>newDefaultInstance</code>
+        methods resolve the platform’s own
+        <code>newDefaultInstance</code>
+        at run time and use it wherever the runtime provides one — Java 9 or 
later, and the Android API levels that ship the method — falling back to
+        instantiating the JDK’s built-in implementation by class name on Java 
8.
+      </p>
+      <p>
+        The
+        <code>newDefaultInstance</code>
+        methods are an opt-out of JAXP pluggability: they pin the platform’s 
built-in implementation instead of whatever a classpath lookup would resolve. 
That
+        suits a library with minimal XML requirements, which can parse with 
the well-known platform parser rather than delegate the choice of 
implementation to
+        the application developer.
+      </p>
+    </section>
+    <section id="stylesheets-and-schemas">
+      <h2>Stylesheets and Schemas</h2>
+      <p>
+        The securing applies to documents parsed through the returned factory. 
Stylesheets given to
+        <code>TransformerFactory.newTransformer(Source)</code>
+        and schemas given to
+        <code>SchemaFactory.newSchema(Source)</code>
+        are read by a parser the implementation picks internally, and that 
parser may not be secured (Saxon’s TrAX is one such case, see Building below). 
Treat
+        stylesheets and schemas as trusted input, or pre-parse them through a 
secured
+        <code>org.apache.commons.xml</code>
+        parser and pass the result as a
+        <code>DOMSource</code>
+        or
+        <code>SAXSource</code>
+        . A stylesheet also chooses where the transform writes (
+        <code>xsl:result-document</code>
+        ): the securing governs reads only, so restrict output destinations 
yourself when running an untrusted stylesheet (see the <a 
href="threat_model.html">Threat
+          Model</a>).
+      </p>
+    </section>
+    <section id="transformer-handlers-and-filters">
+      <h2>Transformer Handlers and Filters</h2>
+      <p>
+        The
+        <code>SAXTransformerFactory</code>
+        extension methods,
+        <code>newTransformerHandler(...)</code>
+        ,
+        <code>newTemplatesHandler()</code>
+        and
+        <code>newXMLFilter(...)</code>
+        , if reachable by casting the factory from
+        <code>SecureTransformerFactory.newInstance()</code>
+        , produce handlers, filters and
+        <code>Templates</code>
+        carrying the same securing as the standard entry points: runtime
+        <code>document()</code>
+        resolves to empty content, and a filter with no caller-set parent 
parses its input through a secured reader. The SAX events you feed into a 
handler, and
+        a parent reader you set on a filter, are your own configuration, like 
any caller-supplied parser. See the <a href="threat_model.html">Threat Model</a>
+        for the exact scope.
+      </p>
+    </section>
+    <section id="caching-and-thread-safety">
+      <h2>Caching and Thread-Safety</h2>
+      <p>
+        There is no caching or pooling inside
+        <code>org.apache.commons.xml</code>
+        ; callers on a hot path are responsible for their own caching. The 
returned factories inherit the thread-safety properties of the underlying JAXP
+        implementation, which in practice means they are not thread-safe. 
Create a new factory per thread or synchronize externally.
+      </p>
+    </section>
+  </section>
+  <section id="configuration">
+    <h1>
+      <img src="org/apache/commons/xml/doc-files/leaf.svg" style="height: 1em; 
padding-right: 0.25em" alt="leaf">Configuration
+    </h1>
+    <p>The secured factories need no configuration. When a document references 
an external resource (a DTD, an external entity, a schema, an XInclude
+      target, or an XSLT document), the securing layer resolves the reference 
to an empty stream: nothing is fetched, nothing leaks into the result, and the
+      parse continues wherever the implementation can proceed with empty 
content. This forgiving default accommodates documents that merely carry such
+      references without needing them.</p>
+    <p>
+      If your application should reject such documents instead of parsing 
them, tighten the factory yourself. The securing floor stays underneath 
whatever you
+      configure, so the tightening carries <strong>no security weight</strong> 
and can be as strict as the application needs:
+    </p>
+    <ul>
+      <li>Set a stricter feature on the factory, for example 
<code>http://apache.org/xml/features/disallow-doctype-decl</code> to reject 
every document
+        carrying a DOCTYPE, on implementations that support the feature.
+      </li>
+      <li>Install a resolver that throws. A caller-supplied 
<code>EntityResolver</code>, <code>XMLResolver</code>, 
<code>LSResourceResolver</code> or <code>URIResolver</code>
+        is consulted before the securing floor, so an allow-list and a 
deny-all are both one resolver away.
+      </li>
+    </ul>
+    <p>
+      As a temporary debugging measure, set the system property
+      <code>org.apache.commons.xml.throwOnUnresolved</code>
+      to
+      <code>true</code>
+      : every unresolved external reference is then rejected with the 
resolution hook’s exception, and the message names the denied resource. The 
property is
+      read at resolution time, so it can be toggled on a running application; 
treat it as a diagnostic switch, not as an application configuration.
+    </p>
+  </section>
+</body>
\ No newline at end of file
diff --git a/src/site/markdown/index.md b/src/site/markdown/index.md
index 6a762f1..ed23283 100644
--- a/src/site/markdown/index.md
+++ b/src/site/markdown/index.md
@@ -18,232 +18,12 @@ limitations under the License.
 # Apache Commons Secure XML
 
 Apache Commons Secure XML is part of the
-[Apache Commons](https://commons.apache.org/index.html) project.
-
-Apache Commons Secure XML provides secure-by-default JAXP factory creation,
+[Apache Commons](https://commons.apache.org/index.html) and provides 
secure-by-default JAXP factory creation,
 abstracting over implementation-specific XXE securing differences between the
 stock JDK and external JAXP implementations.
 
+Full documentation is provided in:
 
-## Why
-
-Any Java library that parses XML has to secure JAXP before handing a factory 
to user code, and every library ends up
-copy-pasting the same securing snippet. The snippet is fragile: the attributes 
and features needed to secure a factory
-are not standardized, each JAXP implementation exposes a slightly different 
set, and setting an unknown one throws an
-exception that callers routinely swallow. Writing this block correctly for 
every implementation is real work, and
-duplicating it across projects means every project owns the maintenance burden 
on its own.
-
-Defaults are also uneven. The stock JDK SAX and DOM parsers already prevent 
external entity resolution through
-`FEATURE_SECURE_PROCESSING`, and JAXP 1.5 conformant implementations ship 
reasonable defaults for most attacks. Others,
-such as standalone Xerces, Woodstox, or Saxon's TrAX, need further 
configuration before they reach the same baseline. A
-library author has no control over which implementation is on the classpath at 
runtime, so the effective security
-posture of their code depends on a deployment decision made elsewhere.
-
-This library provides that baseline. Each `org.apache.commons.xml` factory 
call returns a new factory secured by an
-implementation-specific recipe, so the returned object behaves the same way 
security-wise regardless of which JAXP
-implementation resolved. Security becomes a property of the call, not of the 
classpath, and there is one place to
-update when a new securing setting becomes available or a default changes.
-
-## Usage
-
-To add the library to your build, see <a href="dependency-info.html">Maven 
Coordinates</a>.
-(Maven Coordinates)[dependency-info.html]
-
-Every factory method in `org.apache.commons.xml` returns a new, secured 
factory.
-Pick the one that matches the API you already use;
-no other configuration is required.
-On secured factories an external resource reference (DTD, entity, schema, 
stylesheet) is never fetched:
-it resolves to empty content,
-so the parse continues without it
-(see Configuration below).
-
-### Supported Runtimes
-
-The library requires OpenJDK 8 or later (or a JDK distribution built from it), 
or Android API level 26 or later.
-
-The security guarantees are defined only on the OpenJDK family
-(see the [Threat Model](threat_model.html)).
-No version of Android supports `FEATURE_SECURE_PROCESSING`
-(so states [Android's own 
documentation](https://developer.android.com/reference/javax/xml/parsers/DocumentBuilderFactory#setFeature%28java.lang.String,%20boolean%29)),
-so the library secures the platform's parsers as best-effort.
-Android's `XmlPullParser` API is not supported:
-it is not a JAXP API.
-
-### Supported Implementations
-
-Out of the box the library recognizes the stock JDK JAXP implementations, 
Apache Xerces 2.x, Woodstox, and Saxon-HE. If
-a factory resolves to an implementation not covered by any bundled securing 
recipe, every `org.apache.commons.xml` factory method throws
-`IllegalStateException` with a message naming the unsupported class. Adding 
support for a new JAXP implementation
-requires a code change to this library.
-
-**DOM Parsing** via `DocumentBuilderFactory`:
-
-```java
-import org.w3c.dom.Document;
-import org.apache.commons.xml.SecureDocumentBuilderFactory;
-
-Document doc = 
SecureDocumentBuilderFactory.newInstance().newDocumentBuilder().parse(inputStream);
-```
-
-**SAX Parsing** via `SAXParserFactory`:
-
-```java
-import org.apache.commons.xml.SecureSAXParserFactory;
-
-SecureSAXParserFactory.newInstance().newSAXParser().parse(inputStream, 
myDefaultHandler);
-```
-
-**Streaming (StAX) Parsing** via `XMLInputFactory`:
-
-```java
-import javax.xml.stream.XMLStreamReader;
-import org.apache.commons.xml.SecureXMLInputFactory;
-
-XMLStreamReader reader = 
SecureXMLInputFactory.newInstance().createXMLStreamReader(inputStream);
-```
-
-**XSLT Transforms** via `TransformerFactory`:
-
-```java
-import javax.xml.transform.stream.StreamSource;
-import javax.xml.transform.stream.StreamResult;
-import org.apache.commons.xml.SecureTransformerFactory;
-
-SecureTransformerFactory.newInstance()
-        .newTransformer(new StreamSource(stylesheet))
-        .transform(new StreamSource(inputStream), new 
StreamResult(outputStream));
-```
-
-**XPath Queries** via `XPathFactory`:
-
-```java
-import javax.xml.xpath.XPathConstants;
-import org.w3c.dom.NodeList;
-import org.apache.commons.xml.SecureXPathFactory;
-
-NodeList hits = (NodeList) SecureXPathFactory.newInstance()
-        .newXPath()
-        .evaluate("//item", doc, XPathConstants.NODESET);
-```
-
-**W3C XML Schema Validation** via `SchemaFactory`:
-
-```java
-import javax.xml.XMLConstants;
-import javax.xml.transform.stream.StreamSource;
-import org.apache.commons.xml.SecureSchemaFactory;
-
-SecureSchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI)
-        .newSchema(new StreamSource(xsdStream))
-        .newValidator()
-        .validate(new StreamSource(inputStream));
-```
-
-### Wrappers, not the Original Factories
-
-A returned factory is not necessarily an instance of the underlying 
implementation.
-It might be (and usually is) a wrapper around it,
-so it cannot be cast to the implementation's own class.
-Everything else about the implementation's behavior is preserved:
-features, properties, and attributes delegate to it,
-and only the security behavior is applied.
-
-Preserved behavior includes the choice of internal parsers.
-Each TrAX, XPath, or schema implementation has its own way of instantiating 
them,
-and the library respects it:
-
-- Stock JDK factories use the JDK parsers by default,
-  and expose the `jdk.xml.overrideDefaultParser` feature
-  (and Java system property of the same name)
-  to switch to parsers instantiated through `ServiceLoader`.
-- Saxon selects its parsers through its own configuration.
-
-Whichever parser is selected, it is secured.
-
-### Factory Methods
-
-Each factory class mirrors every static factory method its JAXP counterpart 
offers,
-so a secured factory is a drop-in replacement at any construction site:
-the class-name/class-loader overloads and the StAX `newFactory` family (JDK 8),
-`newDefaultInstance()` (Java 9, 
[JDK-8169778](https://bugs.openjdk.org/browse/JDK-8169778)),
-and the namespace-aware `newNSInstance()` family (Java 13, 
[JDK-8223423](https://bugs.openjdk.org/browse/JDK-8223423)).
-
-All of these methods work on every supported runtime, including Java 8:
-- The `newNSInstance` methods enable namespace awareness on their non-NS 
counterpart,
-  the behavior the JAXP methods are specified to have.
-- The `newDefaultInstance` methods resolve the platform's own 
`newDefaultInstance` at run time
-  and use it wherever the runtime provides one —
-  Java 9 or later, and the Android API levels that ship the method —
-  falling back to instantiating the JDK's built-in implementation by class 
name on Java 8.
-
-The `newDefaultInstance` methods are an opt-out of JAXP pluggability:
-they pin the platform's built-in implementation
-instead of whatever a classpath lookup would resolve.
-That suits a library with minimal XML requirements,
-which can parse with the well-known platform parser
-rather than delegate the choice of implementation to the application developer.
-
-### Stylesheets and Schemas
-
-The securing applies to documents parsed through the returned factory. 
Stylesheets given to
-`TransformerFactory.newTransformer(Source)` and schemas given to 
`SchemaFactory.newSchema(Source)` are read by a parser
-the implementation picks internally, and that parser may not be secured 
(Saxon's TrAX is one such case, see Building
-below). Treat stylesheets and schemas as trusted input, or pre-parse them 
through a secured `org.apache.commons.xml` parser and
-pass the result as a `DOMSource` or `SAXSource`.
-A stylesheet also chooses where the transform writes (`xsl:result-document`):
-the securing governs reads only,
-so restrict output destinations yourself when running an untrusted stylesheet
-(see the [Threat Model](threat_model.html)).
-
-### Transformer Handlers and Filters
-
-The `SAXTransformerFactory` extension methods, `newTransformerHandler(...)`, 
`newTemplatesHandler()` and `newXMLFilter(...)`,
-if reachable by casting the factory from 
`SecureTransformerFactory.newInstance()`,
-produce handlers, filters and `Templates` carrying the same securing as the 
standard entry points:
-runtime `document()` resolves to empty content,
-and a filter with no caller-set parent parses its input through a secured 
reader.
-The SAX events you feed into a handler, and a parent reader you set on a 
filter,
-are your own configuration, like any caller-supplied parser.
-See the [Threat Model](threat_model.html) for the exact scope.
-
-### Caching and Thread-Safety
-
-There is no caching or pooling inside `org.apache.commons.xml`; callers on a 
hot path are responsible for their own caching. The
-returned factories inherit the thread-safety properties of the underlying JAXP 
implementation, which in practice means
-they are not thread-safe. Create a new factory per thread or synchronize 
externally.
-
-## Configuration
-
-The secured factories need no configuration.
-When a document references an external resource
-(a DTD, an external entity, a schema, an XInclude target, or an XSLT document),
-the securing layer resolves the reference to an empty stream:
-nothing is fetched,
-nothing leaks into the result,
-and the parse continues wherever the implementation can proceed with empty 
content.
-This forgiving default accommodates documents that merely carry such 
references without needing them.
-
-If your application should reject such documents instead of parsing them,
-tighten the factory yourself.
-The securing floor stays underneath whatever you configure,
-so the tightening carries **no security weight**
-and can be as strict as the application needs:
-
-- Set a stricter feature on the factory,
-  for example `http://apache.org/xml/features/disallow-doctype-decl`
-  to reject every document carrying a DOCTYPE,
-  on implementations that support the feature.
-- Install a resolver that throws.
-  A caller-supplied `EntityResolver`, `XMLResolver`, `LSResourceResolver` or 
`URIResolver`
-  is consulted before the securing floor,
-  so an allow-list and a deny-all are both one resolver away.
-
-As a temporary debugging measure,
-set the system property `org.apache.commons.xml.throwOnUnresolved` to `true`:
-every unresolved external reference is then rejected with the resolution 
hook's exception,
-and the message names the denied resource.
-The property is read at resolution time,
-so it can be toggled on a running application;
-treat it as a diagnostic switch,
-not as an application configuration.
-
+- [Javadoc Overview](apidocs/index.html),
+- [Javadoc Package 
Summary](apidocs/org/apache/commons/xml/package-summary.html), and
+- [Project Reports](project-reports.html).

Reply via email to