XInclude Processing

Description

This is an example of how you can separate a Checkstyle configuration file into several files and process the configuration using XInclude processing. This requires a SAX parser that supports XML namespaces. First we give an example a SAX parser factory that produces parsers supporting XML namespaces and indicate how to configure your system to use this factory. Then we give an example XML configuration files with XInclude processing and an ant target that uses the Checkstyle ant task to check a Java source file with the configuration files.

Parsers

SAX parser factory NamespacesSAXParserFactoryImpl is an example of a factory that produces parsers supporting XML namespaces:

package com.puppycrawl.tools.checkstyle;

import org.apache.xerces.jaxp.SAXParserFactoryImpl;

/**
 * A parser factory that produces parsers that support XML namespaces. 
 * @author Rick Giles
 * @version May 28, 2004
 */
public class NamespacesSAXParserFactoryImpl extends SAXParserFactoryImpl
{
    /**
     * Constructs a NamespacesSAXParserFactoryImpl. Initializes
     * it to produce parsers that support XML namespaces. 
     */
    public NamespacesSAXParserFactoryImpl()
    {
        super();
        setNamespaceAware(true);
    }
}

In order to use NamespacesSAXParserFactoryImpl as the SAX parser factory, place NamespacesSAXParserFactoryImpl in the classpath and configure your system to load NamespacesSAXParserFactoryImpl as the SAXParserFactory. For example, you can create a file called jaxp.properties in the lib subdirectory of the JRE installation with contents

javax.xml.parsers.SAXParserFactory=com.puppycrawl.tools.checkstyle.NamespacesSAXParserFactoryImpl

XInclude processing requires an XML parser that implements XML inclusions. Here we use the Xerces parser that is in the ant distribution. In order to enable Xinclude processing, you can change the parser configuration by creating a file called xerces.properties in the lib subdirectory of the JRE installation with contents

org.apache.xerces.xni.parser.XMLParserConfiguration=org.apache.xerces.parsers.XIncludeParserConfiguration

Checkstyle Configuration

The Checkstyle configuration of this example is in two files. File config.xml has an internal DTD that supports xi:include elements:

<?xml version="1.0"?>
<!DOCTYPE module [
<!ELEMENT module (module|property|xi:include)*>
<!ATTLIST module name NMTOKEN #REQUIRED>

<!ELEMENT xi:include EMPTY>
<!ATTLIST xi:include
    href CDATA #REQUIRED
    xmlns:xi CDATA #REQUIRED
>

<!ELEMENT property EMPTY>
<!ATTLIST property
    name NMTOKEN #REQUIRED
    value CDATA #REQUIRED
    default CDATA #IMPLIED
>
]>
<module name="Checker">
    <module name="TreeWalker">
        <xi:include
            href="treewalker.xml"
            xmlns:xi="http://www.w3.org/2003/XInclude"/>
    </module>
</module>

The configuration in config.xml includes a second configuration file, treewalker.xml, that applies the TypeName module:

<?xml version="1.0"?>
<!DOCTYPE module PUBLIC
    "-//Puppy Crawl//DTD Check Configuration 1.2//EN"
    "http://www.puppycrawl.com/dtds/configuration_1_2.dtd">
<module name="TypeName">
    <property name="format" value="${typename.format}"/>
</module>

Notice that the configuration of treewalker.xml applies property ${typename.format}. That propery is set in the following segment of an ant build file that uses the Checkstyle ant task to check file InputHeader.java with the configuration of config.xml:

    <taskdef
        resource="checkstyletask.properties"
        classpath="/path/to/checkstyle-all-@CHECKSTYLE_VERSION@.jar" />
    <target name="checkstyle" description="run checkstyle">
        <checkstyle file="InputHeader.java" config="config.xml">
            <property key="typename.format" value="xyz" />
        </checkstyle>
    </target>