Issue #569: Move TreeWalker cache to Checker
This commit is contained in:
parent
3c2c3f7f59
commit
d46c2cf0e9
|
|
@ -12,7 +12,7 @@
|
|||
<!-- There is no other way to deliver filename that was under processing -->
|
||||
<suppress checks="IllegalCatch"
|
||||
files="Checker.java"
|
||||
lines="279"/>
|
||||
lines="327"/>
|
||||
|
||||
<!-- we can not change it as, Check name is part of API (used in configurations) -->
|
||||
<suppress checks="AbbreviationAsWordInName"
|
||||
|
|
|
|||
|
|
@ -112,6 +112,9 @@ public class Checker extends AutomaticBean implements MessageDispatcher {
|
|||
/** Name of a charset. */
|
||||
private String charset = System.getProperty("file.encoding", "UTF-8");
|
||||
|
||||
/** Cache file. **/
|
||||
private PropertyCacheFile cache;
|
||||
|
||||
/**
|
||||
* Creates a new {@code Checker} instance.
|
||||
* The instance needs to be contextualized and configured.
|
||||
|
|
@ -120,6 +123,17 @@ public class Checker extends AutomaticBean implements MessageDispatcher {
|
|||
addListener(counter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets cache file.
|
||||
* @param fileName the cache file.
|
||||
* @throws IOException if there are some problems with file loading.
|
||||
*/
|
||||
public void setCacheFile(String fileName) throws IOException {
|
||||
final Configuration configuration = getConfiguration();
|
||||
cache = new PropertyCacheFile(configuration, fileName);
|
||||
cache.load();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finishLocalSetup() throws CheckstyleException {
|
||||
final Locale locale = new Locale(localeLanguage, localeCountry);
|
||||
|
|
@ -216,6 +230,14 @@ public class Checker extends AutomaticBean implements MessageDispatcher {
|
|||
public void destroy() {
|
||||
listeners.clear();
|
||||
filters.clear();
|
||||
if (cache != null) {
|
||||
try {
|
||||
cache.persist();
|
||||
}
|
||||
catch (IOException ex) {
|
||||
throw new IllegalStateException("Unable to persist cache file.", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -250,38 +272,7 @@ public class Checker extends AutomaticBean implements MessageDispatcher {
|
|||
fsc.beginProcessing(charset);
|
||||
}
|
||||
|
||||
// Process each file
|
||||
for (final File file : files) {
|
||||
try {
|
||||
if (!CommonUtils.matchesFileExtension(file, fileExtensions)) {
|
||||
continue;
|
||||
}
|
||||
final String fileName = file.getAbsolutePath();
|
||||
fireFileStarted(fileName);
|
||||
final SortedSet<LocalizedMessage> fileMessages = Sets.newTreeSet();
|
||||
try {
|
||||
final FileText theText = new FileText(file.getAbsoluteFile(),
|
||||
charset);
|
||||
for (final FileSetCheck fsc : fileSetChecks) {
|
||||
fileMessages.addAll(fsc.process(file, theText));
|
||||
}
|
||||
}
|
||||
catch (final IOException ioe) {
|
||||
LOG.debug("IOException occurred.", ioe);
|
||||
fileMessages.add(new LocalizedMessage(0,
|
||||
Definitions.CHECKSTYLE_BUNDLE, "general.exception",
|
||||
new String[] {ioe.getMessage()}, null, getClass(),
|
||||
null));
|
||||
}
|
||||
fireErrors(fileName, fileMessages);
|
||||
fireFileFinished(fileName);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
// We need to catch all exception to put a reason failure(file name) in exception
|
||||
throw new CheckstyleException("Exception was thrown while processing "
|
||||
+ file.getPath(), ex);
|
||||
}
|
||||
}
|
||||
processFiles(files);
|
||||
|
||||
// Finish up
|
||||
for (final FileSetCheck fsc : fileSetChecks) {
|
||||
|
|
@ -299,6 +290,48 @@ public class Checker extends AutomaticBean implements MessageDispatcher {
|
|||
return errorCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes a list of files with all FileSetChecks.
|
||||
* @param files a list of files to process.
|
||||
* @throws CheckstyleException if error condition within Checkstyle occurs.
|
||||
*/
|
||||
private void processFiles(List<File> files) throws CheckstyleException {
|
||||
for (final File file : files) {
|
||||
try {
|
||||
final String fileName = file.getAbsolutePath();
|
||||
fireFileStarted(fileName);
|
||||
final long timestamp = file.lastModified();
|
||||
if (cache != null && cache.isInCache(fileName, timestamp)
|
||||
|| !CommonUtils.matchesFileExtension(file, fileExtensions)) {
|
||||
continue;
|
||||
}
|
||||
final SortedSet<LocalizedMessage> fileMessages = Sets.newTreeSet();
|
||||
try {
|
||||
final FileText theText = new FileText(file.getAbsoluteFile(), charset);
|
||||
for (final FileSetCheck fsc : fileSetChecks) {
|
||||
fileMessages.addAll(fsc.process(file, theText));
|
||||
}
|
||||
}
|
||||
catch (final IOException ioe) {
|
||||
LOG.debug("IOException occurred.", ioe);
|
||||
fileMessages.add(new LocalizedMessage(0,
|
||||
Definitions.CHECKSTYLE_BUNDLE, "general.exception",
|
||||
new String[] {ioe.getMessage()}, null, getClass(), null));
|
||||
}
|
||||
fireErrors(fileName, fileMessages);
|
||||
fireFileFinished(fileName);
|
||||
if (cache != null && fileMessages.isEmpty()) {
|
||||
cache.put(fileName, timestamp);
|
||||
}
|
||||
}
|
||||
catch (Exception ex) {
|
||||
// We need to catch all exception to put a reason failure(file name) in exception
|
||||
throw new CheckstyleException("Exception was thrown while processing "
|
||||
+ file.getPath(), ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets base directory.
|
||||
* @param basedir the base directory to strip off in file names
|
||||
|
|
@ -480,4 +513,13 @@ public class Checker extends AutomaticBean implements MessageDispatcher {
|
|||
}
|
||||
this.charset = charset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the cache.
|
||||
*/
|
||||
public void clearCache() {
|
||||
if (cache != null) {
|
||||
cache.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -154,6 +154,13 @@ final class PropertyCacheFile {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the cache.
|
||||
*/
|
||||
void clear() {
|
||||
details.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Flushes and closes output stream.
|
||||
* @param stream the output stream
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@
|
|||
package com.puppycrawl.tools.checkstyle;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.io.StringReader;
|
||||
import java.util.AbstractMap.SimpleEntry;
|
||||
|
|
@ -37,7 +36,6 @@ import antlr.Token;
|
|||
import antlr.TokenStreamException;
|
||||
import antlr.TokenStreamHiddenTokenFilter;
|
||||
import antlr.TokenStreamRecognitionException;
|
||||
|
||||
import com.google.common.collect.HashMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.collect.Sets;
|
||||
|
|
@ -84,9 +82,6 @@ public final class TreeWalker
|
|||
/** The distance between tab stops. */
|
||||
private int tabWidth = DEFAULT_TAB_WIDTH;
|
||||
|
||||
/** Cache file. **/
|
||||
private PropertyCacheFile cache;
|
||||
|
||||
/** Class loader to resolve classes with. **/
|
||||
private ClassLoader classLoader;
|
||||
|
||||
|
|
@ -113,14 +108,15 @@ public final class TreeWalker
|
|||
|
||||
/**
|
||||
* Sets cache file.
|
||||
* @deprecated Use {@link Checker#setCacheFile} instead. It does not do anything now. We just
|
||||
* keep the setter for transition period to the same option in Checker. The
|
||||
* method will be completely removed in Checkstyle 8.0. See
|
||||
* <a href="https://github.com/checkstyle/checkstyle/issues/2883">issue#2883</a>
|
||||
* @param fileName the cache file
|
||||
* @throws IOException if there are some problems with file loading
|
||||
*/
|
||||
public void setCacheFile(String fileName) throws IOException {
|
||||
final Configuration configuration = getConfiguration();
|
||||
cache = new PropertyCacheFile(configuration, fileName);
|
||||
|
||||
cache.load();
|
||||
@Deprecated
|
||||
public void setCacheFile(String fileName) {
|
||||
// Deprecated
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -169,16 +165,12 @@ public final class TreeWalker
|
|||
@Override
|
||||
protected void processFiltered(File file, List<String> lines) throws CheckstyleException {
|
||||
// check if already checked and passed the file
|
||||
final String fileName = file.getPath();
|
||||
final long timestamp = file.lastModified();
|
||||
if (cache != null
|
||||
&& (cache.isInCache(fileName, timestamp)
|
||||
|| !CommonUtils.matchesFileExtension(file, getFileExtensions()))) {
|
||||
if (!CommonUtils.matchesFileExtension(file, getFileExtensions())) {
|
||||
return;
|
||||
}
|
||||
|
||||
final String msg = "%s occurred during the analysis of file %s.";
|
||||
|
||||
final String fileName = file.getPath();
|
||||
try {
|
||||
final FileText text = FileText.fromLines(file, lines);
|
||||
final FileContents contents = new FileContents(text);
|
||||
|
|
@ -202,10 +194,6 @@ public final class TreeWalker
|
|||
ex.getClass().getSimpleName(), fileName);
|
||||
throw new CheckstyleException(exceptionMsg, ex);
|
||||
}
|
||||
|
||||
if (cache != null && getMessageCollector().size() == 0) {
|
||||
cache.put(fileName, timestamp);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -463,14 +451,6 @@ public final class TreeWalker
|
|||
for (AbstractCheck check : commentChecks) {
|
||||
check.destroy();
|
||||
}
|
||||
if (cache != null) {
|
||||
try {
|
||||
cache.persist();
|
||||
}
|
||||
catch (IOException ex) {
|
||||
throw new IllegalStateException("Unable to persist cache file", ex);
|
||||
}
|
||||
}
|
||||
super.destroy();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,26 +19,42 @@
|
|||
|
||||
package com.puppycrawl.tools.checkstyle;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.anyOf;
|
||||
import static org.hamcrest.CoreMatchers.instanceOf;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.nio.file.InvalidPathException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.SortedSet;
|
||||
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
import org.junit.Assume;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.TemporaryFolder;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
import com.puppycrawl.tools.checkstyle.api.CheckstyleException;
|
||||
import com.puppycrawl.tools.checkstyle.api.Configuration;
|
||||
import com.puppycrawl.tools.checkstyle.api.LocalizedMessage;
|
||||
import com.puppycrawl.tools.checkstyle.checks.TranslationCheck;
|
||||
import com.puppycrawl.tools.checkstyle.checks.coding.HiddenFieldCheck;
|
||||
|
||||
public class CheckerTest extends BaseCheckTestSupport {
|
||||
|
||||
@Rule
|
||||
public final TemporaryFolder temporaryFolder = new TemporaryFolder();
|
||||
|
||||
public class CheckerTest {
|
||||
@Test
|
||||
public void testDestroy() throws Exception {
|
||||
final DebugChecker checker = new DebugChecker();
|
||||
|
|
@ -174,7 +190,14 @@ public class CheckerTest {
|
|||
|
||||
@Test
|
||||
public void testFileExtensions() throws Exception {
|
||||
final DefaultConfiguration checkerConfig = new DefaultConfiguration("configuration");
|
||||
checkerConfig.addAttribute("charset", "UTF-8");
|
||||
checkerConfig.addAttribute("cacheFile", temporaryFolder.newFile().getPath());
|
||||
|
||||
final Checker checker = new Checker();
|
||||
checker.setModuleClassLoader(Thread.currentThread().getContextClassLoader());
|
||||
checker.configure(checkerConfig);
|
||||
|
||||
final List<File> files = new ArrayList<>();
|
||||
final File file = new File("file.pdf");
|
||||
files.add(file);
|
||||
|
|
@ -182,6 +205,7 @@ public class CheckerTest {
|
|||
files.add(otherFile);
|
||||
final String[] fileExtensions = {"java", "xml", "properties"};
|
||||
checker.setFileExtensions(fileExtensions);
|
||||
checker.setCacheFile(temporaryFolder.newFile().getPath());
|
||||
final int counter = checker.process(files);
|
||||
|
||||
// comparing to 1 as there is only one legal file in input
|
||||
|
|
@ -275,4 +299,197 @@ public class CheckerTest {
|
|||
DebugAuditAdapter.class.getCanonicalName());
|
||||
checker.setupChild(config);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDestroyNonExistingCache() throws Exception {
|
||||
// We use assumption to satisfy coverage rate on OS Windows, since persist() method of
|
||||
// class PropertyCacheFile does not throw IOException on OS Linux when path to a cache
|
||||
// directory is invalid on OS Windows.
|
||||
Assume.assumeTrue(System.getProperty("os.name")
|
||||
.toLowerCase(Locale.ENGLISH).startsWith("windows"));
|
||||
|
||||
final Checker checker = new Checker();
|
||||
final PackageObjectFactory factory = new PackageObjectFactory(
|
||||
new HashSet<String>(), Thread.currentThread().getContextClassLoader());
|
||||
checker.setModuleFactory(factory);
|
||||
checker.configure(new DefaultConfiguration("default config"));
|
||||
final String tempFilePath = temporaryFolder.newFile().getPath() + ".\\\'";
|
||||
checker.setCacheFile(tempFilePath);
|
||||
try {
|
||||
checker.destroy();
|
||||
fail("Exception did not happen");
|
||||
}
|
||||
catch (IllegalStateException ex) {
|
||||
assertTrue(ex.getCause() instanceof IOException);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDestroyCacheFileWithInvalidPath() throws Exception {
|
||||
final Checker checker = new Checker();
|
||||
final PackageObjectFactory factory = new PackageObjectFactory(
|
||||
new HashSet<String>(), Thread.currentThread().getContextClassLoader());
|
||||
checker.setModuleFactory(factory);
|
||||
checker.configure(new DefaultConfiguration("default config"));
|
||||
if (System.getProperty("os.name")
|
||||
.toLowerCase(Locale.ENGLISH).startsWith("windows")) {
|
||||
// https://support.microsoft.com/en-us/kb/177506 but this only for NTFS
|
||||
// WindowsServer 2012 use Resilient File System (ReFS), so any name is ok
|
||||
final File file = new File("C\\:invalid");
|
||||
checker.setCacheFile(file.getAbsolutePath());
|
||||
}
|
||||
else {
|
||||
checker.setCacheFile(File.separator + ":invalid");
|
||||
}
|
||||
try {
|
||||
checker.destroy();
|
||||
fail("Exception did not happen");
|
||||
}
|
||||
catch (IllegalStateException ex) {
|
||||
assertThat(ex.getCause(), anyOf(instanceOf(IOException.class),
|
||||
instanceOf(InvalidPathException.class)));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCacheFile() throws Exception {
|
||||
final DefaultConfiguration checkConfig = createCheckConfig(HiddenFieldCheck.class);
|
||||
|
||||
final DefaultConfiguration treeWalkerConfig = createCheckConfig(TreeWalker.class);
|
||||
treeWalkerConfig.addChild(checkConfig);
|
||||
|
||||
final DefaultConfiguration checkerConfig = new DefaultConfiguration("checkstyleConfig");
|
||||
checkerConfig.addAttribute("charset", "UTF-8");
|
||||
checkerConfig.addChild(treeWalkerConfig);
|
||||
checkerConfig.addAttribute("cacheFile", temporaryFolder.newFile().getPath());
|
||||
|
||||
final Checker checker = new Checker();
|
||||
final Locale locale = Locale.ROOT;
|
||||
checker.setLocaleCountry(locale.getCountry());
|
||||
checker.setLocaleLanguage(locale.getLanguage());
|
||||
checker.setModuleClassLoader(Thread.currentThread().getContextClassLoader());
|
||||
checker.configure(checkerConfig);
|
||||
checker.addListener(new BriefUtLogger(stream));
|
||||
|
||||
final String pathToEmptyFile = temporaryFolder.newFile("file.java").getPath();
|
||||
final String[] expected = ArrayUtils.EMPTY_STRING_ARRAY;
|
||||
|
||||
verify(checker, pathToEmptyFile, pathToEmptyFile, expected);
|
||||
// one more time to reuse cache
|
||||
verify(checker, pathToEmptyFile, pathToEmptyFile, expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCacheFileChangeInConfig() throws Exception {
|
||||
final DefaultConfiguration checkConfig = createCheckConfig(HiddenFieldCheck.class);
|
||||
|
||||
final DefaultConfiguration treeWalkerConfig = createCheckConfig(TreeWalker.class);
|
||||
treeWalkerConfig.addChild(checkConfig);
|
||||
|
||||
final DefaultConfiguration checkerConfig = new DefaultConfiguration("configuration");
|
||||
checkerConfig.addAttribute("charset", "UTF-8");
|
||||
checkerConfig.addChild(treeWalkerConfig);
|
||||
checkerConfig.addAttribute("cacheFile", temporaryFolder.newFile().getPath());
|
||||
|
||||
final Checker checker = new Checker();
|
||||
final Locale locale = Locale.ROOT;
|
||||
checker.setLocaleCountry(locale.getCountry());
|
||||
checker.setLocaleLanguage(locale.getLanguage());
|
||||
checker.setModuleClassLoader(Thread.currentThread().getContextClassLoader());
|
||||
checker.configure(checkerConfig);
|
||||
checker.addListener(new BriefUtLogger(stream));
|
||||
|
||||
final String pathToEmptyFile = temporaryFolder.newFile("file.java").getPath();
|
||||
final String[] expected = ArrayUtils.EMPTY_STRING_ARRAY;
|
||||
|
||||
verify(checker, pathToEmptyFile, pathToEmptyFile, expected);
|
||||
|
||||
// update Checker config
|
||||
checker.destroy();
|
||||
checker.configure(checkerConfig);
|
||||
|
||||
final Checker otherChecker = new Checker();
|
||||
otherChecker.setLocaleCountry(locale.getCountry());
|
||||
otherChecker.setLocaleLanguage(locale.getLanguage());
|
||||
otherChecker.setModuleClassLoader(Thread.currentThread().getContextClassLoader());
|
||||
otherChecker.configure(checkerConfig);
|
||||
otherChecker.addListener(new BriefUtLogger(stream));
|
||||
// here is diff with previous checker
|
||||
checkerConfig.addAttribute("fileExtensions", "java,javax");
|
||||
|
||||
// one more time on updated config
|
||||
verify(otherChecker, pathToEmptyFile, pathToEmptyFile, expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithCacheWithNoViolation() throws Exception {
|
||||
final Checker checker = new Checker();
|
||||
final PackageObjectFactory factory = new PackageObjectFactory(
|
||||
new HashSet<String>(), Thread.currentThread().getContextClassLoader());
|
||||
checker.setModuleFactory(factory);
|
||||
checker.configure(createCheckConfig(TranslationCheck.class));
|
||||
checker.setCacheFile(temporaryFolder.newFile().getPath());
|
||||
checker.setupChild(createCheckConfig(TranslationCheck.class));
|
||||
final File file = temporaryFolder.newFile("file.java");
|
||||
final List<File> files = new ArrayList<>();
|
||||
files.add(file);
|
||||
checker.process(files);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClearExistingCache() throws Exception {
|
||||
final DefaultConfiguration checkConfig = createCheckConfig(HiddenFieldCheck.class);
|
||||
|
||||
final DefaultConfiguration treeWalkerConfig = createCheckConfig(TreeWalker.class);
|
||||
treeWalkerConfig.addChild(checkConfig);
|
||||
|
||||
final DefaultConfiguration checkerConfig = new DefaultConfiguration("myConfig");
|
||||
checkerConfig.addAttribute("charset", "UTF-8");
|
||||
checkerConfig.addChild(treeWalkerConfig);
|
||||
checkerConfig.addAttribute("cacheFile", temporaryFolder.newFile().getPath());
|
||||
|
||||
final Checker checker = new Checker();
|
||||
final Locale locale = Locale.ROOT;
|
||||
checker.setLocaleCountry(locale.getCountry());
|
||||
checker.setLocaleLanguage(locale.getLanguage());
|
||||
checker.setModuleClassLoader(Thread.currentThread().getContextClassLoader());
|
||||
checker.configure(checkerConfig);
|
||||
checker.addListener(new BriefUtLogger(stream));
|
||||
|
||||
final String pathToEmptyFile = temporaryFolder.newFile("file.java").getPath();
|
||||
final String[] expected = ArrayUtils.EMPTY_STRING_ARRAY;
|
||||
|
||||
verify(checker, pathToEmptyFile, pathToEmptyFile, expected);
|
||||
checker.clearCache();
|
||||
// one more time, but file that should be audited is not in cache
|
||||
verify(checker, pathToEmptyFile, pathToEmptyFile, expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClearNonexistentCache() throws Exception {
|
||||
final DefaultConfiguration checkConfig = createCheckConfig(HiddenFieldCheck.class);
|
||||
|
||||
final DefaultConfiguration treeWalkerConfig = createCheckConfig(TreeWalker.class);
|
||||
treeWalkerConfig.addChild(checkConfig);
|
||||
|
||||
final DefaultConfiguration checkerConfig = new DefaultConfiguration("simpleConfig");
|
||||
checkerConfig.addAttribute("charset", "UTF-8");
|
||||
checkerConfig.addChild(treeWalkerConfig);
|
||||
|
||||
final Checker checker = new Checker();
|
||||
final Locale locale = Locale.ROOT;
|
||||
checker.setLocaleCountry(locale.getCountry());
|
||||
checker.setLocaleLanguage(locale.getLanguage());
|
||||
checker.setModuleClassLoader(Thread.currentThread().getContextClassLoader());
|
||||
checker.configure(checkerConfig);
|
||||
checker.addListener(new BriefUtLogger(stream));
|
||||
|
||||
final String pathToEmptyFile = temporaryFolder.newFile("file.java").getPath();
|
||||
final String[] expected = ArrayUtils.EMPTY_STRING_ARRAY;
|
||||
|
||||
verify(checker, pathToEmptyFile, pathToEmptyFile, expected);
|
||||
checker.clearCache();
|
||||
// one more time, but cache does not exist
|
||||
verify(checker, pathToEmptyFile, pathToEmptyFile, expected);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,27 +19,20 @@
|
|||
|
||||
package com.puppycrawl.tools.checkstyle;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.anyOf;
|
||||
import static org.hamcrest.CoreMatchers.instanceOf;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.Writer;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.InvalidPathException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
import org.junit.Assume;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.TemporaryFolder;
|
||||
|
|
@ -138,122 +131,6 @@ public class TreeWalkerTest extends BaseCheckTestSupport {
|
|||
treeWalker.setCacheFile(temporaryFolder.newFile().getPath());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDestroyNonExistingCache() throws Exception {
|
||||
|
||||
// We use assumption to satisfy coverage rate on OS Windows, since persist() method of
|
||||
// class PropertyCacheFile does not throw IOException on OS Linux when path to a cache
|
||||
// directory is invalid on OS Windows.
|
||||
Assume.assumeTrue(System.getProperty("os.name")
|
||||
.toLowerCase(Locale.ENGLISH).startsWith("windows"));
|
||||
|
||||
final TreeWalker treeWalker = new TreeWalker();
|
||||
treeWalker.configure(new DefaultConfiguration("default config"));
|
||||
final String tempFilePath = temporaryFolder.newFile().getPath() + ".\\\'";
|
||||
treeWalker.setCacheFile(tempFilePath);
|
||||
try {
|
||||
treeWalker.destroy();
|
||||
fail("Exception did not happen");
|
||||
}
|
||||
catch (IllegalStateException ex) {
|
||||
assertTrue(ex.getCause() instanceof IOException);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDestroyCacheFileWithInvalidPath() throws Exception {
|
||||
final TreeWalker treeWalker = new TreeWalker();
|
||||
treeWalker.configure(new DefaultConfiguration("default config"));
|
||||
if (System.getProperty("os.name")
|
||||
.toLowerCase(Locale.ENGLISH).startsWith("windows")) {
|
||||
// https://support.microsoft.com/en-us/kb/177506 but this only for NTFS
|
||||
// WindowsServer 2012 use Resilient File System (ReFS), so any name is ok
|
||||
final File file = new File("C\\:invalid");
|
||||
treeWalker.setCacheFile(file.getAbsolutePath());
|
||||
}
|
||||
else {
|
||||
treeWalker.setCacheFile(File.separator + ":invalid");
|
||||
}
|
||||
try {
|
||||
treeWalker.destroy();
|
||||
fail("Exception did not happen");
|
||||
}
|
||||
catch (IllegalStateException ex) {
|
||||
assertThat(ex.getCause(), anyOf(instanceOf(IOException.class),
|
||||
instanceOf(InvalidPathException.class)));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCacheFile() throws Exception {
|
||||
final DefaultConfiguration checkConfig = createCheckConfig(HiddenFieldCheck.class);
|
||||
|
||||
final DefaultConfiguration treeWalkerConfig = createCheckConfig(TreeWalker.class);
|
||||
treeWalkerConfig.addAttribute("cacheFile", temporaryFolder.newFile().getPath());
|
||||
treeWalkerConfig.addChild(checkConfig);
|
||||
|
||||
final DefaultConfiguration checkerConfig = new DefaultConfiguration("configuration");
|
||||
checkerConfig.addAttribute("charset", "UTF-8");
|
||||
checkerConfig.addChild(treeWalkerConfig);
|
||||
|
||||
final Checker checker = new Checker();
|
||||
final Locale locale = Locale.ROOT;
|
||||
checker.setLocaleCountry(locale.getCountry());
|
||||
checker.setLocaleLanguage(locale.getLanguage());
|
||||
checker.setModuleClassLoader(Thread.currentThread().getContextClassLoader());
|
||||
checker.configure(checkerConfig);
|
||||
checker.addListener(new BriefUtLogger(stream));
|
||||
|
||||
final String pathToEmptyFile = temporaryFolder.newFile("file.java").getPath();
|
||||
final String[] expected = ArrayUtils.EMPTY_STRING_ARRAY;
|
||||
|
||||
verify(checker, pathToEmptyFile, pathToEmptyFile, expected);
|
||||
// one more time to reuse cache
|
||||
verify(checker, pathToEmptyFile, pathToEmptyFile, expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCacheFileChangeInConfig() throws Exception {
|
||||
final DefaultConfiguration checkConfig = createCheckConfig(HiddenFieldCheck.class);
|
||||
|
||||
final DefaultConfiguration treeWalkerConfig = createCheckConfig(TreeWalker.class);
|
||||
treeWalkerConfig.addAttribute("cacheFile", temporaryFolder.newFile().getPath());
|
||||
treeWalkerConfig.addChild(checkConfig);
|
||||
|
||||
final DefaultConfiguration checkerConfig = new DefaultConfiguration("configuration");
|
||||
checkerConfig.addAttribute("charset", "UTF-8");
|
||||
checkerConfig.addChild(treeWalkerConfig);
|
||||
|
||||
final Checker checker = new Checker();
|
||||
final Locale locale = Locale.ROOT;
|
||||
checker.setLocaleCountry(locale.getCountry());
|
||||
checker.setLocaleLanguage(locale.getLanguage());
|
||||
checker.setModuleClassLoader(Thread.currentThread().getContextClassLoader());
|
||||
checker.configure(checkerConfig);
|
||||
checker.addListener(new BriefUtLogger(stream));
|
||||
|
||||
final String pathToEmptyFile = temporaryFolder.newFile("file.java").getPath();
|
||||
final String[] expected = ArrayUtils.EMPTY_STRING_ARRAY;
|
||||
|
||||
verify(checker, pathToEmptyFile, pathToEmptyFile, expected);
|
||||
|
||||
// update Checker config
|
||||
//checker.destroy();
|
||||
//checker.configure(checkerConfig);
|
||||
|
||||
final Checker otherChecker = new Checker();
|
||||
otherChecker.setLocaleCountry(locale.getCountry());
|
||||
otherChecker.setLocaleLanguage(locale.getLanguage());
|
||||
otherChecker.setModuleClassLoader(Thread.currentThread().getContextClassLoader());
|
||||
otherChecker.configure(checkerConfig);
|
||||
otherChecker.addListener(new BriefUtLogger(stream));
|
||||
// here is diff with previous checker
|
||||
checkerConfig.addAttribute("fileExtensions", "java,javax");
|
||||
|
||||
// one more time on updated config
|
||||
verify(otherChecker, pathToEmptyFile, pathToEmptyFile, expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testForInvalidCheckImplementation() throws Exception {
|
||||
final DefaultConfiguration checkConfig = createCheckConfig(BadJavaDocCheck.class);
|
||||
|
|
@ -273,7 +150,6 @@ public class TreeWalkerTest extends BaseCheckTestSupport {
|
|||
final TreeWalker treeWalker = new TreeWalker();
|
||||
treeWalker.setTabWidth(1);
|
||||
treeWalker.configure(new DefaultConfiguration("default config"));
|
||||
treeWalker.setCacheFile(temporaryFolder.newFile().getPath());
|
||||
final File file = new File("src/main/resources/checkstyle_packages.xml");
|
||||
treeWalker.processFiltered(file, new ArrayList<String>());
|
||||
}
|
||||
|
|
@ -285,7 +161,6 @@ public class TreeWalkerTest extends BaseCheckTestSupport {
|
|||
final PackageObjectFactory factory = new PackageObjectFactory(
|
||||
new HashSet<String>(), Thread.currentThread().getContextClassLoader());
|
||||
treeWalker.setModuleFactory(factory);
|
||||
treeWalker.setCacheFile(temporaryFolder.newFile().getPath());
|
||||
treeWalker.setupChild(createCheckConfig(TypeNameCheck.class));
|
||||
final File file = temporaryFolder.newFile("file.java");
|
||||
final List<String> lines = new ArrayList<>();
|
||||
|
|
@ -300,7 +175,6 @@ public class TreeWalkerTest extends BaseCheckTestSupport {
|
|||
final PackageObjectFactory factory = new PackageObjectFactory(
|
||||
new HashSet<String>(), Thread.currentThread().getContextClassLoader());
|
||||
treeWalker.setModuleFactory(factory);
|
||||
treeWalker.setCacheFile(temporaryFolder.newFile().getPath());
|
||||
treeWalker.setupChild(createCheckConfig(TypeNameCheck.class));
|
||||
final File file = temporaryFolder.newFile("file.java");
|
||||
final List<String> lines = new ArrayList<>();
|
||||
|
|
@ -322,7 +196,6 @@ public class TreeWalkerTest extends BaseCheckTestSupport {
|
|||
final PackageObjectFactory factory = new PackageObjectFactory(
|
||||
new HashSet<String>(), Thread.currentThread().getContextClassLoader());
|
||||
treeWalker.setModuleFactory(factory);
|
||||
treeWalker.setCacheFile(temporaryFolder.newFile().getPath());
|
||||
treeWalker.setupChild(createCheckConfig(TypeNameCheck.class));
|
||||
final File file = temporaryFolder.newFile("file.java");
|
||||
final List<String> lines = new ArrayList<>();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,38 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// checkstyle: Checks Java source code for adherence to a set of rules.
|
||||
// Copyright (C) 2001-2016 the original author or authors.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
package com.puppycrawl.tools.checkstyle.api;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.puppycrawl.tools.checkstyle.Definitions;
|
||||
|
||||
public class LocalizedMessagesTest {
|
||||
@Test
|
||||
public void testSize() {
|
||||
// Just to satisfy code coverage
|
||||
final LocalizedMessages messages = new LocalizedMessages();
|
||||
messages.add(new LocalizedMessage(0,
|
||||
Definitions.CHECKSTYLE_BUNDLE, "general.exception",
|
||||
new String[] {"args"}, null, getClass(),
|
||||
null));
|
||||
Assert.assertEquals(1, messages.size());
|
||||
}
|
||||
}
|
||||
|
|
@ -297,6 +297,13 @@
|
|||
<td><a href="property_types.html#string">string</a></td>
|
||||
<td><code>null</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>cacheFile</td>
|
||||
<td>caches information about files that have checked OK; used
|
||||
to avoid repeated checks of the same files</td>
|
||||
<td><a href="property_types.html#string">string</a></td>
|
||||
<td><code>null</code> (no cache file)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>localeCountry</td>
|
||||
<td>locale country for messages</td>
|
||||
|
|
@ -327,13 +334,14 @@
|
|||
|
||||
<p>
|
||||
For example, the following configuration fragment specifies base
|
||||
directory <code>src/checkstyle</code> and German
|
||||
directory <code>src/checkstyle</code>, cache file <code>target/cachefile</code> and German
|
||||
locale for all modules:
|
||||
</p>
|
||||
|
||||
<source>
|
||||
<module name="Checker">
|
||||
<property name="basedir" value="src/checkstyle"/>
|
||||
<property name="cacheFile" value="target/cachefile"/>
|
||||
<property name="localeCountry" value="DE"/>
|
||||
<property name="localeLanguage" value="de"/>
|
||||
<module name="JavadocPackage"/>
|
||||
|
|
@ -403,13 +411,6 @@
|
|||
<th>type</th>
|
||||
<th>default value</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>cacheFile</td>
|
||||
<td>caches information about files that have checked OK; used
|
||||
to avoid repeated checks of the same files</td>
|
||||
<td><a href="property_types.html#string">string</a></td>
|
||||
<td><code>null</code> (no cache file)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>tabWidth</td>
|
||||
<td>number of expanded spaces for a tab character (<code>'\t'</code>); used in messages and Checks that
|
||||
|
|
@ -431,13 +432,12 @@
|
|||
|
||||
<p>
|
||||
For example, the following configuration fragment specifies
|
||||
<code>TreeWalker</code> cache file <code>target/cachefile</code>, and a <code>tabWidth</code> of <code>4</code>:
|
||||
<code>TreeWalker</code> a <code>tabWidth</code> of <code>4</code>:
|
||||
</p>
|
||||
|
||||
<source>
|
||||
<module name="Checker">
|
||||
<module name="TreeWalker">
|
||||
<property name="cacheFile" value="target/cachefile"/>
|
||||
<property name="tabWidth" value="4"/>
|
||||
...
|
||||
</module>
|
||||
|
|
|
|||
Loading…
Reference in New Issue