<?xml version="1.0"?>

<ruleset name="Finalizer"
    xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 http://pmd.sourceforge.net/ruleset_2_0_0.xsd">

  <description>
These rules deal with different problems that can occur with finalizers.
  </description>

    <rule name="EmptyFinalizer"
   		language="java"
    		 since="1.5"
          message="Avoid empty finalize methods"
          class="net.sourceforge.pmd.lang.rule.XPathRule"
          externalInfoUrl="${pmd.website.baseurl}/rules/java/finalizers.html#EmptyFinalizer">
       <description>
Empty finalize methods serve no purpose and should be removed.
       </description>
       <priority>3</priority>
        <properties>
            <property name="xpath">
                <value>
<![CDATA[
//MethodDeclaration[MethodDeclarator[@Image='finalize'][not(FormalParameters/*)]]
  /Block[count(*)=0]
]]>
                </value>
            </property>
        </properties>
       <example>
<![CDATA[
public class Foo {
   protected void finalize() {}
}
]]>
       </example>
     </rule>

    <rule name="FinalizeOnlyCallsSuperFinalize"
   		language="java"
    		 since="1.5"
          message="Finalize should do something besides just calling super.finalize()"
          class="net.sourceforge.pmd.lang.rule.XPathRule"
          externalInfoUrl="${pmd.website.baseurl}/rules/java/finalizers.html#FinalizeOnlyCallsSuperFinalize">
       <description>
If the finalize() is implemented, it should do something besides just calling super.finalize().
       </description>
       <priority>3</priority>
        <properties>
            <property name="xpath">
                <value>
<![CDATA[
//MethodDeclaration[MethodDeclarator[@Image="finalize"][not(FormalParameters/*)]]
   /Block[count(BlockStatement)=1]
     /BlockStatement[
       Statement/StatementExpression/PrimaryExpression
       [./PrimaryPrefix[@SuperModifier='true']]
       [./PrimarySuffix[@Image='finalize']]
     ]
]]>
                </value>
            </property>
        </properties>
       <example>
           <![CDATA[
protected void finalize() {
	super.finalize();
}
           ]]>
       </example>
     </rule>

<rule name="FinalizeOverloaded"
   		language="java"
		since="1.5"
      message="Finalize methods should not be overloaded"
      class="net.sourceforge.pmd.lang.rule.XPathRule"
          externalInfoUrl="${pmd.website.baseurl}/rules/java/finalizers.html#FinalizeOverloaded">
   <description>
Methods named finalize() should not have parameters.  It is confusing and most likely an attempt to
overload Object.finalize(). It will not be called by the VM.
   </description>
   <priority>3</priority>
    <properties>
        <property name="xpath">
            <value>
<![CDATA[
//MethodDeclaration
 /MethodDeclarator[@Image='finalize'][FormalParameters[count(*)>0]]
]]>
            </value>
        </property>
    </properties>
   <example>
<![CDATA[
public class Foo {
   // this is confusing and probably a bug
   protected void finalize(int a) {
   }
}
]]>
   </example>
 </rule>

    <rule name="FinalizeDoesNotCallSuperFinalize"
   		language="java"
    		 since="1.5"
          message="Last statement in finalize method should be a call to super.finalize()"
          class="net.sourceforge.pmd.lang.rule.XPathRule"
          externalInfoUrl="${pmd.website.baseurl}/rules/java/finalizers.html#FinalizeDoesNotCallSuperFinalize">
       <description>
If the finalize() is implemented, its last action should be to call super.finalize.
       </description>
       <priority>3</priority>
        <properties>
            <property name="xpath">
                <value>
<!-- in english: a method declaration of finalize(), with no arguments, containing
a block whose last statement is NOT a call to super.finalize -->
<![CDATA[
//MethodDeclaration[MethodDeclarator[@Image='finalize'][not(FormalParameters/*)]]
   /Block
      /BlockStatement[last()]
      [not(Statement/StatementExpression/PrimaryExpression
            [./PrimaryPrefix[@SuperModifier='true']]
            [./PrimarySuffix[@Image='finalize']]
          )
      ]
      [not(Statement/TryStatement/FinallyStatement
       /Block/BlockStatement/Statement/StatementExpression/PrimaryExpression
            [./PrimaryPrefix[@SuperModifier='true']]
            [./PrimarySuffix[@Image='finalize']]
          )
      ]
]]>
                </value>
            </property>
        </properties>
       <example>
<![CDATA[
protected void finalize() {
	something();
	// neglected to call super.finalize()
}
]]>
       </example>
     </rule>

    <rule name="FinalizeShouldBeProtected"
   		language="java"
    		 since="1.1"
          message="If you override finalize(), make it protected"
          class="net.sourceforge.pmd.lang.rule.XPathRule"
          externalInfoUrl="${pmd.website.baseurl}/rules/java/finalizers.html#FinalizeShouldBeProtected">
      <description>
When overriding the finalize(), the new method should be set as protected.  If made public, 
other classes may invoke it at inappropriate times.
      </description>
      <priority>3</priority>
        <properties>
            <property name="xpath">
                <value>
                    <![CDATA[
//MethodDeclaration[@Protected="false"]
  /MethodDeclarator[@Image="finalize"]
  [not(FormalParameters/*)]
                    ]]>
                </value>
            </property>
        </properties>
      <example>
  <![CDATA[
public void finalize() {
	// do something
}
  ]]>
      </example>
    </rule>

    <rule name="AvoidCallingFinalize"
    		 since="3.0"
          message="Avoid calling finalize() explicitly"
          class="net.sourceforge.pmd.lang.java.rule.finalizers.AvoidCallingFinalizeRule"
          externalInfoUrl="${pmd.website.baseurl}/rules/java/finalizers.html#AvoidCallingFinalize">
      <description>
The method Object.finalize() is called by the garbage collector on an object when garbage collection determines
that there are no more references to the object. It should not be invoked by application logic.
      </description>
        <priority>3</priority>
      <example>
<![CDATA[
void foo() {
	Bar b = new Bar();
	b.finalize();
}
]]>
      </example>
    </rule>

 </ruleset>