public void stopRunning( StepMetaInterface smi, StepDataInterface sdi ) throws KettleException {
    if ( this.isStopped() || sdi.isDisposed() ) {
      return;
    }

    final DatabaseJoinData data = (DatabaseJoinData) sdi;

    dbLock.lock();
    try {
      if ( data.db != null && data.db.getConnection() != null && !data.isCanceled ) {
        data.db.cancelStatement( data.pstmt );
        setStopped( true );
        data.isCanceled = true;
      }
    } finally {
      dbLock.unlock();
    }
  }
@Test
  public void testStopRunningWhenStepIsNotStoppedNorStepDataInterfaceIsDisposedAndDatabaseConnectionIsNotValid() throws KettleException {
    doReturn( false ).when( mockDatabaseJoin ).isStopped();
    doReturn( false ).when( mockStepDataInterface ).isDisposed();
    when( mockStepDataInterface.db.getConnection() ).thenReturn( null );

    mockDatabaseJoin.stopRunning( mockStepMetaInterface, mockStepDataInterface );

    verify( mockDatabaseJoin, times( 1 ) ).isStopped();
    verify( mockStepDataInterface, times( 1 ) ).isDisposed();
    verify( mockStepDataInterface.db, times( 1 ) ).getConnection();
    verify( mockStepDataInterface.db, times( 0 ) ).cancelStatement( any( PreparedStatement.class ) );
    assertFalse( mockStepDataInterface.isCanceled );
  }