Skip to content

Decouple ODF DOM Layer from Implementation-Specific XML Libraries #428

@svanteschubert

Description

@svanteschubert

1. Description

Currently, the ODF Toolkit’s DOM classes directly extend implementation-specific classes (e.g., Apache Xerces). This creates significant technical debt and "Dependency Hell" for downstream projects that require different XML implementations or specific versions of Xerces that conflict with the Toolkit’s requirements.

As pointed out by Axel in Issue #54, the ODF Toolkit should not rely on a particular implementation. While the JDK includes a Xerces-based implementation by default, the internal classes are not exposed. Relying on external Xerces implementation classes prevents the Toolkit from being a truly portable library.

2. The Core Problem: Inheritance vs. Delegation

The current architecture uses an "is-a" relationship:

  • OdfElement extends org.apache.xerces.dom.ElementImpl

This makes it impossible to swap the underlying XML engine without a major rewrite. To achieve implementation independence, we must move to a "has-a" relationship (The Adapter/Delegation Pattern):

  • OdfElement implements org.w3c.dom.Element and wraps a generic JAXP-provided Node.

3. Proposed Solution: JAXP Abstraction Layer

We should rely exclusively on the interfaces defined in JAXP (Java API for XML Processing).

A. Configuration-Based Factory

Create a central factory to handle document creation. This allows the Toolkit to have a default (like Xerces) while allowing users to override it via configuration.

public class OdfXmlFactory {
    /**
     * Provides a DocumentBuilder based on:
     * 1. A system property override
     * 2. Standard JAXP discovery (META-INF/services)
     * 3. A default fallback implementation
     */
    public static DocumentBuilder getDocumentBuilder() throws Exception {
        String customFactory = System.getProperty("odftoolkit.xml.factory");
        
        if (customFactory != null) {
            return DocumentBuilderFactory.newInstance(customFactory, null).newDocumentBuilder();
        }
        
        // Standard JAXP discovery mechanism
        return DocumentBuilderFactory.newInstance().newDocumentBuilder();
    }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions