<?xml version="1.0"?>
<!-- 
/*
 * Copyright 2001-2004 The Apache Software Foundation.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
 -->


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