Moved the PMD plugin from http://sourceforge.net/projects/maven-plugins to the Maven CVS. I will move it to another place when we decide to have plugins hosted in a different subproject of maven.apache.org.

git-svn-id: https://svn.apache.org/repos/asf/maven/maven-1/plugins/trunk@113253 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
vmassol 2003-04-03 18:58:12 +00:00
parent 34d3f2b082
commit 5a9dfe3d3c
26 changed files with 1786 additions and 0 deletions

57
pmd/LICENSE.txt Normal file
View File

@ -0,0 +1,57 @@
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2001 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" and
* "Apache Wiki Maven Plugin" must not be used to endorse or promote products
* derived from this software without prior written permission. For
* written permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* "Apache Interactive Maven Plugin", nor may "Apache" appear in their name, without
* prior written permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* ====================================================================
*/

67
pmd/plugin.jelly Normal file
View File

@ -0,0 +1,67 @@
<?xml version="1.0"?>
<project
xmlns:j="jelly:core"
xmlns:doc="doc">
<goal name="maven-pmd-plugin:register">
<j:if test="${sourcesPresent}">
<doc:registerReport
name="PMD"
link="pmd-report"
description="PMD Report."/>
</j:if>
</goal>
<!-- ================================================================== -->
<!-- P M D T A R G E T -->
<!-- ================================================================== -->
<goal name="pmd" description="Static Code Analyzer">
<!-- Only run PMD if it is enabled -->
<j:set var="enable" value="${maven.pmd.enable}"/>
<!-- Either am bloody dumb or this is the only way to make it work ?! -->
<j:if test="${enable.toString().equalsIgnoreCase('true')}">
<attainGoal name="maven-pmd-plugin:report"/>
</j:if>
</goal>
<goal name="maven-pmd-plugin:report"
description="Generate source code report with PMD">
<!-- Create the dirs if we start from a previously cleaned project -->
<mkdir dir="${maven.build.dir}"/>
<mkdir dir="${maven.docs.dest}"/>
<!-- Define a PMD task with the rulesets and all jars in the classpath -->
<taskdef name="pmd" classname="net.sourceforge.pmd.ant.PMDTask"/>
<!-- Run the PMD task - need a way to define the rulesets dynamically -->
<echo>Running the PMD task with ${maven.pmd.rulesetfiles} ...</echo>
<pmd rulesetfiles="${maven.pmd.rulesetfiles}">
<formatter type="xml" toFile="${maven.build.dir}/pmd-raw-report.xml"/>
<fileset dir="${basedir}/${pom.build.sourceDirectory}">
<include name="**/*.java"/>
</fileset>
</pmd>
<!-- Run DVSL to transform the report into XDOC -->
<echo>Converting the PMD report to XDOC ...</echo>
<doc:jsl
input="${maven.build.dir}/pmd-raw-report.xml"
output="pmd-report.xml"
stylesheet="${plugin.dir}/pmd.jsl"
omitXmlDeclaration="true"
outputMode="xml"
prettyPrint="true"
/>
</goal>
</project>

14
pmd/plugin.properties Normal file
View File

@ -0,0 +1,14 @@
# -------------------------------------------------------------------
# P L U G I N P R O P E R I E S
# -------------------------------------------------------------------
# PMD plugin.
# -------------------------------------------------------------------
# enable/disable PMD
maven.pmd.enable = true
# comma seperated list of rules to use
# rulesets/experimental.xml is, well, experimental ... use at your own risk
maven.pmd.rulesetfiles=rulesets/strings.xml,rulesets/junit.xml,rulesets/braces.xml,rulesets/basic.xml,rulesets/unusedcode.xml,rulesets/design.xml,rulesets/naming.xml,rulesets/imports.xml,rulesets/codesize.xml

124
pmd/pmd.jsl Normal file
View File

@ -0,0 +1,124 @@
<?xml version="1.0"?>
<jsl:stylesheet
select="$doc"
xmlns:j="jelly:core"
xmlns:jsl="jelly:jsl"
xmlns:util="jelly:util"
xmlns:x="jelly:xml"
xmlns:doc="doc"
xmlns="dummy" trim="false">
<!-- This needs to be instantiated here to be available in the template matches -->
<j:useBean var="mavenTool" class="org.apache.maven.MavenTool"/>
<j:useBean var="htmlescape" class="org.apache.velocity.anakia.Escape"/>
<j:useBean var="fileutil" class="org.apache.velocity.texen.util.FileUtil"/>
<j:useBean var="pathtool" class="org.apache.maven.DVSLPathTool"/>
<jsl:template match="pmd">
<document>
<properties>
<title>PMD Results</title>
</properties>
<body>
<section name="PMD Results">
<p>
The following document contains the results of
<a
href="http://pmd.sourceforge.net/">PMD</a>.
</p>
</section>
<section name="Summary">
<j:set var="fileCount"><x:expr select="count(file)"/></j:set>
<j:set var="errorCount"><x:expr select="count(file/violation)"/></j:set>
<table>
<tr>
<th>Files</th>
<th>Errors</th>
</tr>
<tr>
<td><doc:formatAsNumber string="${fileCount}" pattern="0"/></td>
<td><doc:formatAsNumber string="${errorCount}" pattern="0"/></td>
</tr>
</table>
</section>
<section name="Files">
<table>
<tr>
<th>Files</th>
<th>Violations</th>
</tr>
<j:set var="fullSrcDir" value="${pom.build.sourceDirectory}"/>
<j:set var="srcDir" value="${fileutil.file(fullSrcDir).getAbsolutePath()}"/>
<j:set var="srcDirLength" value="${srcDir.length() + 1}"/>
<x:set var="files" select="file"/>
<!-- x:forEach is busted -->
<j:forEach var="file" items="${files}">
<!-- Type coercion doesn't work worth a fuck in jexl. -->
<j:set var="name" value="${file.attribute('name').getValue()}"/>
<j:set var="name" value="${name.substring(mavenTool.toInteger(srcDirLength.toString()))}"/>
<util:replace var="name" value="${name}" oldChar="\\" newChar="/"/>
<!--- +1 is for the trailing slash above -->
<j:set var="errorCount"><x:expr select="count($file/violation)"/></j:set>
<j:if test="${errorCount != 0}">
<tr>
<td>
<a href="#${name}">${name}</a>
</td>
<td><doc:formatAsNumber string="${errorCount}" pattern="0"/></td>
</tr>
</j:if>
</j:forEach>
</table>
<j:forEach var="file" items="${files}">
<x:set var="errorCount" select="count($file/violation)"/>
<j:if test="${errorCount != 0}">
<j:set var="name" value="${file.attribute('name').getValue()}"/>
<j:set var="name" value="${name.substring(mavenTool.toInteger(srcDirLength.toString()))}"/>
<util:replace var="name" value="${name}" oldChar="\\" newChar="/"/>
<subsection name="${name}">
<table>
<tr>
<th>Violation</th>
<th>Line</th>
</tr>
<x:set var="errors" select="$file/violation"/>
<j:forEach var="error" items="${errors}">
<tr>
<td>
<j:set var="errorMessage" value="${error.StringValue}"/>
${htmlescape.getText(errorMessage)}
</td>
<td>
<j:set var="line" value="${error.attribute('line').getValue()}"/>
<j:set var="lastIndex" value="${name.lastIndexOf('.java')}"/>
<j:choose>
<j:when test="${lastIndex > 0}">
<j:set var="index" value="${mavenTool.toInteger(lastIndex.toString())}"/>
<j:set var="nameWithoutJavaExtension" value="${name.substring(0, index)}"/>
<util:replace var="nameWithoutJavaExtension" value="${nameWithoutJavaExtension}" oldChar="\\" newChar="/"/>
<a href="xref/${nameWithoutJavaExtension}.html#${line}">${line}</a>
</j:when>
<j:otherwise>
${line}
</j:otherwise>
</j:choose>
</td>
</tr>
</j:forEach>
</table>
</subsection>
</j:if>
</j:forEach>
</section>
</body>
</document>
</jsl:template>
</jsl:stylesheet>

1
pmd/project.properties Normal file
View File

@ -0,0 +1 @@
maven.xdoc.date = bottom

109
pmd/project.xml Normal file
View File

@ -0,0 +1,109 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<project>
<pomVersion>3</pomVersion>
<id>maven-pmd-plugin</id>
<name>Maven PMD Plug-in</name>
<currentVersion>0.5</currentVersion>
<organization>
<name>SourceForge</name>
<url>http://www.sourceforge.net/projects/maven-plugins/</url>
<logo>http://sourceforge.net/sflogo.php?group_id=61626&amp;type=5</logo>
</organization>
<inceptionYear>2002</inceptionYear>
<package>org.apache.maven</package>
<logo>http://jakarta.apache.org/turbine/maven/images/maven.jpg</logo>
<!-- Gump integration -->
<gumpRepositoryId>jakarta</gumpRepositoryId>
<description>
This plugin provides a more or less seamless integration
with Maven and the PMD static source code analyzer
</description>
<shortDescription>Maven Plugin for PMD</shortDescription>
<url>http://maven-plugins.sourceforge.net/pmd/</url>
<issueTrackingUrl>http://nagoya.apache.org/scarab/servlet/scarab/</issueTrackingUrl>
<siteAddress>maven-plugins.sf.net</siteAddress>
<siteDirectory>/home/groups/m/ma/maven-plugins/htdocs/pmd/</siteDirectory>
<distributionDirectory>/home/groups/m/ma/maven-plugins/htdocs/pmd/distributions/</distributionDirectory>
<repository>
<connection>scm:cvs:pserver:anoncvs@cvs.maven-plugins.sourceforge.net:/cvsroot/maven-plugins/:maven-plugins/pmd</connection>
<url>http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/maven-plugins/maven-plugins/pmd/</url>
</repository>
<mailingLists>
<mailingList>
<name>Maven-Plugins User List</name>
<subscribe>maven-plugins-developer-subscribe@lists.sourceforge.net</subscribe>
<unsubscribe>maven-plugins-user-unsubscribe@lists.sourceforge.net</unsubscribe>
<archive>http://sourceforge.net/mailarchive/forum.php?forum_id=11777</archive>
</mailingList>
<mailingList>
<name>Maven-Plugins Developer List</name>
<subscribe>maven-plugins-developer-subscribe@lists.sourceforge.net</subscribe>
<unsubscribe>maven-plugins-developer-unsubscribe@lists.sourceforge.net</unsubscribe>
<archive>http://sourceforge.net/mailarchive/forum.php?forum_id=11782</archive>
</mailingList>
<mailingList>
<name>Maven-Plugins CVS Commits List</name>
<subscribe>${pom.id}-cvs-subscribe@lists.sourceforge.net</subscribe>
<unsubscribe>${pom.id}-cvs-unsubscribe@lists.sourceforge.net</unsubscribe>
<archive>http://sourceforge.net/mailarchive/forum.php?forum_id=11781</archive>
</mailingList>
</mailingLists>
<developers>
<developer>
<name>Siegfried Goeschl</name>
<id>wdsgoe</id>
<email>siegfried.goeschl@it20one.at</email>
<organization>IT20one</organization>
<roles>
<role>Software Developer</role>
</roles>
</developer>
<developer>
<name>Martin Poeschl</name>
<id>mpoeschl</id>
<email>mpoeschl@marmot.at</email>
<organization>Tucana.at</organization>
<roles>
<role>Software Developer</role>
</roles>
</developer>
</developers>
<dependencies>
<dependency>
<id>pmd</id>
<version>1.03</version>
<url>http://pmd.sourceforge.net</url>
<properties>
<classloader>root</classloader>
</properties>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>${basedir}</directory>
<includes>
<include>plugin.jelly</include>
<include>plugin.properties</include>
<include>project.properties</include>
<include>project.xml</include>
<include>pmd.jsl</include>
<include>rulesets/**</include>
</includes>
</resource>
</resources>
</build>
</project>

209
pmd/rulesets/basic.xml Normal file
View File

@ -0,0 +1,209 @@
<?xml version="1.0"?>
<ruleset name="Basic Rules">
<description>
The Basic Ruleset contains a collection of good practice rules
which everyone should follow.
</description>
<rule name="EmptyCatchBlock"
message="Avoid empty catch blocks"
class="net.sourceforge.pmd.rules.EmptyCatchBlockRule">
<description>
Empty Catch Block finds instances where an exception is caught,
but nothing is done. In most circumstances, this swallows an exception
which should either be acted on or reported.
</description>
<example>
<![CDATA[
public void doSomething() {
try {
FileInputStream fis = new FileInputStream("/tmp/bugger");
} catch (IOException ioe) {
// not good
}
}
]]>
</example>
</rule>
<rule name="EmptyIfStmt"
message="Avoid empty 'if' statements"
class="net.sourceforge.pmd.rules.EmptyIfStmtRule">
<description>
Empty If Statement finds instances where a condition is checked but nothing is done about it.
</description>
<example>
<![CDATA[
if (absValue < 1) {
// not good
}
]]>
</example>
</rule>
<rule name="EmptyWhileStmt"
message="Avoid empty 'while' statements"
class="net.sourceforge.pmd.rules.EmptyWhileStmtRule">
<description>
Empty While Statement finds all instances where a while statement
does nothing. If it is a timing loop, then you should use Thread.sleep() for it; if
it's a while loop that does a lot in the exit expression, rewrite it to make it clearer.
</description>
<example>
<![CDATA[
while (a == b) {
// not good
}
]]>
</example>
</rule>
<rule name="UnnecessaryConversionTemporaryRule"
message="Avoid unnecessary temporaries when converting primitives to Strings"
class="net.sourceforge.pmd.rules.UnnecessaryConversionTemporaryRule">
<description>
Avoid unnecessary temporaries when converting primitives to Strings
</description>
<example>
<![CDATA[
public String convert(int x) {
// this wastes an object
String foo = new Integer(x).toString();
// this is better
return Integer.toString(x);
}
]]>
</example>
</rule>
<rule name="EmptyTryBlock"
message="Avoid empty try blocks"
class="net.sourceforge.pmd.rules.EmptyTryBlockRule">
<description>
Avoid empty try blocks - what's the point?
</description>
<example>
<![CDATA[
// this is bad
public void bar() {
try {
} catch (Exception e) {
e.printStackTrace();
}
}
]]>
</example>
</rule>
<rule name="EmptyFinallyBlock"
message="Avoid empty finally blocks"
class="net.sourceforge.pmd.rules.EmptyFinallyBlockRule">
<description>
Avoid empty finally blocks - these can be deleted.
</description>
<example>
<![CDATA[
// this is bad
public void bar() {
try {
int x=2;
} finally {
}
}
]]>
</example>
</rule>
<rule name="EmptySwitchStatements"
message="Avoid empty switch statements"
class="net.sourceforge.pmd.rules.EmptySwitchStmtRule">
<description>
Avoid empty switch statements.
</description>
<example>
<![CDATA[
public class Foo {
public void bar() {
int x = 2;
switch (x) {
// once there was code here
// but it's been commented out or something
}
}
}
]]>
</example>
</rule>
<rule name="OverrideBothEqualsAndHashcodeRule"
message="Ensure you override both equals() and hashCode()"
class="net.sourceforge.pmd.rules.OverrideBothEqualsAndHashcodeRule">
<description>
Override both public boolean Object.equals(Object other), and public int Object.hashCode(), or override neither. Even if you are inheriting a hashCode() from a parent class, consider implementing hashCode and explicitly delegating to your superclass.
</description>
<example>
<![CDATA[
// this is bad
public class Bar {
public boolean equals(Object o) {
// do some comparison
}
}
// and so is this
public class Baz {
public int hashCode() {
// return some hash value
}
}
// this is OK
public class Foo {
public boolean equals(Object other) {
// do some comparison
}
public int hashCode() {
// return some hash value
}
}
]]>
</example>
</rule>
<rule name="JumbledIncrementer"
message="Avoid using an outer loop incrementer in an inner loop for update expression"
class="net.sourceforge.pmd.rules.JumbledIncrementerRule">
<description>
Avoid jumbled loop incrementers - it's usually a mistake, and it's confusing even if it's what's intended.
</description>
<example>
<![CDATA[
public class JumbledIncrementerRule1 {
public void foo() {
for (int i = 0; i < 10; i++) {
for (int k = 0; k < 20; i++) {
System.out.println("Hello");
}
}
}
}}]]>
</example>
</rule>
</ruleset>

92
pmd/rulesets/braces.xml Normal file
View File

@ -0,0 +1,92 @@
<?xml version="1.0"?>
<ruleset name="Braces Rules">
<description>
The Braces Ruleset contains a collection of braces rules.
</description>
<rule name="IfElseStmtsMustUseBracesRule"
message="Avoid using 'if...else' statements without curly braces"
class="net.sourceforge.pmd.rules.IfElseStmtsMustUseBracesRule">
<description>
Avoid using if..else statements without using curly braces
</description>
<example>
<![CDATA[
public void doSomething() {
// this is OK
if (foo) x++;
// but this is not
if (foo)
x=x+1;
else
x=x-1;
}
]]>
</example>
</rule>
<rule name="WhileLoopsMustUseBracesRule"
message="Avoid using 'while' statements without curly braces"
class="net.sourceforge.pmd.rules.WhileLoopsMustUseBracesRule">
<description>
Avoid using 'while' statements without using curly braces
</description>
<example>
<![CDATA[
public void doSomething() {
while (true)
x++;
}
]]>
</example>
</rule>
<rule name="ForLoopsMustUseBracesRule"
message="Avoid using 'for' statements without curly braces"
class="net.sourceforge.pmd.rules.ForLoopsMustUseBracesRule">
<description>
Avoid using 'for' statements without using curly braces
</description>
<example>
<![CDATA[
public void foo() {
for (int i=0; i<42;i++)
foo();
}
]]>
</example>
</rule>
<rule name="IfStmtsMustUseBraces"
message="Avoid using if statements without curly braces"
class="net.sourceforge.pmd.rules.IfStmtsMustUseBracesRule">
<description>
Avoid using if statements without using curly braces
</description>
<example>
<![CDATA[
public class Foo {
public void bar() {
int x = 0;
if (foo) x++;
}
}
]]>
</example>
</rule>
</ruleset>

124
pmd/rulesets/codesize.xml Normal file
View File

@ -0,0 +1,124 @@
<?xml version="1.0"?>
<ruleset name="Code Size Rules">
<description>
The Code Size Ruleset contains a collection of rules that find code size related problems.
</description>
<rule name="ExcessiveMethodLength"
message="Avoid really long methods."
class="net.sourceforge.pmd.rules.design.LongMethodRule">
<description>
Excessive Method Length usually means that the method is doing
too much. There is usually quite a bit of Cut and Paste there
as well. Try to reduce the method size by creating helper methods,
and removing cut and paste.
Default value is 2.5 sigma greater than the mean.
NOTE: In version 0.9 and higher, their are three parameters available:
minimum - Minimum Length before reporting.
sigma - Std Deviations away from the mean before reporting.
topscore - The Maximum Number of reports to generate.
At this time, only one can be used at a time.
</description>
<properties>
<property name="minimum" value="100"/>
</properties>
<example>
<![CDATA[
public void doSomething() {
System.out.println("I am a fish.");
System.out.println("I am a fish.");
System.out.println("I am a fish.");
System.out.println("I am a fish.");
System.out.println("I am a fish.");
// 495 copies omitted for brevity.
}
]]>
</example>
</rule>
<rule name="ExcessiveParameterList"
message="Avoid really long parameter lists."
class="net.sourceforge.pmd.rules.design.LongParameterListRule">
<description>
This checks to make sure that the Parameter Lists in the project aren't
getting too long. If there are long parameter lists, then that is
generally indicative that another object is hiding around there.
Basically, try to group the parameters together.
Default value is 2.5 sigma greater than the mean.
NOTE: In version 0.9 and higher, their are three parameters available:
minimum - Minimum Length before reporting.
sigma - Std Deviations away from the mean before reporting.
topscore - The Maximum Number of reports to generate.
At this time, only one can be used at a time.
</description>
<properties>
<property name="minimum" value="10"/>
</properties>
<example>
<![CDATA[
public void addData(
int p00, int p01, int p02, int p03, int p04, int p05,
int p05, int p06, int p07, int p08, int p09, int p10) {
}
}
]]>
</example>
</rule>
<rule name="ExcessiveClassLength"
message="Avoid really long Classes."
class="net.sourceforge.pmd.rules.design.LongClassRule">
<description>
Long Class files are indications that the class may be trying to
do too much. Try to break it down, and reduce the size to something
managable.
Default value is 2.5 sigma greater than the mean.
NOTE: In version 0.9 and higher, their are three parameters available:
minimum - Minimum Length before reporting.
sigma - Std Deviations away from the mean before reporting.
topscore - The Maximum Number of reports to generate.
At this time, only one can be used at a time.
</description>
<properties>
<property name="minimum" value="1000"/>
</properties>
<example>
<![CDATA[
public class Foo {
public void bar() {
// 500 lines of code
}
public void baz() {
// 500 more lines of code
}
}
]]>
</example>
</rule>
</ruleset>

176
pmd/rulesets/design.xml Normal file
View File

@ -0,0 +1,176 @@
<?xml version="1.0"?>
<ruleset name="Design Rules">
<description>
The Design Ruleset contains a collection of rules that find questionable designs.
</description>
<rule name="UseSingletonRule"
message="All methods are static. Consider using Singleton instead."
class="net.sourceforge.pmd.rules.design.UseSingletonRule">
<description>
If you have a class that has nothing but static methods, consider making it a Singleton
</description>
<example>
<![CDATA[
public class MaybeASingleton {
public static void foo() {
// etc
}
public static void bar() {
// etc
}
}
]]>
</example>
</rule>
<rule name="LooseCouplingRule"
message="Avoid using implementation types like ''{0}''; use the interface instead"
class="net.sourceforge.pmd.rules.design.LooseCouplingRule">
<description>
Avoid using implementation types (i.e., HashSet); use the interface (i.e, Set) instead
</description>
<example>
<![CDATA[
import java.util.*;
public class Bar {
// should be "private List list"
private ArrayList list = new ArrayList();
// should be "public Set getFoo()"
public HashSet getFoo() {
return new HashSet();
}
}
]]>
</example>
</rule>
<rule name="SimplifyBooleanReturnsRule"
message="Avoid unnecessary if..then..else statements when returning a boolean"
class="net.sourceforge.pmd.rules.SimplifyBooleanReturnsRule">
<description>
Avoid unnecessary if..then..else statements when returning a boolean
</description>
<example>
<![CDATA[
public class Foo {
private int bar =2;
public boolean isBarEqualsTo(int x) {
// this bit of code
if (bar == x) {
return true;
} else {
return false;
}
// can be replaced with a simple
// return bar == x;
}
}
]]>
</example>
</rule>
<rule name="SwitchStmtsShouldHaveDefault"
message="Switch statements should have a default label"
class="net.sourceforge.pmd.rules.SwitchStmtsShouldHaveDefaultRule">
<description>
Switch statements should have a default label.
</description>
<example>
<![CDATA[
public class Foo {
public void bar() {
int x = 2;
switch (x) {
case 2: int j = 8;
}
}
}
]]>
</example>
</rule>
<rule name="OnlyOneReturn"
message="A method should have only one exit point, and that should be the last statement in the method"
class="net.sourceforge.pmd.rules.design.OnlyOneReturnRule">
<description>
A method should have only one exit point, and that should be the last statement in the method.
</description>
<example>
<![CDATA[
public class OneReturnOnly1 {
public void foo(int x) {
if (x > 0) {
return "hey"; // oops, multiple exit points!
}
return "hi";
}
}
]]>
</example>
</rule>
<rule name="AvoidDeeplyNestedIfStmts"
message="Deeply nested if..then statements are hard to read"
class="net.sourceforge.pmd.rules.AvoidDeeplyNestedIfStmtsRule">
<description>
Deeply nested if..then statements are hard to read.
</description>
<properties>
<property name="problemDepth" value="3"/>
</properties>
<example>
<![CDATA[
public class Foo {
public void bar() {
int x=2;
int y=3;
int z=4;
if (x>y) {
if (y>z) {
if (z==x) {
// this is officially out of control now
}
}
}
}
}
]]>
</example>
</rule>
<rule name="AvoidReassigningParametersRule"
message="Avoid reassigning parameters such as ''{0}''"
class="net.sourceforge.pmd.rules.AvoidReassigningParametersRule">
<description>
Reassigning values to parameters is a questionable practice. Use a temporary local variable instead.
</description>
<example>
<![CDATA[
public class Foo {
private void foo(String bar) {
bar = "something else";
}
}
]]>
</example>
</rule>
</ruleset>

View File

@ -0,0 +1,90 @@
<?xml version="1.0"?>
<ruleset name="experimental">
<description>
This is the sandbox.
</description>
<!--<rule name="UnnecessaryCast"
message="Avoid unnecessary casts"
class="net.sourceforge.pmd.rules.UnnecessaryCastRule">
<description>
A variable is cast to itself, one of its supertypes or one of its interfaces. Usually
indicates that the programmer is not clear on the class structure they
are working with.
</description>
<example>
<![CDATA[
public Collection doSomething() {
List list = new ArrayList();
return (Collection) list; // Unnecessary Cast
}
]]>
</example>
</rule>
<rule name="PositionalIterator"
message="Avoid positional iterators"
class="net.sourceforge.pmd.rules.design.PositionalIteratorRule">
<description>
Avoid positional iterators. This doesn't work yet,
it breaks on stuff like this:
public class Foo {
private int baz = true;
public void bar(Iterator i) {
Object x = null;
while (i.hasNext()) {
if (baz) {
x = i.next();
} else {
x = new Runnable() {public void run() {Object bif = i.next();}}
}
}
}
}
See javax.security.auth.Subject.java, inner class SecureSet, method removeAll(), around line 1092 for a good example.
</description>
<example>
<![CDATA[
public class PositionalIterators {
public void foo(Iterator i) {
while(i.hasNext()) {
Object one = i.next();
// 2 calls to next() inside the loop == bad!
Object two = i.next();
}
}
}
]]>
</example>
</rule>
<rule name="StringConcatenation"
message="Consider replacing String concatenation inside loops with a StringBuffer"
class="net.sourceforge.pmd.rules.StringConcatenationRule">
<description>
Consider replacing String concatenation inside loops with a StringBuffer
</description>
<example>
<![CDATA[
public class Bar {
public String foo(Object[] someArray) {
String list = "" ;
for( int i = 0; i < someArray.length; i++ ){
list = list + "," + someArray[i];
}
return list;
}
}
]]>
</example>
</rule>
-->
</ruleset>

View File

@ -0,0 +1,23 @@
<?xml version="1.0"?>
<ruleset name="Tom's Favorites">
<description>
The Favorites ruleset contains links to rules that I like to use. Usually I
combine this ruleset with the unusedcode.xml, basic.xml, and import.xml rulesets for my projects.
This ruleset also serves as an example of how to reference one ruleset from another.
</description>
<rule ref="rulesets/braces.xml/WhileLoopsMustUseBracesRule"/>
<rule ref="rulesets/braces.xml/ForLoopsMustUseBracesRule"/>
<rule ref="rulesets/design.xml/UseSingletonRule"/>
<rule ref="rulesets/design.xml/LooseCouplingRule"/>
<rule ref="rulesets/design.xml/SimplifyBooleanReturnsRule"/>
<rule ref="rulesets/design.xml/SwitchStmtsShouldHaveDefault"/>
<rule ref="rulesets/design.xml/AvoidDeeplyNestedIfStmts"/>
<rule ref="rulesets/strings.xml/StringToString"/>
<rule ref="rulesets/strings.xml/StringInstantiation"/>
</ruleset>

75
pmd/rulesets/imports.xml Normal file
View File

@ -0,0 +1,75 @@
<?xml version="1.0"?>
<ruleset name="Import Rules">
<description>
These rules deal with different problems that can occur with a class' import statements.
</description>
<rule name="DuplicateImports"
message="Avoid duplicate imports such as ''{0}''"
class="net.sourceforge.pmd.rules.DuplicateImportsRule">
<description>
Avoid duplicate import statements.
</description>
<example>
<![CDATA[
// this is bad
import java.io.File;
import java.io.File;
public class Foo {}
// --- in another source code file...
// this is bad
import java.io.*;
import java.io.File;
public class Foo {}
]]>
</example>
</rule>
<rule name="DontImportJavaLang"
message="Avoid importing anything from the package 'java.lang'"
class="net.sourceforge.pmd.rules.DontImportJavaLangRule">
<description>
Avoid importing anything from the package 'java.lang'. These classes are automatically imported (JLS 7.5.3).
</description>
<example>
<![CDATA[
// this is bad
import java.lang.String;
public class Foo {}
// --- in another source code file...
// this is bad
import java.lang.*;
public class Foo {}
]]>
</example>
</rule>
<rule name="UnusedImports"
message="Avoid unused imports such as ''{0}''"
class="net.sourceforge.pmd.rules.UnusedImportsRule">
<description>
Avoid unused import statements.
</description>
<example>
<![CDATA[
// this is bad
import java.io.File;
public class Foo {}
]]>
</example>
</rule>
</ruleset>

48
pmd/rulesets/junit.xml Normal file
View File

@ -0,0 +1,48 @@
<?xml version="1.0"?>
<ruleset name="JUnit Rules">
<description>
These rules deal with different problems that can occur with JUnit tests.
</description>
<rule name="JUnitSpelling"
message="You may have misspelled the JUnit framework ''{0}'' method as ''{1}''"
class="net.sourceforge.pmd.rules.JUnitSpellingRule">
<description>
Some JUnit framework methods are easy to misspell.
</description>
<example>
<![CDATA[
import junit.framework.*;
public class Foo extends TestCase {
public void setup() {} // oops, should be setUp
public void TearDown() {} // oops, should be tearDown
}
]]>
</example>
</rule>
<rule name="JUnitStaticSuite"
message="You have a suite() method that is not both public and static, so JUnit won't call it to get your TestSuite. Is that what you wanted to do?"
class="net.sourceforge.pmd.rules.JUnitStaticSuiteRule">
<description>
The suite() method in a JUnit test needs to be both public and static.
</description>
<example>
<![CDATA[
import junit.framework.*;
public class Foo extends TestCase {
public void suite() {} // oops, should be static
private static void suite() {} // oops, should be public
}
]]>
</example>
</rule>
</ruleset>

85
pmd/rulesets/naming.xml Normal file
View File

@ -0,0 +1,85 @@
<?xml version="1.0"?>
<ruleset name="Naming Rules">
<description>
The Naming Ruleset contains a collection of rules about names - too long, too short, and so forth.
</description>
<rule name="ShortVariable"
message="Avoid variables with short names such as ''{0}''"
class="net.sourceforge.pmd.rules.ShortVariableRule">
<description>
Detects when a field, local or parameter has a short name.
</description>
<properties>
<property name="minimumLength" value="3"/>
</properties>
<example>
<![CDATA[
public class Something {
private int q = 15; // VIOLATION - Field
public static void main( String as[] ) { // VIOLATION - Formal
int r = 20 + q; // VIOLATION - Local
for (int i = 0; i < 10; i++) { // Not a Violation (inside FOR)
r += q;
}
}
}
]]>
</example>
</rule>
<rule name="LongVariable"
message="Avoid excessively long variable names such as ''{0}''"
class="net.sourceforge.pmd.rules.LongVariableRule">
<description>
Detects when a field, formal or local variable is declared with a big name.
</description>
<properties>
<property name="minimumLength" value="12"/>
</properties>
<example>
<![CDATA[
public class Something {
int reallyLongIntName = -3; // VIOLATION - Field
public static void main( String argumentsList[] ) { // VIOLATION - Formal
int otherReallyLongName = -5; // VIOLATION - Local
for (int interestingIntIndex = 0; // VIOLATION - For
interestingIntIndex < 10;
interestingIntIndex ++ ) {
}
}
]]>
</example>
</rule>
<rule name="ShortMethodNameRule"
message="Avoid using short method names such as ''{0}''"
class="net.sourceforge.pmd.rules.ShortMethodNameRule">
<description>
Detects when very short method names are used.
</description>
<properties>
<property name="minimumLength" value="3"/>
</properties>
<example>
<![CDATA[
public class ShortMethod {
public void a( int i ) { // Violation
}
}
]]>
</example>
</rule>
</ruleset>

12
pmd/rulesets/newrules.xml Normal file
View File

@ -0,0 +1,12 @@
<?xml version="1.0"?>
<ruleset name="newrules">
<description>
These are new rules for the next release
</description>
</ruleset>

View File

@ -0,0 +1 @@
rulesets.filenames=rulesets/strings.xml,rulesets/junit.xml,rulesets/braces.xml,rulesets/basic.xml,rulesets/unusedcode.xml,rulesets/design.xml,rulesets/naming.xml,rulesets/imports.xml,rulesets/codesize.xml

71
pmd/rulesets/strings.xml Normal file
View File

@ -0,0 +1,71 @@
<?xml version="1.0"?>
<ruleset name="Strings Rules">
<description>
These rules deal with different problems that can occur with String manipulation.
</description>
<rule name="StringInstantiation"
message="Avoid instantiating String objects; this is usually unnecessary."
class="net.sourceforge.pmd.rules.StringInstantiationRule">
<description>
Avoid instantiating String objects; this is usually unnecessary.
</description>
<example>
<![CDATA[
public class Foo {
private String bar = new String("bar"); // just do a String bar = "bar";
}
]]>
</example>
</rule>
<rule name="AvoidDuplicateLiterals"
message="The same String literal appears {0} times in this file; the first occurrence is on line {1}"
class="net.sourceforge.pmd.rules.AvoidDuplicateLiteralsRule">
<description>
Code containing duplicate String literals can usually be improved by declaring the String as a constant field.
</description>
<properties>
<property name="threshold" value="4"/>
</properties>
<example>
<![CDATA[
public class Foo {
private void bar() {
buz("Howdy");
buz("Howdy");
buz("Howdy");
buz("Howdy");
}
private void buz(String x) {}
}
]]>
</example>
</rule>
<rule name="StringToString"
message="Avoid calling toString() on String objects; this is unnecessary"
class="net.sourceforge.pmd.rules.StringToStringRule">
<description>
Avoid calling toString() on String objects; this is unnecessary
</description>
<example>
<![CDATA[
public class Foo {
private String baz() {
String bar = "howdy";
return bar.toString();
}
}
]]>
</example>
</rule>
</ruleset>

105
pmd/rulesets/unusedcode.xml Normal file
View File

@ -0,0 +1,105 @@
<?xml version="1.0"?>
<ruleset name="Unused Code Rules">
<description>
The Unused Code Ruleset contains a collection of rules that find unused code.
</description>
<rule name="UnusedPrivateField"
message="Avoid unused private fields such as ''{0}''"
class="net.sourceforge.pmd.rules.UnusedPrivateFieldRule">
<description>
Unused Private Field detects when a private field is declared
that is not used by the class.
</description>
<example>
<![CDATA[
public class Something {
private static int FOO = 2; // Unused
private int i = 5; // Unused
private int j = 6;
public int addOne() {
return j++;
}
}
]]>
</example>
</rule>
<rule name="UnusedLocalVariable"
message="Avoid unused local variables such as ''{0}''"
class="net.sourceforge.pmd.rules.UnusedLocalVariableRule">
<description>
Unused Local Variables detects when a variable is declared, but not
used (except for possibly initial assignment)
</description>
<example>
<![CDATA[
public int doSomething() {
int i = 5; // Unused
int j = 6;
j += 3;
return j;
}
]]>
</example>
</rule>
<rule name="UnusedPrivateMethod"
message="Avoid unused private methods such as ''{0}''"
class="net.sourceforge.pmd.rules.UnusedPrivateMethodRule">
<description>
Unused Private Method detects when a private method is declared but is unused.
</description>
<example>
<![CDATA[
public class Something {
private void foo() {} // unused
}
]]>
</example>
</rule>
<rule name="UnusedFormalParameter"
message="Avoid unused formal parameters such as ''{0}''"
class="net.sourceforge.pmd.rules.UnusedFormalParameterRule">
<description>
Avoid passing parameters to methods and then not using those parameters.
</description>
<example>
<![CDATA[
public class Foo {
private void bar(String howdy) {
// howdy is not used
}
]]>
</example>
</rule>
<rule name="UnnecessaryConstructorRule"
message="Avoid unnecessary constructors - the compiler will generate these for you"
class="net.sourceforge.pmd.rules.UnnecessaryConstructorRule">
<description>
Unnecessary constructor detects when a constructor is not necessary; i.e., when there's only one constructor,
it's public, has an empty body, and takes no arguments.
</description>
<example>
<![CDATA[
public class Foo {
public Foo() {}
}
]]>
</example>
</rule>
</ruleset>

52
pmd/xdocs/changes.xml Normal file
View File

@ -0,0 +1,52 @@
<?xml version="1.0"?>
<document>
<properties>
<title>Changes</title>
<author email="siegfried.goeschl@it20one.at">Siegfried Goeschl</author>
<author email="vmassol@apache.org">Vincent Massol</author>
</properties>
<releases>
<release version="0.6" date="in CVS">
<action dev="vmassol" type="update">
Moved the PMD plugin from the
<link href="http://sourceforge.net/projects/maven-plugins">Maven-Plugins SF project</link>
to the Maven project.
</action>
</release>
<release version="0.5" date="14-03-2003">
<action dev="mpoeschl" type="update">
Updated to used PMD 1.03
</action>
<action dev="mpoeschl" type="update">
Updated to work for maven-1,0-beta8
</action>
</release>
<release version="0.4" date="16-Jan-2003">
<action dev="wdsgoe" type="fix">
PMD can be enabled/disabled by setting maven.pmd.enable
</action>
<action dev="wdsgoe" type="fix">
Upgraded to PMD 1.01 and removed the DVSLPath Tool
since it is not longer needed
</action>
<action dev="wdsgoe" type="fix">
Added files for integration with the existing maven-plugin buikd
</action>
<action dev="wdsgoe" type="fix">
Tom Copeland fixed some stuff in the Jelly script
</action>
</release>
<release version="0.3" date="in CVS">
<action dev="wdsgoe" type="update">
Updated to used PMD 1.0
</action>
</release>
</releases>
</document>

68
pmd/xdocs/how-to.xml Normal file
View File

@ -0,0 +1,68 @@
<?xml version="1.0"?>
<document>
<properties>
<title>Maven PMD Plug-in How To</title>
<author email="siegfried.goeschl@it20one.at">Siegfried Goeschl</author>
</properties>
<body>
<section name="Maven PMD Plugin How To">
<subsection name="How to enable PMD for all of my projects?">
<p>
Usually I provide a custom plugin, e.g. "maven-it20one-plugin-1.0"
which sets the variable "maven.pmd.enable" to "true". Since all
plugins are parsed it is guaranteed that PMD will be executed
</p>
<p>
The simple way is to define the property in
$MAVEN_HOME/bin/driver.properties
</p>
</subsection>
<subsection name="How to disable PMD for one projects?">
<p>
Assume that you have generated a DB layer having a few
hundreds Java source files. Apart from being curious you
don't want to have a PMD report for generated source files.
Simple put "maven.pmd.enable=false" into your project properties
</p>
</subsection>
<subsection name="How to get rid of zillions of rule violations?">
<p>
You could fix the rule violations. On the other hand I find
some of the rules quite annoying. Rules can be removed by editing
the rulesets.properties.
</p>
<p>
In other case you change the trigger of the rules directly in the
ruleset files to fine tune the reports.
</p>
</subsection>
<subsection name="How to upgrade to a newer PMD jar?">
<p>
"Those bloody contributors do not keep up with the
release - there is the new JAR out there for two
days and no update of the plugin ... having pizza,
coke, a joint and doing nothing" - Fine, as
long as we do not inhale ... ;-)
</p>
<p>
The JAR picked up the plugin is defined in
$MAVEN_HOME/plugins/pmd/project.xml and can be
changed.
</p>
<p>
Leave it, try it but don't whine will I have to carve
out a living with some paid work ... :-[]
</p>
</subsection>
</section>
</body>
</document>

BIN
pmd/xdocs/images/sample.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

107
pmd/xdocs/index.xml Normal file
View File

@ -0,0 +1,107 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<document>
<properties>
<title>Maven PMD Plug-in</title>
<author email="siegfried.goeschl@it20one.at">Siegfried Goeschl</author>
</properties>
<body>
<section name="Maven PMD Plug-in">
<p>
This plugin generates a report of the PMD static source code
analyzer.
</p>
<subsection name="Installation">
<p>
Copy the downloaded plugin into the Maven plugin directory.
Any older version of the plugin should to be deleted to make
sure that the newest plugin is called
</p>
<p>
Download the PMD binary distribution and put the PMD
jar into the repository. This has to be done manually
unless PMD is hosted on the Maven remote repository.
</p>
<p>
Run "maven -g" and look out for documented PMD goals.
If you see some then the unpacking succeeded.
</p>
<p>
The PMD plugin can be started through "maven pmd"
or integrated by using the following code snippet in
maven.xml:
</p>
<source>
<![CDATA[
<?xml version="1.0"?>
<preGoal name="site:generate">
<attainGoal name="pmd"/>
</preGoal>
]]>
</source>
<p>
The generated report has to be added manually to the
website which is usually done with navigation.xml.
</p>
<source>
<![CDATA[
<?xml version="1.0"?>
<menu name="Custom Reports">
<item name="PMD Report" href="/pmd-report.html"/>
<!-- Add more custom reports here -->
</menu>
]]>
</source>
<p>
Another way to integrate the PMD plugin is to add it to the &lt;reports&gt;
section in your project.xml:
</p>
<source>
<![CDATA[
<reports>
<report>maven-jdepend-plugin</report>
<report>maven-checkstyle-plugin</report>
<report>maven-pmd-plugin</report>
<report>maven-changelog-plugin</report>
<report>maven-file-activity-plugin</report>
<report>maven-developer-activity-plugin</report>
<report>maven-javadoc-plugin</report>
<report>maven-jxr-plugin</report>
<report>maven-junit-report-plugin</report>
<report>maven-tasklist-plugin</report>
</reports>
]]>
</source>
</subsection>
<subsection name="Thanks to ...">
<p>
And last but not least - thanks to
<a href="http://www.together.at">Together Teamlösungen</a> for
their support of Open Source Software and their contributions
such as <a href="http://www.enhydra.org">Enhydra Application
Server 5.0 ("Aonyx")</a> and a couple of Maven plugins.
</p>
</subsection>
</section>
</body>
</document>

18
pmd/xdocs/navigation.xml Normal file
View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<project name="Maven PMD Plugin">
<title>Maven PMD Plugin</title>
<body>
<menu name="Home">
<item name="Front Page" href="/index.html"/>
<item name="Properties" href="/properties.html"/>
<item name="Sample" href="/images/sample.gif"/>
<item name="How To's" href="/how-to.html"/>
</menu>
</body>
</project>

36
pmd/xdocs/properties.xml Normal file
View File

@ -0,0 +1,36 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<document>
<properties>
<title>PMD Plug-in Properties</title>
<author email="siegfried.goeschl@it20one.at">Siegfried Goeschl</author>
</properties>
<body>
<section name="PMD Plug-in Properties">
<table>
<tr>
<th>Property</th>
<th>Optional?</th>
<th>Description</th>
</tr>
<tr>
<td>maven.pmd.enable</td>
<td>No</td>
<td>
Enable/disable the PMD plugin. Has to be set to "true"
to enable the plugin
</td>
</tr>
<tr>
<td>maven.pmd.rulesetfiles</td>
<td>Yes</td>
<td>
Defines the rule to be used for running PMD. Is
already defined in the plugin
</td>
</tr>
</table>
</section>
</body>
</document>

22
pmd/xdocs/tasks.xml Normal file
View File

@ -0,0 +1,22 @@
<?xml version="1.0"?>
<document>
<properties>
<title>Tasks</title>
<author email="siegfried.goeschl@it20one.at">Siegfried Goeschl</author>
</properties>
<body>
<section name="Tasks">
<subsection name="Release 0.4">
<ul>
<li>
Add a description of the violation if the PMD report
contains more metadata
</li>
</ul>
</subsection>
</section>
</body>
</document>