You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@causeway.apache.org by ah...@apache.org on 2023/03/29 09:30:13 UTC
[causeway] branch master updated: CAUSEWAY-3404: [Commons] adds data-source mapping and unzip/first
This is an automated email from the ASF dual-hosted git repository.
ahuber pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/causeway.git
The following commit(s) were added to refs/heads/master by this push:
new 77842600b5 CAUSEWAY-3404: [Commons] adds data-source mapping and unzip/first
77842600b5 is described below
commit 77842600b5ddf5d302e4ac7dd7632fce13f78de0
Author: Andi Huber <ah...@apache.org>
AuthorDate: Wed Mar 29 11:30:07 2023 +0200
CAUSEWAY-3404: [Commons] adds data-source mapping and unzip/first
---
.../org/apache/causeway/applib/value/Blob.java | 3 +-
.../commons/internal/collections/_Lists.java | 14 ++++++++
.../org/apache/causeway/commons/io/DataSource.java | 16 +++++++++
.../org/apache/causeway/commons/io/ZipUtils.java | 40 ++++++++++++++++++++++
.../apache/causeway/commons/io/ZipUtilsTest.java | 12 +++++--
5 files changed, 81 insertions(+), 4 deletions(-)
diff --git a/api/applib/src/main/java/org/apache/causeway/applib/value/Blob.java b/api/applib/src/main/java/org/apache/causeway/applib/value/Blob.java
index 4a90aae5cb..1740c52390 100644
--- a/api/applib/src/main/java/org/apache/causeway/applib/value/Blob.java
+++ b/api/applib/src/main/java/org/apache/causeway/applib/value/Blob.java
@@ -254,12 +254,11 @@ public final class Blob implements NamedWithMimeType {
}
public Blob unZip(final @NonNull CommonMimeType resultingMimeType) {
- return ZipUtils.streamZipEntries(asDataSource())
+ return ZipUtils.firstZipEntry(asDataSource()) // assuming first entry is the one we want
.map(zipEntryDataSource->Blob.of(
zipEntryDataSource.zipEntry().getName(),
resultingMimeType,
zipEntryDataSource.bytes()))
- .findFirst() // assuming first entry is the one we want
.orElseThrow(()->_Exceptions
.unrecoverable("failed to unzip blob, no entry found %s", getName()));
}
diff --git a/commons/src/main/java/org/apache/causeway/commons/internal/collections/_Lists.java b/commons/src/main/java/org/apache/causeway/commons/internal/collections/_Lists.java
index d9100d003b..897f1e5903 100644
--- a/commons/src/main/java/org/apache/causeway/commons/internal/collections/_Lists.java
+++ b/commons/src/main/java/org/apache/causeway/commons/internal/collections/_Lists.java
@@ -57,6 +57,20 @@ public final class _Lists {
// -- LIST ACCESS
+ public static <T> T firstElementIfAny(final @Nullable List<T> list) {
+ if(_NullSafe.isEmpty(list)) {
+ return null;
+ }
+ return list.get(0);
+ }
+
+ public static <T> Optional<T> firstElement(final @Nullable List<T> list) {
+ if(_NullSafe.isEmpty(list)) {
+ return Optional.empty();
+ }
+ return Optional.ofNullable(list.get(0));
+ }
+
public static <T> T lastElementIfAny(final @Nullable List<T> list) {
if(_NullSafe.isEmpty(list)) {
return null;
diff --git a/commons/src/main/java/org/apache/causeway/commons/io/DataSource.java b/commons/src/main/java/org/apache/causeway/commons/io/DataSource.java
index 0350ff10ac..8c60cabb4c 100644
--- a/commons/src/main/java/org/apache/causeway/commons/io/DataSource.java
+++ b/commons/src/main/java/org/apache/causeway/commons/io/DataSource.java
@@ -160,6 +160,22 @@ public interface DataSource {
.asHexString();
}
+ // -- MAP
+
+ /**
+ * Returns a new {@link DataSource} that maps the {@link InputStream} of this {@link DataSource} to another
+ * through means of applying given unary operator {@code inputStreamMapper}.
+ * (eg the decode or encode the originating input stream)
+ */
+ default DataSource map(final @NonNull ThrowingFunction<InputStream, InputStream> inputStreamMapper) {
+ val self = this;
+ return new DataSource() {
+ @Override public <T> Try<T> tryReadAll(final @NonNull Function<InputStream, Try<T>> consumingMapper) {
+ return self.tryReadAll(is->consumingMapper.apply(inputStreamMapper.apply(is)));
+ }
+ };
+ }
+
// -- PIPE
/**
diff --git a/commons/src/main/java/org/apache/causeway/commons/io/ZipUtils.java b/commons/src/main/java/org/apache/causeway/commons/io/ZipUtils.java
index 2d264b6864..9eae8351e2 100644
--- a/commons/src/main/java/org/apache/causeway/commons/io/ZipUtils.java
+++ b/commons/src/main/java/org/apache/causeway/commons/io/ZipUtils.java
@@ -25,6 +25,7 @@ import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
+import java.util.Optional;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Stream;
@@ -163,6 +164,45 @@ public class ZipUtils {
return streamZipEntries(zippedSource, ZipOptions.builder().build());
}
+ /**
+ * Optionally the first zip-entry as {@link ZipEntryDataSource}, based on whether an entry exists.
+ */
+ public Optional<ZipEntryDataSource> firstZipEntry(
+ final @NonNull DataSource zippedSource,
+ final @NonNull ZipOptions zipOptions) {
+
+ val zipEntryDataSources = _Lists.<ZipEntryDataSource>newArrayList(1);
+
+ zippedSource.tryReadAndAccept(is->{
+ try(final ZipInputStream in = new ZipInputStream(
+ new BufferedInputStream(is, zipOptions.bufferSize()),
+ zipOptions.zipEntryCharset())) {
+
+ ZipEntry zipEntry;
+ while((zipEntry = in.getNextEntry())!=null) {
+ if(zipEntry.isDirectory()) continue;
+ if(zipOptions.zipEntryFilter().test(zipEntry)) {
+ zipEntryDataSources.add(
+ new ZipEntryDataSource(zipEntry, _Bytes.ofKeepOpen(in)));
+ return; // stop further processing
+ }
+ }
+ }
+ })
+ .ifFailureFail();
+
+ return _Lists.firstElement(zipEntryDataSources);
+ }
+
+ /**
+ * Shortcut for {@code firstZipEntry(zippedSource, ZipOptions.builder().build())}
+ * @see #firstZipEntry(DataSource, ZipOptions)
+ */
+ public Optional<ZipEntryDataSource> firstZipEntry(
+ final @NonNull DataSource zippedSource) {
+ return firstZipEntry(zippedSource, ZipOptions.builder().build());
+ }
+
// -- WRITING
public static byte[] zipToBytes(final @NonNull Stream<ZipEntryDataSource> entryStream) {
diff --git a/commons/src/test/java/org/apache/causeway/commons/io/ZipUtilsTest.java b/commons/src/test/java/org/apache/causeway/commons/io/ZipUtilsTest.java
index c32bf5bbfd..20d7d25a87 100644
--- a/commons/src/test/java/org/apache/causeway/commons/io/ZipUtilsTest.java
+++ b/commons/src/test/java/org/apache/causeway/commons/io/ZipUtilsTest.java
@@ -41,7 +41,8 @@ class ZipUtilsTest {
@Test
void zipUnzipRountrip() throws Exception {
- assertArrayEquals(bytes, unZip(zip(bytes)));
+ assertArrayEquals(bytes, unZip_usingStream(zip(bytes)));
+ assertArrayEquals(bytes, unZip_usingOptional(zip(bytes)));
}
// -- HELPER
@@ -53,11 +54,18 @@ class ZipUtilsTest {
}
@SneakyThrows
- private static byte[] unZip(final byte[] zipped) {
+ private static byte[] unZip_usingStream(final byte[] zipped) {
return ZipUtils.streamZipEntries(DataSource.ofBytes(zipped))
.findFirst()
.map(entry->entry.bytes())
.orElseGet(()->new byte[0]);
}
+ @SneakyThrows
+ private static byte[] unZip_usingOptional(final byte[] zipped) {
+ return ZipUtils.firstZipEntry(DataSource.ofBytes(zipped))
+ .map(entry->entry.bytes())
+ .orElseGet(()->new byte[0]);
+ }
+
}