|
|
@@ -29,32 +29,33 @@ import org.aspectj.tools.ajc.CompilationResult; |
|
|
|
import org.aspectj.util.FileUtil; |
|
|
|
|
|
|
|
/** |
|
|
|
* Root class for all Test suites that are based on an AspectJ XML test suite |
|
|
|
* file. Extends AjcTestCase allowing a mix of programmatic and spec-file |
|
|
|
* driven testing. See org.aspectj.systemtest.incremental.IncrementalTests for |
|
|
|
* an example of this mixed style. |
|
|
|
* <p>The class org.aspectj.testing.MakeTestClass will generate a subclass of |
|
|
|
* this class for you, given a suite spec. file as input...</p> |
|
|
|
* Root class for all Test suites that are based on an AspectJ XML test suite file. Extends AjcTestCase allowing a mix of |
|
|
|
* programmatic and spec-file driven testing. See org.aspectj.systemtest.incremental.IncrementalTests for an example of this mixed |
|
|
|
* style. |
|
|
|
* <p> |
|
|
|
* The class org.aspectj.testing.MakeTestClass will generate a subclass of this class for you, given a suite spec. file as input... |
|
|
|
* </p> |
|
|
|
*/ |
|
|
|
public abstract class XMLBasedAjcTestCase extends AjcTestCase { |
|
|
|
|
|
|
|
|
|
|
|
private static Map testMap = new HashMap(); |
|
|
|
private static boolean suiteLoaded = false; |
|
|
|
private AjcTest currentTest = null; |
|
|
|
private Stack clearTestAfterRun = new Stack(); |
|
|
|
|
|
|
|
private Stack clearTestAfterRun = new Stack(); |
|
|
|
|
|
|
|
public XMLBasedAjcTestCase() { |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* You must define a suite() method in subclasses, and return |
|
|
|
* the result of calling this method. (Don't you hate static |
|
|
|
* methods in programming models). For example: |
|
|
|
* You must define a suite() method in subclasses, and return the result of calling this method. (Don't you hate static methods |
|
|
|
* in programming models). For example: |
|
|
|
* |
|
|
|
* <pre> |
|
|
|
* public static Test suite() { |
|
|
|
* return XMLBasedAjcTestCase.loadSuite(MyTestCaseClass.class); |
|
|
|
* } |
|
|
|
* public static Test suite() { |
|
|
|
* return XMLBasedAjcTestCase.loadSuite(MyTestCaseClass.class); |
|
|
|
* } |
|
|
|
* </pre> |
|
|
|
* |
|
|
|
* @param testCaseClass |
|
|
|
* @return |
|
|
|
*/ |
|
|
@@ -62,14 +63,19 @@ public abstract class XMLBasedAjcTestCase extends AjcTestCase { |
|
|
|
TestSuite suite = new TestSuite(testCaseClass.getName()); |
|
|
|
suite.addTestSuite(testCaseClass); |
|
|
|
TestSetup wrapper = new TestSetup(suite) { |
|
|
|
/* (non-Javadoc) |
|
|
|
/* |
|
|
|
* (non-Javadoc) |
|
|
|
* |
|
|
|
* @see junit.extensions.TestSetup#setUp() |
|
|
|
*/ |
|
|
|
protected void setUp() throws Exception { |
|
|
|
super.setUp(); |
|
|
|
suiteLoaded = false; |
|
|
|
} |
|
|
|
/* (non-Javadoc) |
|
|
|
|
|
|
|
/* |
|
|
|
* (non-Javadoc) |
|
|
|
* |
|
|
|
* @see junit.extensions.TestSetup#tearDown() |
|
|
|
*/ |
|
|
|
protected void tearDown() throws Exception { |
|
|
@@ -79,128 +85,142 @@ public abstract class XMLBasedAjcTestCase extends AjcTestCase { |
|
|
|
}; |
|
|
|
return wrapper; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* The file containing the XML specification for the tests. |
|
|
|
*/ |
|
|
|
protected abstract File getSpecFile(); |
|
|
|
|
|
|
|
|
|
|
|
/* |
|
|
|
* Return a map from (String) test title -> AjcTest |
|
|
|
*/ |
|
|
|
protected Map getSuiteTests() { |
|
|
|
return testMap; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* This helper method runs the test with the given title in the |
|
|
|
* suite spec file. All tests steps in given ajc-test execute |
|
|
|
* in the same sandbox. |
|
|
|
* This helper method runs the test with the given title in the suite spec file. All tests steps in given ajc-test execute in |
|
|
|
* the same sandbox. |
|
|
|
*/ |
|
|
|
protected void runTest(String title, boolean print) { |
|
|
|
try { |
|
|
|
currentTest = (AjcTest) testMap.get(title); |
|
|
|
final boolean clearTest = clearTestAfterRun(); |
|
|
|
if (currentTest == null) { |
|
|
|
if (clearTest) { |
|
|
|
System.err.println("test already run: " + title); |
|
|
|
return; |
|
|
|
} else { |
|
|
|
fail("No test '" + title + "' in suite."); |
|
|
|
} |
|
|
|
} |
|
|
|
boolean run = currentTest.runTest(this); |
|
|
|
assertTrue("Test not run", run); |
|
|
|
if (clearTest) { |
|
|
|
testMap.remove(title); |
|
|
|
} |
|
|
|
} finally { |
|
|
|
if (print) { |
|
|
|
System.out.println("SYSOUT"); |
|
|
|
System.out.println(ajc.getLastCompilationResult().getStandardOutput()); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
protected void runTest(String title) { |
|
|
|
currentTest = (AjcTest) testMap.get(title); |
|
|
|
final boolean clearTest = clearTestAfterRun(); |
|
|
|
if (currentTest == null) { |
|
|
|
if (clearTest) { |
|
|
|
System.err.println("test already run: " + title); |
|
|
|
return; |
|
|
|
} else { |
|
|
|
fail("No test '" + title + "' in suite."); |
|
|
|
} |
|
|
|
} |
|
|
|
boolean run = currentTest.runTest(this); |
|
|
|
assertTrue("Test not run",run); |
|
|
|
if (clearTest) { |
|
|
|
testMap.remove(title); |
|
|
|
} |
|
|
|
runTest(title, false); |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* Get the currently executing test. Useful for access to e.g. |
|
|
|
* AjcTest.getTitle() etc.. |
|
|
|
* Get the currently executing test. Useful for access to e.g. AjcTest.getTitle() etc.. |
|
|
|
*/ |
|
|
|
protected AjcTest getCurrentTest() { |
|
|
|
return currentTest; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* For use by the Digester. As the XML document is parsed, it creates instances |
|
|
|
* of AjcTest objects, which are added to this TestCase by the Digester by |
|
|
|
* calling this method. |
|
|
|
*/ |
|
|
|
* For use by the Digester. As the XML document is parsed, it creates instances of AjcTest objects, which are added to this |
|
|
|
* TestCase by the Digester by calling this method. |
|
|
|
*/ |
|
|
|
public void addTest(AjcTest test) { |
|
|
|
testMap.put(test.getTitle(),test); |
|
|
|
testMap.put(test.getTitle(), test); |
|
|
|
} |
|
|
|
|
|
|
|
protected final void pushClearTestAfterRun(boolean val) { |
|
|
|
clearTestAfterRun.push(val ? Boolean.FALSE : Boolean.TRUE); |
|
|
|
} |
|
|
|
|
|
|
|
protected final boolean popClearTestAfterRun() { |
|
|
|
return clearTest(true); |
|
|
|
} |
|
|
|
|
|
|
|
protected final boolean clearTestAfterRun() { |
|
|
|
return clearTest(false); |
|
|
|
} |
|
|
|
|
|
|
|
private boolean clearTest(boolean pop) { |
|
|
|
if (clearTestAfterRun.isEmpty()) { |
|
|
|
return false; |
|
|
|
} |
|
|
|
boolean result = ((Boolean) clearTestAfterRun.peek()).booleanValue(); |
|
|
|
if (pop) { |
|
|
|
clearTestAfterRun.pop(); |
|
|
|
} |
|
|
|
return result; |
|
|
|
} |
|
|
|
protected final void pushClearTestAfterRun(boolean val) { |
|
|
|
clearTestAfterRun.push(val ? Boolean.FALSE: Boolean.TRUE); |
|
|
|
} |
|
|
|
protected final boolean popClearTestAfterRun() { |
|
|
|
return clearTest(true); |
|
|
|
} |
|
|
|
protected final boolean clearTestAfterRun() { |
|
|
|
return clearTest(false); |
|
|
|
} |
|
|
|
private boolean clearTest(boolean pop) { |
|
|
|
if (clearTestAfterRun.isEmpty()) { |
|
|
|
return false; |
|
|
|
} |
|
|
|
boolean result = ((Boolean) clearTestAfterRun.peek()).booleanValue(); |
|
|
|
if (pop) { |
|
|
|
clearTestAfterRun.pop(); |
|
|
|
} |
|
|
|
return result; |
|
|
|
} |
|
|
|
|
|
|
|
/* |
|
|
|
* The rules for parsing a suite spec file. The Digester using bean properties to match attributes |
|
|
|
* in the XML document to properties in the associated classes, so this simple implementation should |
|
|
|
* be very easy to maintain and extend should you ever need to. |
|
|
|
* The rules for parsing a suite spec file. The Digester using bean properties to match attributes in the XML document to |
|
|
|
* properties in the associated classes, so this simple implementation should be very easy to maintain and extend should you |
|
|
|
* ever need to. |
|
|
|
*/ |
|
|
|
protected Digester getDigester() { |
|
|
|
Digester digester = new Digester(); |
|
|
|
digester.push(this); |
|
|
|
digester.addObjectCreate("suite/ajc-test",AjcTest.class); |
|
|
|
digester.addObjectCreate("suite/ajc-test", AjcTest.class); |
|
|
|
digester.addSetProperties("suite/ajc-test"); |
|
|
|
digester.addSetNext("suite/ajc-test","addTest","org.aspectj.testing.AjcTest"); |
|
|
|
digester.addObjectCreate("suite/ajc-test/compile",CompileSpec.class); |
|
|
|
digester.addSetNext("suite/ajc-test", "addTest", "org.aspectj.testing.AjcTest"); |
|
|
|
digester.addObjectCreate("suite/ajc-test/compile", CompileSpec.class); |
|
|
|
digester.addSetProperties("suite/ajc-test/compile"); |
|
|
|
digester.addSetNext("suite/ajc-test/compile","addTestStep","org.aspectj.testing.ITestStep"); |
|
|
|
digester.addObjectCreate("suite/ajc-test/run",RunSpec.class); |
|
|
|
digester.addSetProperties("suite/ajc-test/run","class","classToRun"); |
|
|
|
digester.addSetProperties("suite/ajc-test/run","ltw","ltwFile"); |
|
|
|
digester.addSetProperties("suite/ajc-test/run","xlintfile","xlintFile"); |
|
|
|
digester.addSetProperties("suite/ajc-test/run/stderr","ordered","orderedStderr"); |
|
|
|
digester.addSetNext("suite/ajc-test/run","addTestStep","org.aspectj.testing.ITestStep"); |
|
|
|
digester.addObjectCreate("*/message",ExpectedMessageSpec.class); |
|
|
|
digester.addSetNext("suite/ajc-test/compile", "addTestStep", "org.aspectj.testing.ITestStep"); |
|
|
|
digester.addObjectCreate("suite/ajc-test/run", RunSpec.class); |
|
|
|
digester.addSetProperties("suite/ajc-test/run", "class", "classToRun"); |
|
|
|
digester.addSetProperties("suite/ajc-test/run", "ltw", "ltwFile"); |
|
|
|
digester.addSetProperties("suite/ajc-test/run", "xlintfile", "xlintFile"); |
|
|
|
digester.addSetProperties("suite/ajc-test/run/stderr", "ordered", "orderedStderr"); |
|
|
|
digester.addSetNext("suite/ajc-test/run", "addTestStep", "org.aspectj.testing.ITestStep"); |
|
|
|
digester.addObjectCreate("*/message", ExpectedMessageSpec.class); |
|
|
|
digester.addSetProperties("*/message"); |
|
|
|
digester.addSetNext("*/message","addExpectedMessage","org.aspectj.testing.ExpectedMessageSpec"); |
|
|
|
digester.addObjectCreate("suite/ajc-test/weave",WeaveSpec.class); |
|
|
|
digester.addSetNext("*/message", "addExpectedMessage", "org.aspectj.testing.ExpectedMessageSpec"); |
|
|
|
digester.addObjectCreate("suite/ajc-test/weave", WeaveSpec.class); |
|
|
|
digester.addSetProperties("suite/ajc-test/weave"); |
|
|
|
digester.addSetNext("suite/ajc-test/weave","addTestStep","org.aspectj.testing.ITestStep"); |
|
|
|
|
|
|
|
digester.addObjectCreate("suite/ajc-test/ant",AntSpec.class); |
|
|
|
digester.addSetProperties("suite/ajc-test/ant"); |
|
|
|
digester.addSetNext("suite/ajc-test/ant","addTestStep","org.aspectj.testing.ITestStep"); |
|
|
|
digester.addObjectCreate("suite/ajc-test/ant/stderr",OutputSpec.class); |
|
|
|
digester.addSetProperties("suite/ajc-test/ant/stderr"); |
|
|
|
digester.addSetNext("suite/ajc-test/ant/stderr","addStdErrSpec","org.aspectj.testing.OutputSpec"); |
|
|
|
digester.addObjectCreate("suite/ajc-test/ant/stdout",OutputSpec.class); |
|
|
|
digester.addSetProperties("suite/ajc-test/ant/stdout"); |
|
|
|
digester.addSetNext("suite/ajc-test/ant/stdout","addStdOutSpec","org.aspectj.testing.OutputSpec"); |
|
|
|
|
|
|
|
digester.addObjectCreate("suite/ajc-test/run/stderr",OutputSpec.class); |
|
|
|
digester.addSetNext("suite/ajc-test/weave", "addTestStep", "org.aspectj.testing.ITestStep"); |
|
|
|
|
|
|
|
digester.addObjectCreate("suite/ajc-test/ant", AntSpec.class); |
|
|
|
digester.addSetProperties("suite/ajc-test/ant"); |
|
|
|
digester.addSetNext("suite/ajc-test/ant", "addTestStep", "org.aspectj.testing.ITestStep"); |
|
|
|
digester.addObjectCreate("suite/ajc-test/ant/stderr", OutputSpec.class); |
|
|
|
digester.addSetProperties("suite/ajc-test/ant/stderr"); |
|
|
|
digester.addSetNext("suite/ajc-test/ant/stderr", "addStdErrSpec", "org.aspectj.testing.OutputSpec"); |
|
|
|
digester.addObjectCreate("suite/ajc-test/ant/stdout", OutputSpec.class); |
|
|
|
digester.addSetProperties("suite/ajc-test/ant/stdout"); |
|
|
|
digester.addSetNext("suite/ajc-test/ant/stdout", "addStdOutSpec", "org.aspectj.testing.OutputSpec"); |
|
|
|
|
|
|
|
digester.addObjectCreate("suite/ajc-test/run/stderr", OutputSpec.class); |
|
|
|
digester.addSetProperties("suite/ajc-test/run/stderr"); |
|
|
|
digester.addSetNext("suite/ajc-test/run/stderr","addStdErrSpec","org.aspectj.testing.OutputSpec"); |
|
|
|
digester.addObjectCreate("suite/ajc-test/run/stdout",OutputSpec.class); |
|
|
|
digester.addSetNext("suite/ajc-test/run/stderr", "addStdErrSpec", "org.aspectj.testing.OutputSpec"); |
|
|
|
digester.addObjectCreate("suite/ajc-test/run/stdout", OutputSpec.class); |
|
|
|
digester.addSetProperties("suite/ajc-test/run/stdout"); |
|
|
|
digester.addSetNext("suite/ajc-test/run/stdout","addStdOutSpec","org.aspectj.testing.OutputSpec"); |
|
|
|
digester.addObjectCreate("*/line",OutputLine.class); |
|
|
|
digester.addSetNext("suite/ajc-test/run/stdout", "addStdOutSpec", "org.aspectj.testing.OutputSpec"); |
|
|
|
digester.addObjectCreate("*/line", OutputLine.class); |
|
|
|
digester.addSetProperties("*/line"); |
|
|
|
digester.addSetNext("*/line","addLine","org.aspectj.testing.OutputLine"); |
|
|
|
digester.addSetNext("*/line", "addLine", "org.aspectj.testing.OutputLine"); |
|
|
|
return digester; |
|
|
|
} |
|
|
|
|
|
|
|
/* (non-Javadoc) |
|
|
|
/* |
|
|
|
* (non-Javadoc) |
|
|
|
* |
|
|
|
* @see org.aspectj.tools.ajc.AjcTestCase#setUp() |
|
|
|
*/ |
|
|
|
protected void setUp() throws Exception { |
|
|
@@ -219,82 +239,80 @@ public abstract class XMLBasedAjcTestCase extends AjcTestCase { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
protected long nextIncrement(boolean doWait) { |
|
|
|
long time = System.currentTimeMillis(); |
|
|
|
if (doWait) { |
|
|
|
try { |
|
|
|
Thread.sleep(1000); |
|
|
|
} catch (InterruptedException intEx) {} |
|
|
|
} |
|
|
|
return time; |
|
|
|
} |
|
|
|
|
|
|
|
protected void copyFile(String from, String to) throws Exception { |
|
|
|
String dir = getCurrentTest().getDir(); |
|
|
|
FileUtil.copyFile(new File(dir + File.separator + from), |
|
|
|
new File(ajc.getSandboxDirectory(),to)); |
|
|
|
} |
|
|
|
|
|
|
|
protected void copyFileAndDoIncrementalBuild(String from, String to) throws Exception { |
|
|
|
copyFile(from,to); |
|
|
|
CompilationResult result = ajc.doIncrementalCompile(); |
|
|
|
assertNoMessages(result,"Expected clean compile from test '" + getCurrentTest().getTitle() + "'"); |
|
|
|
} |
|
|
|
|
|
|
|
protected void copyFileAndDoIncrementalBuild(String from, String to, MessageSpec expectedResults) throws Exception { |
|
|
|
String dir = getCurrentTest().getDir(); |
|
|
|
FileUtil.copyFile(new File(dir + File.separator + from), |
|
|
|
new File(ajc.getSandboxDirectory(),to)); |
|
|
|
CompilationResult result = ajc.doIncrementalCompile(); |
|
|
|
assertMessages(result,"Test '" + getCurrentTest().getTitle() + "' did not produce expected messages",expectedResults); |
|
|
|
} |
|
|
|
|
|
|
|
protected void deleteFile(String file) { |
|
|
|
new File(ajc.getSandboxDirectory(),file).delete(); |
|
|
|
} |
|
|
|
|
|
|
|
protected void deleteFileAndDoIncrementalBuild(String file, MessageSpec expectedResult) throws Exception { |
|
|
|
deleteFile(file); |
|
|
|
CompilationResult result = ajc.doIncrementalCompile(); |
|
|
|
assertMessages(result,"Test '" + getCurrentTest().getTitle() + "' did not produce expected messages",expectedResult); |
|
|
|
} |
|
|
|
|
|
|
|
protected void deleteFileAndDoIncrementalBuild(String file) throws Exception { |
|
|
|
deleteFileAndDoIncrementalBuild(file,MessageSpec.EMPTY_MESSAGE_SET); |
|
|
|
} |
|
|
|
|
|
|
|
protected void assertAdded(String file) { |
|
|
|
assertTrue("File " + file + " should have been added", |
|
|
|
new File(ajc.getSandboxDirectory(),file).exists()); |
|
|
|
} |
|
|
|
|
|
|
|
protected void assertDeleted(String file) { |
|
|
|
assertFalse("File " + file + " should have been deleted", |
|
|
|
new File(ajc.getSandboxDirectory(),file).exists()); |
|
|
|
} |
|
|
|
|
|
|
|
protected void assertUpdated(String file, long sinceTime) { |
|
|
|
File f = new File(ajc.getSandboxDirectory(),file); |
|
|
|
assertTrue("File " + file + " should have been updated",f.lastModified() > sinceTime); |
|
|
|
} |
|
|
|
|
|
|
|
public static class CountingFilenameFilter implements FilenameFilter { |
|
|
|
|
|
|
|
private String suffix; |
|
|
|
private int count; |
|
|
|
|
|
|
|
public CountingFilenameFilter (String s) { |
|
|
|
this.suffix = s; |
|
|
|
} |
|
|
|
|
|
|
|
public boolean accept(File dir, String name) { |
|
|
|
if (name.endsWith(suffix)) count++; |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
public int getCount() { |
|
|
|
return count; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
protected long nextIncrement(boolean doWait) { |
|
|
|
long time = System.currentTimeMillis(); |
|
|
|
if (doWait) { |
|
|
|
try { |
|
|
|
Thread.sleep(1000); |
|
|
|
} catch (InterruptedException intEx) { |
|
|
|
} |
|
|
|
} |
|
|
|
return time; |
|
|
|
} |
|
|
|
|
|
|
|
protected void copyFile(String from, String to) throws Exception { |
|
|
|
String dir = getCurrentTest().getDir(); |
|
|
|
FileUtil.copyFile(new File(dir + File.separator + from), new File(ajc.getSandboxDirectory(), to)); |
|
|
|
} |
|
|
|
|
|
|
|
protected void copyFileAndDoIncrementalBuild(String from, String to) throws Exception { |
|
|
|
copyFile(from, to); |
|
|
|
CompilationResult result = ajc.doIncrementalCompile(); |
|
|
|
assertNoMessages(result, "Expected clean compile from test '" + getCurrentTest().getTitle() + "'"); |
|
|
|
} |
|
|
|
|
|
|
|
protected void copyFileAndDoIncrementalBuild(String from, String to, MessageSpec expectedResults) throws Exception { |
|
|
|
String dir = getCurrentTest().getDir(); |
|
|
|
FileUtil.copyFile(new File(dir + File.separator + from), new File(ajc.getSandboxDirectory(), to)); |
|
|
|
CompilationResult result = ajc.doIncrementalCompile(); |
|
|
|
assertMessages(result, "Test '" + getCurrentTest().getTitle() + "' did not produce expected messages", expectedResults); |
|
|
|
} |
|
|
|
|
|
|
|
protected void deleteFile(String file) { |
|
|
|
new File(ajc.getSandboxDirectory(), file).delete(); |
|
|
|
} |
|
|
|
|
|
|
|
protected void deleteFileAndDoIncrementalBuild(String file, MessageSpec expectedResult) throws Exception { |
|
|
|
deleteFile(file); |
|
|
|
CompilationResult result = ajc.doIncrementalCompile(); |
|
|
|
assertMessages(result, "Test '" + getCurrentTest().getTitle() + "' did not produce expected messages", expectedResult); |
|
|
|
} |
|
|
|
|
|
|
|
protected void deleteFileAndDoIncrementalBuild(String file) throws Exception { |
|
|
|
deleteFileAndDoIncrementalBuild(file, MessageSpec.EMPTY_MESSAGE_SET); |
|
|
|
} |
|
|
|
|
|
|
|
protected void assertAdded(String file) { |
|
|
|
assertTrue("File " + file + " should have been added", new File(ajc.getSandboxDirectory(), file).exists()); |
|
|
|
} |
|
|
|
|
|
|
|
protected void assertDeleted(String file) { |
|
|
|
assertFalse("File " + file + " should have been deleted", new File(ajc.getSandboxDirectory(), file).exists()); |
|
|
|
} |
|
|
|
|
|
|
|
protected void assertUpdated(String file, long sinceTime) { |
|
|
|
File f = new File(ajc.getSandboxDirectory(), file); |
|
|
|
assertTrue("File " + file + " should have been updated", f.lastModified() > sinceTime); |
|
|
|
} |
|
|
|
|
|
|
|
public static class CountingFilenameFilter implements FilenameFilter { |
|
|
|
|
|
|
|
private String suffix; |
|
|
|
private int count; |
|
|
|
|
|
|
|
public CountingFilenameFilter(String s) { |
|
|
|
this.suffix = s; |
|
|
|
} |
|
|
|
|
|
|
|
public boolean accept(File dir, String name) { |
|
|
|
if (name.endsWith(suffix)) { |
|
|
|
count++; |
|
|
|
} |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
public int getCount() { |
|
|
|
return count; |
|
|
|
} |
|
|
|
} |
|
|
|
} |