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.
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
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>