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/isis.git
The following commit(s) were added to refs/heads/master by this push:
new e0d5938510 ISIS-3300: support file i/o for Blob and Clob (convenience)
e0d5938510 is described below
commit e0d59385101b09d1c452c2124a29eca9ef0a98b0
Author: Andi Huber <[email protected]>
AuthorDate: Thu Dec 1 18:41:23 2022 +0100
ISIS-3300: support file i/o for Blob and Clob (convenience)
---
.../org/apache/causeway/applib/value/Blob.java | 56 ++++++++++++++++++++--
.../org/apache/causeway/applib/value/Clob.java | 54 +++++++++++++++++++++
.../domainmodel/MetaModelRegressionTest.java | 18 +++----
3 files changed, 113 insertions(+), 15 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 2acada6c29..794df8b10c 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
@@ -20,6 +20,9 @@ package org.apache.causeway.applib.value;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
@@ -36,11 +39,14 @@ import javax.inject.Named;
import javax.xml.bind.annotation.adapters.XmlAdapter;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
+import org.springframework.lang.Nullable;
+
import org.apache.causeway.applib.CausewayModuleApplib;
import org.apache.causeway.applib.annotation.Value;
import org.apache.causeway.applib.jaxb.PrimitiveJaxbAdapters;
import org.apache.causeway.applib.util.ZipReader;
import org.apache.causeway.applib.util.ZipWriter;
+import org.apache.causeway.commons.functional.Try;
import org.apache.causeway.commons.internal.base._Bytes;
import org.apache.causeway.commons.internal.base._Strings;
import org.apache.causeway.commons.internal.exceptions._Exceptions;
@@ -113,6 +119,28 @@ public final class Blob implements NamedWithMimeType {
return new Blob(fileName, mimeType.getMimeType(), content);
}
+ /**
+ * Returns a new {@link Blob} of given {@code name}, {@code mimeType} and
content from {@code file},
+ * wrapped with a {@link Try}.
+ * <p>
+ * {@code name} may or may not include the desired filename extension, it
+ * is guaranteed, that the resulting {@link Blob} has the appropriate
extension
+ * as constraint by the given {@code mimeType}.
+ * <p>
+ * For more fine-grained control use one of the {@link Blob} constructors
directly.
+ * @param name - may or may not include the desired filename extension
+ * @param mimeType
+ * @param file - the file to be opened for reading
+ * @return new {@link Blob}
+ */
+ public static Try<Blob> tryRead(final String name, final CommonMimeType
mimeType, final File file) {
+ return Try.call(()->{
+ try(val fis = new FileInputStream(file)){
+ return Blob.of(name, mimeType, _Bytes.ofKeepOpen(fis));
+ }
+ });
+ }
+
// --
private final MimeType mimeType;
@@ -167,10 +195,9 @@ public final class Blob implements NamedWithMimeType {
/**
* Does not close the OutputStream.
- * @param os
- * @throws IOException
*/
- public void writeBytesTo(final OutputStream os) throws IOException {
+ @SneakyThrows
+ public void writeBytesTo(final @Nullable OutputStream os) {
if(os==null) {
return;
}
@@ -179,12 +206,33 @@ public final class Blob implements NamedWithMimeType {
}
}
+ /**
+ * Writes this {@link Blob} to the file represented by
+ * the specified <code>File</code> object.
+ * <p>
+ * If the file exists but is a directory rather than a regular file, does
+ * not exist but cannot be created, or cannot be opened for any other
+ * reason then a <code>FileNotFoundException</code> is thrown.
+ *
+ * @param file the file to be opened for writing; if
<code>null</code> this method does nothing
+ * @see java.io.FileOutputStream
+ */
+ @SneakyThrows
+ public void writeTo(final @Nullable File file) {
+ if(file==null) {
+ return; // just ignore
+ }
+ try(val os = new FileOutputStream(file)){
+ writeBytesTo(os);
+ }
+ }
+
/**
* The {@link InputStream} involved is closed after consumption.
* @param consumer
* @throws IOException
*/
- public void consume(final Consumer<InputStream> consumer) throws
IOException {
+ public void consume(final @NonNull Consumer<InputStream> consumer) throws
IOException {
// null to empty
val bytes = Optional.ofNullable(getBytes())
.orElse(new byte[0]);
diff --git
a/api/applib/src/main/java/org/apache/causeway/applib/value/Clob.java
b/api/applib/src/main/java/org/apache/causeway/applib/value/Clob.java
index 80a047ab76..5e7cb3f9d7 100644
--- a/api/applib/src/main/java/org/apache/causeway/applib/value/Clob.java
+++ b/api/applib/src/main/java/org/apache/causeway/applib/value/Clob.java
@@ -18,7 +18,11 @@
*/
package org.apache.causeway.applib.value;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
import java.io.IOException;
+import java.io.OutputStreamWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.nio.charset.Charset;
@@ -31,9 +35,12 @@ import javax.inject.Named;
import javax.xml.bind.annotation.adapters.XmlAdapter;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
+import org.springframework.lang.Nullable;
+
import org.apache.causeway.applib.CausewayModuleApplib;
import org.apache.causeway.applib.annotation.Value;
import org.apache.causeway.applib.jaxb.PrimitiveJaxbAdapters;
+import org.apache.causeway.commons.functional.Try;
import org.apache.causeway.commons.internal.base._Strings;
import lombok.NonNull;
@@ -107,6 +114,30 @@ public final class Clob implements NamedWithMimeType {
return new Clob(fileName, mimeType.getMimeType(), content);
}
+ /**
+ * Returns a new {@link Clob} of given {@code name}, {@code mimeType} and
content from {@code file},
+ * wrapped with a {@link Try}.
+ * <p>
+ * {@code name} may or may not include the desired filename extension, it
+ * is guaranteed, that the resulting {@link Clob} has the appropriate
extension
+ * as constraint by the given {@code mimeType}.
+ * <p>
+ * For more fine-grained control use one of the {@link Clob} constructors
directly.
+ * @param name - may or may not include the desired filename extension
+ * @param mimeType
+ * @param file - the file to be opened for reading
+ * @param charset - {@link Charset} to use for reading given file
+ * @return new {@link Clob}
+ */
+ public static Try<Clob> tryRead(final String name, final CommonMimeType
mimeType, final File file,
+ final @NonNull Charset charset) {
+ return Try.call(()->{
+ try(val fis = new FileInputStream(file)){
+ return Clob.of(name, mimeType, _Strings.read(fis, charset));
+ }
+ });
+ }
+
// --
public Clob(final String name, final String primaryType, final String
subType, final char[] chars) {
@@ -173,6 +204,29 @@ public final class Clob implements NamedWithMimeType {
}
}
+ /**
+ * Writes this {@link Clob} to the file represented by
+ * the specified <code>File</code> object.
+ * <p>
+ * If the file exists but is a directory rather than a regular file, does
+ * not exist but cannot be created, or cannot be opened for any other
+ * reason then a <code>FileNotFoundException</code> is thrown.
+ *
+ * @param file the file to be opened for writing; if
<code>null</code> this method does nothing
+ * @param charset - {@link Charset} to use for writing to given file
+ * @see java.io.FileOutputStream
+ * @see java.io.OutputStreamWriter
+ */
+ @SneakyThrows
+ public void writeTo(final @Nullable File file, final @NonNull Charset
charset) {
+ if(file==null) {
+ return; // just ignore
+ }
+ try(val os = new FileOutputStream(file)){
+ writeCharsTo(new OutputStreamWriter(os, StandardCharsets.UTF_8));
+ }
+ }
+
@SneakyThrows
public String asString() {
val sw = new StringWriter();
diff --git
a/regressiontests/stable-domainmodel/src/test/java/org/apache/causeway/testdomain/domainmodel/MetaModelRegressionTest.java
b/regressiontests/stable-domainmodel/src/test/java/org/apache/causeway/testdomain/domainmodel/MetaModelRegressionTest.java
index 609c515296..90a9ef0825 100644
---
a/regressiontests/stable-domainmodel/src/test/java/org/apache/causeway/testdomain/domainmodel/MetaModelRegressionTest.java
+++
b/regressiontests/stable-domainmodel/src/test/java/org/apache/causeway/testdomain/domainmodel/MetaModelRegressionTest.java
@@ -18,7 +18,6 @@
*/
package org.apache.causeway.testdomain.domainmodel;
-import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.List;
@@ -44,7 +43,6 @@ import
org.apache.causeway.testdomain.conf.Configuration_headless;
import
org.apache.causeway.testdomain.model.good.Configuration_usingValidDomain;
import lombok.SneakyThrows;
-import lombok.val;
@SpringBootTest(
classes = {
@@ -81,17 +79,15 @@ class MetaModelRegressionTest {
// disable if rename, as the .zip file needs to be updated.
// Assumptions.assumeThat(getClass().getName()).contains("causeway");
- Blob metaModelZip =
factoryService.mixin(MetaModelServiceMenu.downloadMetaModelXml.class,
- metaModelServiceMenu).act("metamodel.xml", namespaces(), true);
- val xml = asXml(metaModelZip);
+ final Blob metaModelZip = factoryService
+ .mixin(MetaModelServiceMenu.downloadMetaModelXml.class,
metaModelServiceMenu)
+ .act("metamodel.xml", namespaces(), true);
+ final String xml = metaModelZip
+ .unZip(CommonMimeType.XML)
+ .toClob(StandardCharsets.UTF_8)
+ .asString();
Approvals.verify(xml, options());
-
- }
-
- private static String asXml(final Blob zip) throws IOException {
- val clob =
zip.unZip(CommonMimeType.XML).toClob(StandardCharsets.UTF_8);
- return clob.asString();
}
private Options options() {