diff --git a/src/main/java/com/puppycrawl/tools/checkstyle/Checker.java b/src/main/java/com/puppycrawl/tools/checkstyle/Checker.java index 31f66e852..b633e0527 100644 --- a/src/main/java/com/puppycrawl/tools/checkstyle/Checker.java +++ b/src/main/java/com/puppycrawl/tools/checkstyle/Checker.java @@ -562,7 +562,7 @@ public class Checker extends AutomaticBean implements MessageDispatcher { */ public void clearCache() { if (cache != null) { - cache.clear(); + cache.reset(); } } } diff --git a/src/main/java/com/puppycrawl/tools/checkstyle/PropertyCacheFile.java b/src/main/java/com/puppycrawl/tools/checkstyle/PropertyCacheFile.java index 8b4dc1ebe..4d998f308 100644 --- a/src/main/java/com/puppycrawl/tools/checkstyle/PropertyCacheFile.java +++ b/src/main/java/com/puppycrawl/tools/checkstyle/PropertyCacheFile.java @@ -68,7 +68,7 @@ final class PropertyCacheFile { * checked the key is chosen in such a way that it cannot be a * valid file name. */ - private static final String CONFIG_HASH_KEY = "configuration*?"; + public static final String CONFIG_HASH_KEY = "configuration*?"; /** Size of buffer which is used to read external configuration resources. */ private static final int BUFFER_SIZE = 1024; @@ -82,6 +82,9 @@ final class PropertyCacheFile { /** File name of cache. **/ private final String fileName; + /** Generated configuration hash. **/ + private String configHash; + /** * Creates a new {@code PropertyCacheFile} instance. * @@ -106,17 +109,16 @@ final class PropertyCacheFile { public void load() throws IOException { // get the current config so if the file isn't found // the first time the hash will be added to output file - final String currentConfigHash = getHashCodeBasedOnObjectContent(config); + configHash = getHashCodeBasedOnObjectContent(config); if (new File(fileName).exists()) { FileInputStream inStream = null; try { inStream = new FileInputStream(fileName); details.load(inStream); final String cachedConfigHash = details.getProperty(CONFIG_HASH_KEY); - if (!currentConfigHash.equals(cachedConfigHash)) { + if (!configHash.equals(cachedConfigHash)) { // Detected configuration change - clear cache - details.clear(); - details.setProperty(CONFIG_HASH_KEY, currentConfigHash); + reset(); } } finally { @@ -125,7 +127,7 @@ final class PropertyCacheFile { } else { // put the hash in the file if the file is going to be created - details.setProperty(CONFIG_HASH_KEY, currentConfigHash); + reset(); } } @@ -149,10 +151,11 @@ final class PropertyCacheFile { } /** - * Clears the cache. + * Resets the cache to be empty except for the configuration hash. */ - public void clear() { + public void reset() { details.clear(); + details.setProperty(CONFIG_HASH_KEY, configHash); } /** @@ -188,6 +191,15 @@ final class PropertyCacheFile { details.setProperty(checkedFileName, Long.toString(timestamp)); } + /** + * Retrieves the hash of a specific file. + * @param name The name of the file to retrieve. + * @return The has of the file or {@code null}. + */ + public String get(String name) { + return details.getProperty(name); + } + /** * Calculates the hashcode for the serializable object based on its content. * @param object serializable object. @@ -230,7 +242,7 @@ final class PropertyCacheFile { public void putExternalResources(Set locations) { final Set resources = loadExternalResources(locations); if (areExternalResourcesChanged(resources)) { - details.clear(); + reset(); } fillCacheWithExternalResources(resources); } diff --git a/src/test/java/com/puppycrawl/tools/checkstyle/PropertyCacheFileTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/PropertyCacheFileTest.java index 8a0282e1a..d450a8634 100644 --- a/src/test/java/com/puppycrawl/tools/checkstyle/PropertyCacheFileTest.java +++ b/src/test/java/com/puppycrawl/tools/checkstyle/PropertyCacheFileTest.java @@ -21,13 +21,13 @@ package com.puppycrawl.tools.checkstyle; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import static org.powermock.api.mockito.PowerMockito.mockStatic; import static org.powermock.api.mockito.PowerMockito.when; import java.io.File; -import java.io.FileNotFoundException; import java.io.IOException; import java.io.Serializable; import java.lang.reflect.InvocationTargetException; @@ -36,7 +36,9 @@ import java.nio.file.Files; import java.nio.file.Paths; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; +import java.util.HashSet; import java.util.Locale; +import java.util.Set; import org.junit.Rule; import org.junit.Test; @@ -82,18 +84,55 @@ public class PropertyCacheFileTest { assertFalse(cache.isInCache("myFile1", 1)); } + @Test + public void testConfigHashOnReset() throws IOException { + final Configuration config = new DefaultConfiguration("myName"); + final String filePath = temporaryFolder.newFile().getPath(); + final PropertyCacheFile cache = new PropertyCacheFile(config, filePath); + + cache.load(); + + final String hash = cache.get(PropertyCacheFile.CONFIG_HASH_KEY); + assertNotNull(hash); + + cache.reset(); + + assertEquals(hash, cache.get(PropertyCacheFile.CONFIG_HASH_KEY)); + } + + @Test + public void testConfigHashRemainsOnResetExternalResources() throws IOException { + final Configuration config = new DefaultConfiguration("myName"); + final String filePath = temporaryFolder.newFile().getPath(); + final PropertyCacheFile cache = new PropertyCacheFile(config, filePath); + + // create cache with one file + cache.load(); + cache.put("myFile", 1); + + final String hash = cache.get(PropertyCacheFile.CONFIG_HASH_KEY); + assertNotNull(hash); + + // apply new external resource to clear cache + final Set resources = new HashSet<>(); + resources.add("dummy"); + cache.putExternalResources(resources); + + assertEquals(hash, cache.get(PropertyCacheFile.CONFIG_HASH_KEY)); + assertFalse(cache.isInCache("myFile", 1)); + } + @Test public void testCacheDirectoryDoesNotExistAndShouldBeCreated() throws IOException { final Configuration config = new DefaultConfiguration("myName"); final String filePath = String.format(Locale.getDefault(), "%s%2$stemp%2$scache.temp", temporaryFolder.getRoot(), File.separator); final PropertyCacheFile cache = new PropertyCacheFile(config, filePath); - try { - cache.persist(); - } - catch (FileNotFoundException ex) { - fail("Exception is not expected. Cache directory should be created successfully!"); - } + + // no exception expected, cache directory should be created + cache.persist(); + + assertTrue("cache exists in directory", new File(filePath).exists()); } @Test @@ -102,12 +141,8 @@ public class PropertyCacheFileTest { final String filePath = "temp.cache"; final PropertyCacheFile cache = new PropertyCacheFile(config, filePath); - try { - cache.persist(); - } - catch (FileNotFoundException ex) { - fail("Exception is not expected!"); - } + // no exception expected + cache.persist(); if (Files.exists(Paths.get(filePath))) { Files.delete(Paths.get(filePath));