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);