You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by bo...@apache.org on 2019/08/20 14:54:21 UTC

[commons-compress] branch master updated: COMPRESS-478 provide default names in line with 7z tools

This is an automated email from the ASF dual-hosted git repository.

bodewig pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-compress.git


The following commit(s) were added to refs/heads/master by this push:
     new 7897da7  COMPRESS-478 provide default names in line with 7z tools
7897da7 is described below

commit 7897da76152e44029b90698ff195c49e035f8c73
Author: Stefan Bodewig <bo...@apache.org>
AuthorDate: Tue Aug 20 16:53:51 2019 +0200

    COMPRESS-478 provide default names in line with 7z tools
---
 pom.xml                                            | 12 +++++++
 .../compress/archivers/sevenz/SevenZFile.java      | 39 +++++++++++++++++++---
 .../compress/archivers/sevenz/SevenZFileTest.java  | 18 ++++++++++
 3 files changed, 65 insertions(+), 4 deletions(-)

diff --git a/pom.xml b/pom.xml
index cecbedf..7b839ff 100644
--- a/pom.xml
+++ b/pom.xml
@@ -91,6 +91,18 @@ Brotli, Zstandard and ar, cpio, jar, tar, zip, dump, 7z, arj.
       <scope>test</scope>
     </dependency>
     <dependency>
+      <groupId>org.hamcrest</groupId>
+      <artifactId>hamcrest-library</artifactId>
+      <version>1.3</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.hamcrest</groupId>
+      <artifactId>hamcrest-core</artifactId>
+      <version>1.3</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
       <groupId>com.github.luben</groupId>
       <artifactId>zstd-jni</artifactId>
       <version>1.4.0-1</version>
diff --git a/src/main/java/org/apache/commons/compress/archivers/sevenz/SevenZFile.java b/src/main/java/org/apache/commons/compress/archivers/sevenz/SevenZFile.java
index 3580e6d..adcc023 100644
--- a/src/main/java/org/apache/commons/compress/archivers/sevenz/SevenZFile.java
+++ b/src/main/java/org/apache/commons/compress/archivers/sevenz/SevenZFile.java
@@ -83,6 +83,8 @@ import org.apache.commons.compress.utils.InputStreamStatistics;
 public class SevenZFile implements Closeable {
     static final int SIGNATURE_HEADER_SIZE = 32;
 
+    private static final String DEFAULT_FILE_NAME = "unknown archive";
+
     private final String fileName;
     private SeekableByteChannel channel;
     private final Archive archive;
@@ -190,7 +192,7 @@ public class SevenZFile implements Closeable {
      * @since 1.19
      */
     public SevenZFile(final SeekableByteChannel channel, final int maxMemoryLimitInKb) throws IOException {
-        this(channel, "unknown archive", (char[]) null, maxMemoryLimitInKb);
+        this(channel, DEFAULT_FILE_NAME, (char[]) null, maxMemoryLimitInKb);
     }
 
     /**
@@ -226,7 +228,7 @@ public class SevenZFile implements Closeable {
      */
     public SevenZFile(final SeekableByteChannel channel, final char[] password, final int maxMemoryLimitInKb)
             throws IOException {
-        this(channel, "unknown archive", utf16Decode(password), maxMemoryLimitInKb);
+        this(channel, DEFAULT_FILE_NAME, utf16Decode(password), maxMemoryLimitInKb);
     }
 
     /**
@@ -320,7 +322,7 @@ public class SevenZFile implements Closeable {
      */
     public SevenZFile(final SeekableByteChannel channel,
                       final byte[] password) throws IOException {
-        this(channel, "unknown archive", password);
+        this(channel, DEFAULT_FILE_NAME, password);
     }
 
     /**
@@ -342,7 +344,7 @@ public class SevenZFile implements Closeable {
      */
     public SevenZFile(final SeekableByteChannel channel, final byte[] password, final int maxMemoryLimitInKb)
             throws IOException {
-        this(channel, "unknown archive", password, maxMemoryLimitInKb);
+        this(channel, DEFAULT_FILE_NAME, password, maxMemoryLimitInKb);
     }
 
     /**
@@ -1378,6 +1380,35 @@ public class SevenZFile implements Closeable {
       return archive.toString();
     }
 
+    /**
+     * Derives a default file name from the archive name - if known.
+     *
+     * <p>This implements the same heuristics the 7z tools use. In
+     * 7z's case if an archive contains entries without a name -
+     * i.e. {@link SevenZArchiveEntry#getName} returns {@code null} -
+     * then its command line and GUI tools will use this default name
+     * when extracting the entries.</p>
+     *
+     * @return null if the name of the archive is unknown. Otherwise
+     * if the name of the archive has got any extension, it is
+     * stripped and the remainder returned. Finally if the name of the
+     * archive hasn't got any extension then a {@code ~} character is
+     * appended to the archive name.
+     *
+     * @since 1.19
+     */
+    public String getDefaultName() {
+        if (DEFAULT_FILE_NAME.equals(fileName) || fileName == null) {
+            return null;
+        }
+
+        final int dotPos = fileName.lastIndexOf(".");
+        if (dotPos > 0) { // if the file starts with a dot then this is not an extension
+            return fileName.substring(0, dotPos);
+        }
+        return fileName + "~";
+    }
+
     private static final CharsetEncoder PASSWORD_ENCODER = StandardCharsets.UTF_16LE.newEncoder();
 
     private static byte[] utf16Decode(char[] chars) throws IOException {
diff --git a/src/test/java/org/apache/commons/compress/archivers/sevenz/SevenZFileTest.java b/src/test/java/org/apache/commons/compress/archivers/sevenz/SevenZFileTest.java
index 4ce07ee..008aeba 100644
--- a/src/test/java/org/apache/commons/compress/archivers/sevenz/SevenZFileTest.java
+++ b/src/test/java/org/apache/commons/compress/archivers/sevenz/SevenZFileTest.java
@@ -18,11 +18,13 @@
 package org.apache.commons.compress.archivers.sevenz;
 
 import static org.junit.Assert.*;
+import static org.hamcrest.Matchers.endsWith;
 
 import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.IOException;
+import java.nio.file.Files;
 import java.security.NoSuchAlgorithmException;
 import java.util.Arrays;
 import java.util.HashMap;
@@ -311,6 +313,22 @@ public class SevenZFileTest extends AbstractTestCase {
         }
     }
 
+    @Test
+    public void getDefaultNameWorksAsExpected() throws Exception {
+        try (SevenZFile sevenZFile = new SevenZFile(getFile("bla.deflate64.7z"))) {
+            assertThat(sevenZFile.getDefaultName(), endsWith("bla.deflate64"));
+        }
+        try (SevenZFile sevenZFile = new SevenZFile(Files.newByteChannel(getFile("bla.deflate64.7z").toPath()))) {
+            assertNull(sevenZFile.getDefaultName());
+        }
+        try (SevenZFile sevenZFile = new SevenZFile(Files.newByteChannel(getFile("bla.deflate64.7z").toPath()), "foo")) {
+            assertEquals("foo~", sevenZFile.getDefaultName());
+        }
+        try (SevenZFile sevenZFile = new SevenZFile(Files.newByteChannel(getFile("bla.deflate64.7z").toPath()), ".foo")) {
+            assertEquals(".foo~", sevenZFile.getDefaultName());
+        }
+    }
+
     private void test7zUnarchive(final File f, final SevenZMethod m, final byte[] password) throws Exception {
         try (SevenZFile sevenZFile = new SevenZFile(f, password)) {
             test7zUnarchive(sevenZFile, m);