From c96bd9f8f7584da107fc7d90db53cdadf3d792f5 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Sun, 4 Aug 2019 13:59:13 +0200 Subject: [PATCH] [platform] improves Compressor filter API once again (IDEA-CR-50030) GitOrigin-RevId: d24e3f67ffa88856365c0fb60acfcb040a4bab1e --- .../src/ExportSettingsAction.kt | 2 +- .../src/com/intellij/util/io/Compressor.java | 61 +++++++++---------- .../com/intellij/util/io/CompressorTest.kt | 2 +- .../src/build/PrepareToDeployAction.java | 4 +- 4 files changed, 32 insertions(+), 37 deletions(-) diff --git a/platform/configuration-store-impl/src/ExportSettingsAction.kt b/platform/configuration-store-impl/src/ExportSettingsAction.kt index 17bf48d15d0f..dfd88e691dda 100644 --- a/platform/configuration-store-impl/src/ExportSettingsAction.kt +++ b/platform/configuration-store-impl/src/ExportSettingsAction.kt @@ -101,7 +101,7 @@ open class ExportSettingsAction : AnAction(), DumbAware { fun exportSettings(exportFiles: Set, out: OutputStream, configPath: String) { val filter = THashSet() - Compressor.Zip(out).filter { path, isDir -> isDir || filter.add(path) }.use { zip -> + Compressor.Zip(out).filter { entryName, _ -> filter.add(entryName) }.use { zip -> for (file in exportFiles) { val fileInfo = file.basicAttributesIfExists() ?: continue val relativePath = FileUtil.getRelativePath(configPath, file.toAbsolutePath().systemIndependentPath, '/')!! diff --git a/platform/util/src/com/intellij/util/io/Compressor.java b/platform/util/src/com/intellij/util/io/Compressor.java index 11e627413356..7d0055f4b477 100644 --- a/platform/util/src/com/intellij/util/io/Compressor.java +++ b/platform/util/src/com/intellij/util/io/Compressor.java @@ -132,26 +132,34 @@ public abstract class Compressor implements Closeable { } } - private BiPredicate myFilter = null; + private BiPredicate myFilter = null; /** @deprecated use {@link #filter(BiPredicate)} instead */ @Deprecated @ApiStatus.ScheduledForRemoval(inVersion = "2020.1") public Compressor filter(@Nullable Condition filter) { - return filter(filter != null ? (entryName, isDirectory) -> filter.value(entryName) : null); + myFilter = filter == null ? null : (entryName, file) -> { + int p = -1; + while ((p = entryName.indexOf('/', p + 1)) > 0) { + if (!filter.value(entryName.substring(0, p))) return false; + } + return filter.value(entryName); + }; + return this; } - public Compressor filter(@Nullable BiPredicate filter) { + /** + * Allows filtering entries being added to the archive. + * Please note that the second parameter of a filter ({@code File}) could be {@code null} when the filter is applied + * to an entry not present on a disk - e.g. via {@link #addFile(String, byte[])}. + */ + public Compressor filter(@Nullable BiPredicate filter) { myFilter = filter; return this; } public final void addFile(@NotNull String entryName, @NotNull File file) throws IOException { - addFile(entryName(entryName), file, true); - } - - private void addFile(String entryName, File file, boolean checkParents) throws IOException { - if (accepts(entryName, Boolean.FALSE, checkParents)) { + if (accepts(entryName, file)) { try (InputStream source = new FileInputStream(file)) { writeFileEntry(entryName, source, file.length(), file.lastModified()); } @@ -164,7 +172,7 @@ public abstract class Compressor implements Closeable { public final void addFile(@NotNull String entryName, @NotNull byte[] content, long timestamp) throws IOException { entryName = entryName(entryName); - if (accepts(entryName, Boolean.FALSE, true)) { + if (accepts(entryName, null)) { writeFileEntry(entryName, new ByteArrayInputStream(content), content.length, timestamp(timestamp)); } } @@ -175,7 +183,7 @@ public abstract class Compressor implements Closeable { public final void addFile(@NotNull String entryName, @NotNull InputStream content, long timestamp) throws IOException { entryName = entryName(entryName); - if (accepts(entryName, Boolean.FALSE, true)) { + if (accepts(entryName, null)) { writeFileEntry(entryName, content, -1, timestamp(timestamp)); } } @@ -186,7 +194,7 @@ public abstract class Compressor implements Closeable { public final void addDirectory(@NotNull String entryName, long timestamp) throws IOException { entryName = entryName(entryName); - if (accepts(entryName, Boolean.TRUE, true)) { + if (accepts(entryName, null)) { writeDirectoryEntry(entryName, timestamp(timestamp)); } } @@ -196,10 +204,7 @@ public abstract class Compressor implements Closeable { } public final void addDirectory(@NotNull String prefix, @NotNull File directory) throws IOException { - prefix = entryName(prefix); - if (accepts(prefix, Boolean.TRUE, true)) { - addRecursively(prefix, directory); - } + addRecursively(entryName(prefix), directory); } // @@ -215,27 +220,17 @@ public abstract class Compressor implements Closeable { return timestamp == -1 ? System.currentTimeMillis() : timestamp; } - private boolean accepts(String entryName, Boolean isDirectory, boolean checkParents) { - if (myFilter == null) return true; - if (checkParents) { - int p = -1; - while ((p = entryName.indexOf('/', p + 1)) > 0) { - if (!myFilter.test(entryName.substring(0, p), Boolean.TRUE)) { - return false; - } - } - } - return myFilter.test(entryName, isDirectory); + private boolean accepts(String entryName, @Nullable File file) { + return myFilter == null || myFilter.test(entryName, file); } private void addRecursively(String prefix, File directory) throws IOException { + if (!accepts(prefix, directory)) { + return; + } + if (!prefix.isEmpty()) { - if (!accepts(prefix, Boolean.TRUE, false)) { - return; - } - else { - writeDirectoryEntry(prefix, directory.lastModified()); - } + writeDirectoryEntry(prefix, directory.lastModified()); } File[] children = directory.listFiles(); @@ -246,7 +241,7 @@ public abstract class Compressor implements Closeable { addRecursively(name, child); } else { - addFile(name, child, false); + addFile(name, child); } } } diff --git a/platform/util/testSrc/com/intellij/util/io/CompressorTest.kt b/platform/util/testSrc/com/intellij/util/io/CompressorTest.kt index 22e16cbe8dad..c2f4f184ad59 100644 --- a/platform/util/testSrc/com/intellij/util/io/CompressorTest.kt +++ b/platform/util/testSrc/com/intellij/util/io/CompressorTest.kt @@ -30,7 +30,7 @@ class CompressorTest { @Test fun simpleZipWithFilters() { val zip = tempDir.newFile("test.zip") val set = mutableSetOf() - Compressor.Zip(zip).filter { entryName, _ -> set.add(entryName) && entryName != "d1" }.use { + Compressor.Zip(zip).filter { entryName, _ -> set.add(entryName) && !entryName.startsWith("d1/") }.use { it.addFile("file1.txt", "123".toByteArray()) it.addFile("file2.txt", "456".toByteArray()) it.addFile("file1.txt", "789".toByteArray()) diff --git a/plugins/devkit/devkit-core/src/build/PrepareToDeployAction.java b/plugins/devkit/devkit-core/src/build/PrepareToDeployAction.java index c751c5c4251c..0169ae72bb17 100644 --- a/plugins/devkit/devkit-core/src/build/PrepareToDeployAction.java +++ b/plugins/devkit/devkit-core/src/build/PrepareToDeployAction.java @@ -242,7 +242,7 @@ public class PrepareToDeployAction extends AnAction { try { try (Compressor tempZip = new Compressor.Zip(tempFile)) { FileTypeManager manager = FileTypeManager.getInstance(); - tempZip.filter((entryName, isDir) -> !manager.isFileIgnored(PathUtil.getFileName(entryName))); + tempZip.filter((entryName, file) -> !manager.isFileIgnored(PathUtil.getFileName(entryName))); tempZip.addDirectory(VfsUtilCore.virtualToIoFile(root)); } String jarName = getLibraryJarName(root.getName() + JAR_EXTENSION, usedJarNames, preferredName == null ? null : preferredName + JAR_EXTENSION); @@ -288,7 +288,7 @@ public class PrepareToDeployAction extends AnAction { try (Compressor.Jar jar = new Compressor.Jar(tempFile)) { FileTypeManager manager = FileTypeManager.getInstance(); Set uniqueEntries = new HashSet<>(); - jar.filter((entryName, isDir) -> isDir || !manager.isFileIgnored(PathUtil.getFileName(entryName)) && uniqueEntries.add(entryName)); + jar.filter((entryName, file) -> !manager.isFileIgnored(PathUtil.getFileName(entryName)) && uniqueEntries.add(entryName)); if (manifest != null) { jar.addManifest(manifest);