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

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

commit ecf0a52983aeaf1e93e97a6e3feb702d87c13d5a
Author: Piotr P. Karwasz <[email protected]>
AuthorDate: Thu Apr 23 09:44:00 2026 +0200

    feat: provide simple web page
---
 pom.xml                    |   5 +-
 src/site/markdown/index.md | 145 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 148 insertions(+), 2 deletions(-)

diff --git a/pom.xml b/pom.xml
index 6264ec5..5b483e7 100644
--- a/pom.xml
+++ b/pom.xml
@@ -44,9 +44,10 @@
     <commons.packageId>xml.factory</commons.packageId>
     
<project.build.outputTimestamp>2026-04-22T00:00:00Z</project.build.outputTimestamp>
 
-    <!-- JIRA coordinates (to be assigned) -->
+    <!-- JIRA coordinates (to be assigned)
     <commons.jira.id>COMMONSXMLFACTORY</commons.jira.id>
-    <commons.jira.pid>12300000</commons.jira.pid>
+    <commons.jira.pid>12300000</commons.jira.pid> -->
+    <changes.jira.skip>true</changes.jira.skip>
 
     <!-- Java baseline -->
     <maven.compiler.source>1.8</maven.compiler.source>
diff --git a/src/site/markdown/index.md b/src/site/markdown/index.md
new file mode 100644
index 0000000..a7e7878
--- /dev/null
+++ b/src/site/markdown/index.md
@@ -0,0 +1,145 @@
+<!--
+ 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.
+-->
+# Apache Commons XML Factory
+
+Apache Commons XML Factory provides secure-by-default JAXP factory creation,
+abstracting over implementation-specific XXE hardening differences between the
+stock JDK and external JAXP implementations.
+
+
+## Why
+
+Any Java library that parses XML has to harden JAXP before handing a factory 
to user code, and every library ends up
+copy-pasting the same hardening snippet. The snippet is fragile: the 
attributes and features needed to harden a factory
+are not standardised, 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 `XmlFactories` call returns a fresh 
factory hardened by a provider-specific
+SPI, 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 hardening
+setting becomes available or a default changes.
+
+## Usage
+
+Add the library to your build:
+
+```xml
+<dependency>
+  <groupId>org.apache.commons</groupId>
+  <artifactId>commons-xml-factory</artifactId>
+  <version>${commons.release.version}</version>
+</dependency>
+```
+
+Every method on `XmlFactories` returns a fresh, hardened factory. Pick the one 
that matches the API you already use; no
+other configuration is required. On hardened factories any attempt to resolve 
an external resource (DTD, entity, schema,
+stylesheet) is blocked, and DOCTYPE input is rejected wherever the underlying 
implementation allows it.
+
+### Supported implementations
+
+Out of the box the library recognises 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 or 
registered provider, every `XmlFactories` method
+throws `UnsupportedXmlImplementationException`.
+
+Support for additional implementations can be plugged in by publishing an
+`org.apache.commons.xml.factory.spi.XmlProvider` through the standard Java 
`ServiceLoader` mechanism. Bundled providers
+always take precedence, so a third-party provider cannot hijack hardening for 
a factory class this library already
+supports.
+
+**DOM parsing** via `DocumentBuilderFactory`:
+
+```java
+import org.w3c.dom.Document;
+import org.apache.commons.xml.factory.XmlFactories;
+
+Document doc = 
XmlFactories.newDocumentBuilderFactory().newDocumentBuilder().parse(inputStream);
+```
+
+**SAX parsing** via `SAXParserFactory`:
+
+```java
+import org.apache.commons.xml.factory.XmlFactories;
+
+XmlFactories.newSAXParserFactory().newSAXParser().parse(inputStream, 
myDefaultHandler);
+```
+
+**Streaming (StAX) parsing** via `XMLInputFactory`:
+
+```java
+import javax.xml.stream.XMLStreamReader;
+import org.apache.commons.xml.factory.XmlFactories;
+
+XMLStreamReader reader = 
XmlFactories.newXMLInputFactory().createXMLStreamReader(inputStream);
+```
+
+**XSLT transforms** via `TransformerFactory`:
+
+```java
+import javax.xml.transform.stream.StreamSource;
+import javax.xml.transform.stream.StreamResult;
+import org.apache.commons.xml.factory.XmlFactories;
+
+XmlFactories.newTransformerFactory()
+        .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.factory.XmlFactories;
+
+NodeList hits = (NodeList) XmlFactories.newXPathFactory()
+        .newXPath()
+        .evaluate("//item", doc, XPathConstants.NODESET);
+```
+
+**W3C XML Schema validation** via `SchemaFactory`:
+
+```java
+import javax.xml.transform.stream.StreamSource;
+import org.apache.commons.xml.factory.XmlFactories;
+
+XmlFactories.newSchemaFactory()
+        .newSchema(new StreamSource(xsdStream))
+        .newValidator()
+        .validate(new StreamSource(inputStream));
+```
+
+### Stylesheets and schemas
+
+The hardening 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 hardened 
(Saxon's TrAX is one such case, see Building
+below). Treat stylesheets and schemas as trusted input, or pre-parse them 
through a hardened `XmlFactories` parser and
+pass the result as a `DOMSource` or `SAXSource`.
+
+### Caching and thread-safety
+
+There is no caching or pooling inside `XmlFactories`; 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 synchronise 
externally.
+

Reply via email to