git-svn-id: https://svn.apache.org/repos/asf/maven/maven-1/plugins/trunk@113258 13f79535-47bb-0310-9956-ffa450edef68
304 lines
7.9 KiB
XML
304 lines
7.9 KiB
XML
<?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>
|
|
<priority>3</priority>
|
|
|
|
<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>
|
|
<priority>3</priority>
|
|
|
|
<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>
|
|
<priority>3</priority>
|
|
<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.XPathRule">
|
|
<description>
|
|
Switch statements should have a default label.
|
|
</description>
|
|
<properties>
|
|
<property name="xpath">
|
|
<value>
|
|
<![CDATA[
|
|
//SwitchStatement[not(SwitchLabel[count(*) = 0])]
|
|
]]>
|
|
</value>
|
|
</property>
|
|
</properties>
|
|
<priority>3</priority>
|
|
|
|
<example>
|
|
<![CDATA[
|
|
public class Foo {
|
|
public void bar() {
|
|
int x = 2;
|
|
switch (x) {
|
|
case 2: int j = 8;
|
|
}
|
|
}
|
|
}
|
|
]]>
|
|
</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>
|
|
<priority>3</priority>
|
|
<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>
|
|
<priority>2</priority>
|
|
<example>
|
|
<![CDATA[
|
|
public class Foo {
|
|
private void foo(String bar) {
|
|
bar = "something else";
|
|
}
|
|
}
|
|
]]>
|
|
</example>
|
|
</rule>
|
|
|
|
<rule name="SwitchDensity"
|
|
message="A high ratio of statements to labels in a switch statement. Consider refactoring."
|
|
class="net.sourceforge.pmd.rules.design.SwitchDensityRule">
|
|
<description>
|
|
A high ratio of statements to labels in a switch statement implies that the switch
|
|
statement is doing too much work. Consider moving the statements either into new
|
|
methods, or creating subclasses based on the switch variable.
|
|
</description>
|
|
<priority>3</priority>
|
|
<properties>
|
|
<property name="minimum" value="10"/>
|
|
</properties>
|
|
<example>
|
|
<![CDATA[
|
|
public class Foo {
|
|
private int x;
|
|
public void bar() {
|
|
switch (x) {
|
|
case 1: {
|
|
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.");
|
|
break;
|
|
}
|
|
|
|
case 2: {
|
|
System.out.println("I am a cow.");
|
|
System.out.println("I am a cow.");
|
|
System.out.println("I am a cow.");
|
|
System.out.println("I am a cow.");
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
]]>
|
|
</example>
|
|
</rule>
|
|
|
|
<rule name="ConstructorCallsOverridableMethodRule"
|
|
message="Avoid calls to overridable methods during construction"
|
|
class="net.sourceforge.pmd.rules.ConstructorCallsOverridableMethodRule">
|
|
<description>
|
|
Calling overridable methods during construction poses a risk of invoking methods on an
|
|
incompletely constructed object. This situation can be difficult to discern.
|
|
It may leave the sub-class unable to construct its superclass or forced to
|
|
replicate the construction process completely within itself, losing the ability to call
|
|
super(). If the default constructor contains a call to an overridable method,
|
|
the subclass may be completely uninstantiable.
|
|
</description>
|
|
<priority>1</priority>
|
|
<example>
|
|
<![CDATA[
|
|
public class SeniorClass {
|
|
public SeniorClass(){
|
|
toString(); //may throw NullPointerException if overridden
|
|
}
|
|
public String toString(){
|
|
return "IAmSeniorClass";
|
|
}
|
|
}
|
|
public class JuniorClass extends SeniorClass {
|
|
private String name;
|
|
public JuniorClass(){
|
|
super(); //Automatic call leads to NullPointerException
|
|
name = "JuniorClass";
|
|
}
|
|
public String toString(){
|
|
return name;
|
|
}
|
|
}
|
|
]]>
|
|
</example>
|
|
</rule>
|
|
|
|
<rule name="AccessorClassGenerationRule"
|
|
message="Avoid instantiation through private constructors from outside of the constructor's class."
|
|
class="net.sourceforge.pmd.rules.AccessorClassGenerationRule">
|
|
<description>
|
|
Instantiation by way of private constructors from outside of the constructor's class often causes the generation of an accessor.
|
|
A factory method, or non-privitization of the constructor can eliminate this situation.
|
|
The generated class file is actually an interface. It gives the accessing class the ability to invoke a new hidden package
|
|
scope constructor that takes the interface as a supplementary parameter. This turns a private constructor effectively into
|
|
one with package scope, though not visible to the naked eye.
|
|
</description>
|
|
<priority>3</priority>
|
|
<example>
|
|
<![CDATA[
|
|
public class OuterClass {
|
|
void method(){
|
|
InnerClass ic = new InnerClass();//Causes generation of accessor
|
|
}
|
|
public class InnerClass {
|
|
private InnerClass(){
|
|
}
|
|
}
|
|
}
|
|
|
|
public class OuterClass {
|
|
void method(){
|
|
InnerClass ic = new InnerClass();//OK, due to public constructor
|
|
}
|
|
public class InnerClass {
|
|
public InnerClass(){
|
|
}
|
|
}
|
|
}
|
|
|
|
public class OuterClass {
|
|
void method(){
|
|
InnerClass ic = InnerClass.getInnerClass();//OK
|
|
}
|
|
public static class InnerClass {
|
|
private InnerClass(){
|
|
}
|
|
private static InnerClass getInnerClass(){
|
|
return new InnerClass();
|
|
}
|
|
}
|
|
}
|
|
|
|
public class OuterClass {
|
|
private OuterClass(){
|
|
}
|
|
public class InnerClass {
|
|
void method(){
|
|
OuterClass oc = new OuterClass();//Causes generation of accessor
|
|
}
|
|
}
|
|
}
|
|
]]>
|
|
</example>
|
|
</rule>
|
|
|
|
</ruleset>
|