<?xml version="1.0" encoding="UTF-8"?>
<test-data>
    <test-code>
        <description><![CDATA[
connection is closed, ok
     ]]></description>
        <rule-property name="types">Connection,Statement,ResultSet</rule-property>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
public class Foo {
 void bar() {
  Connection c = pool.getConnection();
  try {
  } catch (Exception e) {
  } finally {
   c.close();
  }
 }
}
     ]]></code>
    </test-code>
    <test-code>

        <description><![CDATA[
connection not closed, should have failed
     ]]></description>
        <rule-property name="types">Connection,Statement,ResultSet</rule-property>
        <expected-problems>1</expected-problems>
        <code><![CDATA[
import java.sql.*;
public class Foo {
 void bar() {
  Connection c = pool.getConnection();
  try {
  } catch (Exception e) {
  }
 }
}
     ]]></code>
    </test-code>
    <test-code>
        <description><![CDATA[
ResultSet not closed, should have failed
     ]]></description>
        <rule-property name="types">Connection,Statement,ResultSet</rule-property>

        <expected-problems>1</expected-problems>
        <code><![CDATA[
import java.sql.*;
public class Foo {
 void bar() {
  ResultSet c = pool.getRS();
  try {
  } catch (Exception e) {}
 }
}
     ]]></code>
    </test-code>
    <test-code>
        <description><![CDATA[
Statement not closed, should have failed
     ]]></description>
        <rule-property name="types">Connection,Statement,ResultSet</rule-property>
        <expected-problems>1</expected-problems>

        <code><![CDATA[
import java.sql.*;
public class Foo {
 void bar() {
  Statement c = pool.getStmt();
  try {
  } catch (Exception e) {}
 }
}
     ]]></code>
    </test-code>
    <code-fragment id="executeQuery"><![CDATA[
import java.sql.*;
public class Foo {
 void bar() {
  Statement c = pool.getStmt();
  Statement st = c.executeQuery("SELECT * FROM FOO");
  try {
  } finally {
     MyHelper.close(c);
     cleanup(st);
}
 }
}
     ]]></code-fragment>
    <test-code>
        <description><![CDATA[
Bad, no closeTargets properties for statements
     ]]></description>
        <rule-property name="types">Connection,Statement,ResultSet</rule-property>
        <expected-problems>2</expected-problems>
        <code-ref id="executeQuery"/>

    </test-code>
    <test-code>
        <description><![CDATA[
Ok, closeTargets properties for statements
     ]]></description>
        <rule-property name="closeTargets">MyHelper.close,cleanup</rule-property>
        <rule-property name="types">Connection,Statement,ResultSet</rule-property>
        <expected-problems>0</expected-problems>
        <code-ref id="executeQuery"/>
    </test-code>
    
    <test-code>
        <description><![CDATA[
Add type param
     ]]></description>
        <rule-property name="types">ObjectInputStream</rule-property>
        <expected-problems>1</expected-problems>
        <code><![CDATA[
import java.io.*;
public class BadClose {
private void readData() {
File aFile = new File(FileName);
FileInputStream anInput = new FileInputStream(aFile);
ObjectInputStream aStream = new ObjectInputStream(anInput);

readExternal(aStream);
}
}
     ]]></code>
    </test-code>
    <test-code>

        <description><![CDATA[
OK
     ]]></description>
        <rule-property name="closeTargets">MyHelper.close</rule-property>
        <rule-property name="types">Connection,Statement,ResultSet</rule-property>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
import java.sql.*;
public class Foo {
 void bar() {
  Statement c = pool.getStmt();
  try {
  } finally {
     MyHelper.close(c);
}
 }
}
     ]]></code>
    </test-code>
    <test-code>
        <description><![CDATA[
New use case
     ]]></description>
        <rule-property name="closeTargets">commit,close</rule-property>
        <rule-property name="types">DAOTransaction,Connection,Statement,ResulSet</rule-property>
        <expected-problems>1</expected-problems>
        <expected-linenumbers>8</expected-linenumbers>
        <code><![CDATA[
import java.sql.*;
public class Foo {
	public void bar() throws SQLException
	{
		DAOTransaction trx = trxManager.open();
		Connection cnx = pool.newConn();
		ResultSet rs = null;
		Statement stmt = null;

		try
		{
			// ...
		}
		finally
		{
			//stmt.close(); // Error !!! you have to close the Statement
			rs.close(); // Correct
			cnx.commit(); // Correct ( cnx.close() would be equivalent)
			trx.commit(); // Correct
		}
	}
}
     ]]></code>
    </test-code>


    <test-code>
        <description><![CDATA[
[1964798] 3 bugs in CloseResourceRule : Case failing with complete name
     ]]></description>
        <rule-property name="closeTargets">MyHelper.MyClose</rule-property>
        <rule-property name="types">Connection,Statement,ResultSet</rule-property>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
import java.sql.*;
public class Foo {
 void bar() {
  Statement c = pool.getStmt();
  try {
  } finally {
     MyHelper.MyClose(c);
}
 }
}
     ]]></code>
    </test-code>
    
 
    <test-code>
        <description><![CDATA[
[1964798] 3 bugs in CloseResourceRule : null object is passed to close conection method (1)
     ]]></description>
        <rule-property	name="closeTargets">this.closeConnection</rule-property>
        <rule-property	name="types">Connection,Statement,ResultSet</rule-property>
        <expected-problems>1</expected-problems>
        <code><![CDATA[
import java.sql.*;
public class Foo {
 void bar() {
  Connection c;
  try {
    c = pool.getConnection();
  } finally {
     this.closeConnection(null);
  }
 }
}
     ]]></code>
    </test-code>  
   <test-code>
        <description><![CDATA[
[1964798] 3 bugs in CloseResourceRule : null object is passed to close conection method (2)
     ]]></description>
        <rule-property	name="closeTargets">this.closeConnection</rule-property>
        <rule-property	name="types">Connection,Statement,ResultSet</rule-property>
        <expected-problems>1</expected-problems>
        <code><![CDATA[
import java.sql.*;
public class Foo {
 void bar() {
  Connection c = pool.getConnection();
  try {
    //...
  } finally {
     this.closeConnection(null);
  }
 }
}
     ]]></code>
    </test-code>        
	<test-code>
        <description><![CDATA[
[1964798] 3 bugs in CloseResourceRule : If connection is returned, we should not log a violation.
     ]]></description>
        <rule-property name="types">Connection,Statement,ResultSet</rule-property>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
public class Foo {
	public Connection getConnection() {
		Connection c = pool.getConnection();
		return c;
	}
}
     ]]></code>
    </test-code>
        <test-code reinitializeRule="true">
        <description><![CDATA[
invoke an external method that close the resource
bug 2920057
     ]]></description>
        <rule-property name="closeTargets">closeStatement,closeStatement,closeResultSet,closeConnexion
        </rule-property>
        <rule-property name="types">PreparedStatement,Statement,ResultSet,Connection</rule-property>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
import java.sql.*;

public class StructureFactory {

    public void rechercherListe() {

        Connection _connexion = null;
        ResultSet _rs = null;
        PreparedStatement _st = null;
        try
        {
           //
        }


        finally
        {
            getProviderInstance().closeConnexion(_connexion);
            getProviderInstance().closeResultSet(_rs);
            getProviderInstance().closeStatement(_st);
            
        }
    }
}
     ]]></code>
    </test-code>
    <test-code reinitializeRule="true">
        <description><![CDATA[
invoke an external method that closes the resource, but one is not the right method and an another is not the right variable
see bug 2920057
     ]]></description>
        <rule-property name="closeTargets">closeStatement,closeStatement,closeResultSet,closeConnexion
        </rule-property>
        <rule-property name="types">PreparedStatement,Statement,ResultSet,Connection</rule-property>
        <expected-problems>2</expected-problems>
        <code><![CDATA[
import java.sql.*;

public class StructureFactory {

    public void searchList() {

        Connection _connexion = pool.getConn();
        ResultSet _rs = createResultSet(_connexion);
        PreparedStatement _st = createPrepStmt(_connexion);
        Structure _structure = null;
        try
        {
           //
        }


        finally
        {
            getProviderInstance().closeConnexion(_connexion);
            getProviderInstance().closeYourEyes(_rs); //not the right method
            getProviderInstance().closeStatement(_badOne); // not the right variable
            
        }
    }
}
     ]]></code>
    </test-code>
    <test-code> reinitializeRule="true"
        <description>#1011 CloseResource Rule ignores Constructors</description>
        <expected-problems>1</expected-problems>
        <code><![CDATA[
public class Test {
    public Test() {
        Connection c = pool.getConnection();
    }
}
        ]]></code>
    </test-code>
    <test-code reinitializeRule="true">
        <description>#1011 CloseResource Rule ignores Constructors - closed in finally</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
public class Test {
    public Test() {
        Connection c;
        try {
            c = pool.getConnection();
        } finally {
            c.close();
        }
    }
}
        ]]></code>
    </test-code>
    <test-code reinitializeRule="true">
        <description>#1011 CloseResource Rule ignores Constructors - not a problem - instance variable</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
public class Test {
    Connection c;
    public Test() {
        c = pool.getConnection();
    }
}
        ]]></code>
    </test-code>
    <test-code reinitializeRule="true">
        <description>#1029 No instance level check in the close resource rule</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
public class Test {
    Connection c;
    public void doIt() {
        c = pool.getConnection();
    }
}
        ]]></code>
    </test-code>
    <test-code>
        <description>#947 CloseResource rule fails if field is marked with annotation</description>
        <expected-problems>2</expected-problems>
        <code><![CDATA[
public class CloseResourceRuleBug {
  public void foo() {
    try {
      Connection c = DriverManager.getConnection("fake");
      Statement s = c.createStatement();
      @SuppressWarnings("PMD.CloseResource") ResultSet rs = s.executeQuery("fake");
      while (rs.next()) {
      }
      rs.close();
    } catch (SQLException e) {
    }
  }
}
]]></code>
    </test-code>

    <test-code>
        <description>#992 Class java.beans.Statement triggered in CloseResource rule</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
import java.beans.Statement;

public class Test {
    public void foo() {
        Statement stmt = new Statement(vo, "set" + prop, new Object[] { vector });

        try {
            stmt.execute();
        } catch (Exception e) {
            throw new RuntimeException("Could not set property prop: " + prop + "of type:" + pd.getPropertyType(), e);
        }
    }
}
        ]]></code>
    </test-code>
    
    <test-code>
        <description><![CDATA[Custom close method, should be ok]]></description>
        <rule-property name="closeTargets">cleanup</rule-property>
        <rule-property name="types">MyClass</rule-property>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
public class Foo {
   void bar() {
       MyClass myClass = null;
       try {
           myClass = new MyClass();
       } catch (Exception e) {
       } finally {
            myClass.cleanup(); // should be ok, it's closed with cleanup
       }
    }
 }
  ]]></code>
    </test-code>
    <test-code>
        <description>bug #1131 CloseResource should complain if code betwen declaration of resource and try: Code betwen declaration and try, should fail</description>
        <rule-property name="types">Connection</rule-property>
        <expected-problems>1</expected-problems>
        <code><![CDATA[
public class Foo {
    void bar() {
        String test = "";
        Connection c = pool.getConnection();
        if (test != null) {
            throw new RuntimeException("haha"); // <- RuntimeException, Connection  c is not closed
        }
        try {
        } catch (Exception e) {
        } finally {
           c.close();
        }
    }
}
        ]]></code>
    </test-code>
    <test-code>
        <description>bug #1131 CloseResource should complain if code betwen declaration of resource and try: Creation inside try, ok</description>
        <rule-property name="types">Connection</rule-property>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
public class Foo {
 void bar() {
  String test = "";
  Connection c = null;
  if (test != null) {
     throw new RuntimeException("haha");
  }
  try {
      // Creation inside try, ok
       c = pool.getConnection();
  } catch (Exception e) {
  } finally {
      if (c!= null) {
        c.close();
      }
  }
 }
}
        ]]></code>
    </test-code>
    <test-code>
        <description>bug #1131 CloseResource should complain if code betwen declaration of resource and try: No sentences between creation and try, ok</description>
        <rule-property name="types">Connection</rule-property>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
public class Foo {
 void bar() {
  String test = "";
  if (test != null) {
     throw new RuntimeException("haha");
  } 
  Connection c = pool.getConnection();
  // No sentences between creation and try, ok
  try {
  } catch (Exception e) {
  } finally {
      if (c!= null) {
        c.close();
      }
  }
 }
}
        ]]></code>
    </test-code>
    <test-code>
        <description>#1259 CloseResource rule ignores conditionnals within finally blocks</description>
        <expected-problems>1</expected-problems>
        <code><![CDATA[
public class Bar {
    public void foo() {
        Connection c = pool.getConnection();
        try {
            // do stuff
        } catch (SQLException ex) {
            // handle exception
        } finally {
            if(false) {
                c.close();
            }
        }
    }
}
        ]]></code>
    </test-code>
    <test-code>
        <description>#1375 CloseResource not detected properly - ok</description>
        <expected-problems>1</expected-problems>
        <code><![CDATA[
public class Foo {
 void bar() {
  ResultSet rs;
  Statement stmt = getConnection().createStatement();
  try {
  rs = stmt.getResultSet();
  rs.getString(0);
  rs.close();
  } catch (Exception e) {
    } finally {
   stmt.close();
  } 
 }
}
        ]]></code>
    </test-code>
    <test-code>
        <description>#1375 CloseResource not detected properly - false negative</description>
        <expected-problems>1</expected-problems>
        <code><![CDATA[
public class Foo {
 void bar() {
  ResultSet rs = null;
  Statement stmt = getConnection().createStatement();
  try {
  rs = stmt.getResultSet();
  rs.getString(0);
  rs.close();
  } catch (Exception e) {
    } finally {
   stmt.close();
  } 
 }
}
        ]]></code>
    </test-code>
    <test-code>
        <description>#1372 False Negative for CloseResource rule.</description>
        <expected-problems>1</expected-problems>
        <expected-linenumbers>8</expected-linenumbers>
        <rule-property name="types">Connection,Statement,ResultSet,PreparedStatement</rule-property>
        <rule-property name="closeTargets">closeLocalResources,closeResultSet</rule-property>
        <code><![CDATA[
public class CloseResourceTest {
    public Object selectOne(final int val, final int val2) {
        getCurrentSession().doWork(new Work() {

        @Override
        public void execute(Connection connection) throws SQLException {
            PreparedStatement stmt = null;
            ResultSet rs = null;
            try {
                stmt = createDefaultPreparedStatement(connection, CONSTANTS.QUERY_STRING);
                stmt.setInt(1, vaL);
                stmt.setInt(2, val2);
                rs = stmt.executeQuery();
                // do result set processing
            } catch (SQLException se) {
                // error
            } finally {
                closeLocalResources(stmt);
                //closeResultSet(rs); // --- ERROR
            }
        }
        });
    }
}
        ]]></code>
    </test-code>
</test-data>
