proof-of-concept for DigesterLoader

This commit is contained in:
Rick Giles 2002-12-01 22:20:48 +00:00
parent e09a108f22
commit 04ad1d6947
5 changed files with 335 additions and 0 deletions

View File

@ -0,0 +1,20 @@
<?xml version="1.0"?>
<configuration tabWidth="4" basedir="${checkstyle.basedir}">
<TreeWalker>
<AvoidStarImport/>
<MemberNameCheck
format="^m_[a-zA-Z0-9]*$"/>
<ConstantNameCheck/>
<EmptyBlockCheck/>
<EqualsHashCodeCheck/>
<FileLengthCheck/>
<NoWhitespaceAfterCheck
tokens="DOT"
allowLineBreaks="true"/>
<GenericIllegalRegexpCheck
format="System.out.println"/>
</TreeWalker>
<PackageHtmlCheck/>
<TranslationCheck/>
</configuration>

View File

@ -0,0 +1,27 @@
<?xml version="1.0"?>
<digester-rules>
<!-- This form of rule is also accepted
<pattern value="configuration">
<config-create-rule
shortname="configuration"
classname="com.puppycrawl.tools.checkstyle.Configuration" />
</pattern>
-->
<config-create-rule
pattern="configuration"
classname="com.puppycrawl.tools.checkstyle.Configuration" />
<config-create-rule
pattern="*/TreeWalker"
classname="com.puppycrawl.tools.checkstyle.TreeWalker" />
<config-create-rule
pattern="*/AvoidStarImport"
classname="com.puppycrawl.tools.checkstyle.AvoidStarImport" />
<config-create-rule
pattern="*/MemberNameCheck"
classname="com.puppycrawl.tools.checkstyle.MemberNameCheck" />
</digester-rules>

View File

@ -0,0 +1,97 @@
////////////////////////////////////////////////////////////////////////////////
// checkstyle: Checks Java source code for adherence to a set of rules.
// Copyright (C) 2001-2002 Oliver Burn
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
////////////////////////////////////////////////////////////////////////////////
package com.puppycrawl.tools.checkstyle;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.Properties;
import java.util.Stack;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParserFactory;
import com.puppycrawl.tools.checkstyle.api.Configuration;
import org.apache.commons.digester.Digester;
import org.apache.commons.digester.RuleSet;
import org.apache.commons.digester.xmlrules.FromXmlRuleSet;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import com.puppycrawl.tools.checkstyle.api.CheckstyleException;
/**
* Describe class <code>ConfigurationLoaderDigester</code> here.
*
* @author <a href="mailto:checkstyle@puppycrawl.com">Oliver Burn</a>
* @version 1.0
*/
class ConfigurationDigesterLoader
extends DefaultHandler
{
/** overriding properties **/
private Properties mOverrideProps = new Properties();
/**
* Creates a new <code>ConfigurationLoaderDigester</code> instance.
* @throws ParserConfigurationException if an error occurs
* @throws SAXException if an error occurs
*/
private ConfigurationDigesterLoader()
{
}
/**
* Returns the check configurations in a specified file.
* @param aRulesFname name of digester rules file
* @param aConfigFname name of config file
* @param aOverrideProps overriding properties
* @return the check configurations
* @throws CheckstyleException if an error occurs
*/
public static Configuration loadConfiguration(String aRulesFname,
String aConfigFname,
Properties aOverrideProps)
throws CheckstyleException
{
try {
final File rulesFile = new File(aRulesFname);
final File configFile = new File(aConfigFname);
final RuleSet ruleSet = new FromXmlRuleSet(rulesFile.toURL(),
new ConfigurationRuleParser());
final Digester digester = new Digester();
digester.addRuleSet(ruleSet);
digester.setValidating(false);
digester.push(new DefaultConfiguration("root"));
//TODO: apply aOverrideProps and perform property expansion
return (DefaultConfiguration) digester.parse(configFile);
}
catch (FileNotFoundException e) {
throw new CheckstyleException("unable to find " + aConfigFname);
}
catch (SAXException e) {
throw new CheckstyleException("unable to parse "
+ aConfigFname + " - " + e.getMessage());
}
catch (IOException e) {
throw new CheckstyleException("unable to read " + aConfigFname);
}
}
}

View File

@ -0,0 +1,168 @@
package com.puppycrawl.tools.checkstyle;
import org.apache.commons.digester.AbstractObjectCreationFactory;
import org.apache.commons.digester.Digester;
import org.apache.commons.digester.Rule;
import org.apache.commons.digester.xmlrules.DigesterRuleParser;
import org.xml.sax.Attributes;
/**
* This is a RuleSet that parses XML into Digester rules, and then
* adds those rules to a 'target' Digester.
* @author Rick Giles
* @version 1-Dec-2002
*/
public class ConfigurationRuleParser extends DigesterRuleParser
{
/** name of the Rule class */
private final String ruleClassName = Rule.class.getName();
/** @see org.apache.commons.digester.xmlrules.DigesterRuleParser */
public void addRuleInstances(Digester aDigester)
{
super.addRuleInstances(aDigester);
aDigester.addFactoryCreate(
"*/config-create-rule", new ConfigCreateRuleFactory());
aDigester.addRule(
"*/config-create-rule", new PatternRule("pattern"));
aDigester.addSetNext("*/config-create-rule", "add", ruleClassName);
}
/**
* Factory for creating a configCreateRule
*/
protected class ConfigCreateRuleFactory
extends AbstractObjectCreationFactory
{
public Object createObject(Attributes anAttributes)
{
final String className = anAttributes.getValue("classname");
return new ConfigCreateRule(className);
}
}
/**
* A rule for extracting the pattern matching strings from the rules XML.
* In the digester-rules document type, a pattern can either be declared
* in the 'value' attribute of a <pattern> element (in which case the
* pattern applies to all rules elements contained within the <pattern>
* element), or it can be declared in the optional 'pattern' attribute of
* a rule element.
*/
private class PatternRule extends Rule
{
private String mAttrName;
private String mPattern = null;
/**
* Creates a pattern rule.
* @param attrName The name of the attribute containing the pattern
*/
public PatternRule(String aAttrName)
{
mAttrName = aAttrName;
}
/**
* If a pattern is defined for the attribute, push it onto the
* pattern stack.
* @param aAttrs the attributes to search.
*
*/
public void begin(Attributes aAttrs)
{
mPattern = aAttrs.getValue(mAttrName);
if (mPattern != null) {
patternStack.push(mPattern);
}
}
/**
* If there was a pattern for this element, pop it off the pattern
* stack.
*/
public void end()
{
if (mPattern != null) {
patternStack.pop();
}
}
}
protected class ConfigCreateRule extends Rule
{
/** name of the class for the configuration */
private String mClassName;
/**
* Construct an configuration create rule with the specified class
* name.
*
* @param aClassName Java class name of the object to be created
*/
public ConfigCreateRule(String aClassName)
{
mClassName = aClassName;
}
/**
* Process the beginning of this element.
* @param aAtts The attribute list of this element
*/
public void begin(Attributes aAtts)
{
// TODO: add logging
// if (digester.log.isDebugEnabled()) {
// digester.log.debug(
// "[ObjectCreateRule]{" + digester.match + "}New "
// + realClassName);
// }
// Instantiate the new object and push it on the context stack
final DefaultConfiguration config =
new DefaultConfiguration(mClassName);
config.addAttribute("classname", mClassName);
final int attCount = aAtts.getLength();
for (int i = 0; i < attCount; i++) {
final String name = aAtts.getQName(i);
final String value = aAtts.getValue(i);
config.addAttribute(name, value);
}
final DefaultConfiguration parent =
(DefaultConfiguration) digester.peek();
parent.addChild(config);
digester.push(config);
}
/**
* Process the end of this element.
*/
public void end()
{
Object top = digester.pop();
// TODO: add logging
// if (digester.log.isDebugEnabled()) {
// digester.log.debug("[ObjectCreateRule]{" + digester.match +
// "} Pop " + top.getClass().getName());
// }
}
/**
* Render a printable version of this Rule.
* @return a String representation of this Rule.
*/
public String toString()
{
StringBuffer sb = new StringBuffer("ConfigCreateRule[");
sb.append("className=");
sb.append(mClassName);
sb.append("]");
return (sb.toString());
}
}
}

View File

@ -0,0 +1,23 @@
package com.puppycrawl.tools.checkstyle;
import com.puppycrawl.tools.checkstyle.api.Configuration;
public class DigesterLoaderTest
{
public static void main(String[] args)
{
try {
final String inputFname = "src/digester/checkstyle_checks.xml";
final String rulesFname = "src/digester/checkstyle_rules.xml";
final Configuration config =
ConfigurationDigesterLoader.loadConfiguration(
rulesFname, inputFname, null);
System.out.println(config.toString());
}
catch (Exception exc) {
exc.printStackTrace();
}
}
}