You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by ah...@apache.org on 2022/12/13 10:47:22 UTC

[isis] branch master updated: ISIS-3304: promote Yaml utils from internal to public

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 ffffa1adfa ISIS-3304: promote Yaml utils from internal to public
ffffa1adfa is described below

commit ffffa1adfae59a8e2b9fdb5a7c4be7e2469df10e
Author: Andi Huber <ah...@apache.org>
AuthorDate: Tue Dec 13 11:47:14 2022 +0100

    ISIS-3304: promote Yaml utils from internal to public
---
 .../causeway/commons/internal/resources/_Yaml.java | 168 ---------------------
 .../org/apache/causeway/commons/io/YamlUtils.java  | 123 +++++++++++++++
 .../internal/resources/JsonYamlReaderTest.java     |   7 +-
 .../secman/applib/util/ApplicationSecurityDto.java |   4 +-
 .../org/apache/causeway/tooling/cli/CliConfig.java |   5 +-
 .../causeway/tooling/cli/test/CliConfigTest.java   |  10 +-
 6 files changed, 139 insertions(+), 178 deletions(-)

diff --git a/commons/src/main/java/org/apache/causeway/commons/internal/resources/_Yaml.java b/commons/src/main/java/org/apache/causeway/commons/internal/resources/_Yaml.java
deleted file mode 100644
index a7a9bf52ff..0000000000
--- a/commons/src/main/java/org/apache/causeway/commons/internal/resources/_Yaml.java
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-package org.apache.causeway.commons.internal.resources;
-
-import java.io.ByteArrayInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.StringWriter;
-import java.util.Optional;
-import java.util.function.UnaryOperator;
-
-import org.springframework.lang.Nullable;
-import org.yaml.snakeyaml.DumperOptions;
-import org.yaml.snakeyaml.DumperOptions.LineBreak;
-import org.yaml.snakeyaml.Yaml;
-import org.yaml.snakeyaml.constructor.Constructor;
-
-import org.apache.causeway.commons.functional.Try;
-
-import lombok.SneakyThrows;
-import lombok.val;
-
-/**
- * <h1>- internal use only -</h1>
- * <p>
- * Utilities for the YAML format.
- * </p>
- * <p>
- * <b>WARNING</b>: Do <b>NOT</b> use any of the classes provided by this package! <br/>
- * These may be changed or removed without notice!
- * </p>
- * @since 2.0
- */
-public class _Yaml {
-
-    // -- FROM INPUT STREAM
-
-    private static <T> T _readYaml(final Class<T> clazz, final InputStream content) {
-        val yaml = new Yaml(new Constructor(clazz));
-        return yaml.load(content);
-    }
-
-    /**
-     * Either deserialize YAML content from given YAML content InputStream into an instance of
-     * given {@code clazz} type, or any exception that occurred during parsing.
-     * @param <T>
-     * @param clazz
-     * @param content
-     */
-    public static <T> Try<T> readYaml(final Class<T> clazz, final InputStream content) {
-        return Try.call(()->_readYaml(clazz, content));
-    }
-
-    // -- FROM STRING
-
-    private static <T> T _readYaml(final Class<T> clazz, final String content) {
-        val yaml = new Yaml(new Constructor(clazz));
-        return yaml.load(content);
-    }
-
-    /**
-     * Either deserialize YAML content from given YAML content String into an instance of
-     * given {@code clazz} type, or any exception that occurred during parsing.
-     * @param <T>
-     * @param clazz
-     * @param content
-     */
-    public static <T> Try<T> readYaml(final Class<T> clazz, final String content) {
-        return Try.call(()->_readYaml(clazz, content));
-    }
-
-    // -- FROM FILE
-
-    private static <T> T _readYaml(final Class<T> clazz, final File content) throws FileNotFoundException, IOException {
-        try(val fis = new FileInputStream(content)) {
-            val yaml = new Yaml(new Constructor(clazz));
-            return yaml.load(fis);
-        }
-    }
-
-    /**
-     * Either deserialize YAML content from given YAML content File into an instance of
-     * given {@code clazz} type, or any exception that occurred during parsing.
-     * @param <T>
-     * @param clazz
-     * @param content
-     */
-    public static <T> Try<T> readYaml(final Class<T> clazz, final File content) {
-        return Try.call(()->_readYaml(clazz, content));
-    }
-
-    // -- FROM BYTE ARRAY
-
-    private static <T> T _readYaml(final Class<T> clazz, final byte[] content) throws IOException {
-        try(val bais = new ByteArrayInputStream(content)) {
-            val yaml = new Yaml(new Constructor(clazz));
-            return yaml.load(bais);
-        }
-    }
-
-    /**
-     * Either deserialize YAML content from given YAML content byte[] into an instance of
-     * given {@code clazz} type, or any exception that occurred during parsing.
-     * @param <T>
-     * @param clazz
-     * @param content
-     */
-    public static <T> Try<T> readYaml(final Class<T> clazz, final byte[] content) {
-        return Try.call(()->_readYaml(clazz, content));
-    }
-
-    // -- WRITING
-
-    public static Try<String> toString(
-            final @Nullable Object pojo) {
-        return Try.call(()->_toString(pojo, null));
-    }
-
-    public static Try<String> toString(
-            final @Nullable Object pojo,
-            final @Nullable UnaryOperator<DumperOptions> customizer) {
-        return Try.call(()->_toString(pojo, customizer));
-    }
-
-    @SneakyThrows
-    private static String _toString(
-            final @Nullable Object pojo,
-            final @Nullable UnaryOperator<DumperOptions> customizer) {
-        if(pojo==null) {
-            return "";
-        }
-        try(val writer = new StringWriter()){
-            val defaultOptions = new DumperOptions();
-            defaultOptions.setIndent(2);
-            defaultOptions.setLineBreak(LineBreak.UNIX); // fixated for consistency
-            //options.setPrettyFlow(true);
-            //options.setDefaultFlowStyle(FlowStyle.BLOCK);
-
-            val options = Optional.ofNullable(customizer)
-            .map(f->f.apply(defaultOptions))
-            .orElse(defaultOptions);
-
-            val yaml = new Yaml(options);
-            yaml.dump(pojo, writer);
-            return writer.toString();
-        }
-    }
-
-}
diff --git a/commons/src/main/java/org/apache/causeway/commons/io/YamlUtils.java b/commons/src/main/java/org/apache/causeway/commons/io/YamlUtils.java
new file mode 100644
index 0000000000..7985385679
--- /dev/null
+++ b/commons/src/main/java/org/apache/causeway/commons/io/YamlUtils.java
@@ -0,0 +1,123 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.causeway.commons.io;
+
+import java.io.InputStream;
+import java.io.OutputStreamWriter;
+import java.util.Optional;
+import java.util.function.UnaryOperator;
+
+import org.springframework.lang.Nullable;
+import org.yaml.snakeyaml.DumperOptions;
+import org.yaml.snakeyaml.DumperOptions.LineBreak;
+import org.yaml.snakeyaml.Yaml;
+import org.yaml.snakeyaml.constructor.Constructor;
+
+import org.apache.causeway.commons.functional.Try;
+
+import lombok.NonNull;
+import lombok.SneakyThrows;
+import lombok.experimental.UtilityClass;
+
+/**
+ * Utilities to convert from and to YAML format.
+ *
+ * @since 2.0 {@index}
+ */
+@UtilityClass
+public class YamlUtils {
+
+    @FunctionalInterface
+    public interface YamlCustomizer extends UnaryOperator<DumperOptions> {}
+
+    // -- READING
+
+    /**
+     * Tries to deserialize YAML content from given UTF8 encoded {@link String}
+     * into an instance of given {@code mappedType}.
+     */
+    public <T> Try<T> tryRead(
+            final @NonNull Class<T> mappedType,
+            final @Nullable String stringUtf8) {
+        return tryRead(mappedType, DataSource.ofStringUtf8(stringUtf8));
+    }
+
+    /**
+     * Tries to deserialize YAML content from given {@link DataSource} into an instance of
+     * given {@code requiredType}.
+     */
+    public <T> Try<T> tryRead(
+            final @NonNull Class<T> mappedType,
+            final @NonNull DataSource source) {
+        return source.readAll((final InputStream is)->{
+            return Try.call(()->createMapper(mappedType).load(is));
+        });
+    }
+
+    // -- WRITING
+
+    /**
+     * Writes given {@code pojo} to given {@link DataSink}.
+     */
+    public void write(
+            final @Nullable Object pojo,
+            final @NonNull DataSink sink,
+            final YamlUtils.YamlCustomizer ... customizers) {
+        if(pojo==null) return;
+        sink.writeAll(os->
+            Try.run(()->createMapper(pojo.getClass(), customizers).dump(pojo, new OutputStreamWriter(os))));
+    }
+
+    /**
+     * Converts given {@code pojo} to an UTF8 encoded {@link String}.
+     * @return <code>null</code> if pojo is <code>null</code>
+     */
+    @SneakyThrows
+    @Nullable
+    public static String toStringUtf8(
+            final @Nullable Object pojo,
+            final YamlUtils.YamlCustomizer ... customizers) {
+        return pojo!=null
+                ? createMapper(pojo.getClass(), customizers).dump(pojo)
+                : null;
+    }
+
+
+    // -- CUSTOMIZERS
+
+
+    // -- MAPPER FACTORY
+
+    private Yaml createMapper(
+            final Class<?> mappedType,
+            final YamlUtils.YamlCustomizer ... customizers) {
+        var mapper = new Yaml(new Constructor(mappedType));
+        var options = new DumperOptions();
+        options.setIndent(2);
+        options.setLineBreak(LineBreak.UNIX); // fixated for consistency
+        //options.setPrettyFlow(true);
+        //options.setDefaultFlowStyle(FlowStyle.BLOCK);
+        for(YamlUtils.YamlCustomizer customizer : customizers) {
+            options = Optional.ofNullable(customizer.apply(options))
+                    .orElse(options);
+        }
+        return mapper;
+    }
+
+}
diff --git a/commons/src/test/java/org/apache/causeway/commons/internal/resources/JsonYamlReaderTest.java b/commons/src/test/java/org/apache/causeway/commons/internal/resources/JsonYamlReaderTest.java
index ff8143c708..ebd60b6c71 100644
--- a/commons/src/test/java/org/apache/causeway/commons/internal/resources/JsonYamlReaderTest.java
+++ b/commons/src/test/java/org/apache/causeway/commons/internal/resources/JsonYamlReaderTest.java
@@ -32,6 +32,7 @@ import static org.junit.jupiter.api.Assertions.assertNotNull;
 
 import org.apache.causeway.commons.io.DataSource;
 import org.apache.causeway.commons.io.JsonUtils;
+import org.apache.causeway.commons.io.YamlUtils;
 
 import lombok.Data;
 import lombok.val;
@@ -64,8 +65,10 @@ class JsonYamlReaderTest {
 
     @Test
     void loadCustomerFromYaml() {
-        val customer = _Yaml.readYaml(Customer.class, this.getClass().getResourceAsStream("customer.yml"))
-                .getValue().orElse(null);
+        val customer = YamlUtils.tryRead(Customer.class, DataSource.ofResource(this.getClass(), "customer.yml"))
+                .ifFailureFail()
+                .getValue()
+                .orElse(null);
         assertCustomerIsJohnDoe(customer);
     }
 
diff --git a/extensions/security/secman/applib/src/main/java/org/apache/causeway/extensions/secman/applib/util/ApplicationSecurityDto.java b/extensions/security/secman/applib/src/main/java/org/apache/causeway/extensions/secman/applib/util/ApplicationSecurityDto.java
index 0d2f944ad8..abf0b82cc5 100644
--- a/extensions/security/secman/applib/src/main/java/org/apache/causeway/extensions/secman/applib/util/ApplicationSecurityDto.java
+++ b/extensions/security/secman/applib/src/main/java/org/apache/causeway/extensions/secman/applib/util/ApplicationSecurityDto.java
@@ -22,7 +22,7 @@ import java.util.ArrayList;
 import java.util.List;
 
 import org.apache.causeway.applib.services.appfeat.ApplicationFeatureSort;
-import org.apache.causeway.commons.internal.resources._Yaml;
+import org.apache.causeway.commons.io.YamlUtils;
 import org.apache.causeway.extensions.secman.applib.permission.dom.ApplicationPermission;
 import org.apache.causeway.extensions.secman.applib.permission.dom.ApplicationPermissionMode;
 import org.apache.causeway.extensions.secman.applib.permission.dom.ApplicationPermissionRule;
@@ -117,7 +117,7 @@ public class ApplicationSecurityDto {
     private List<UserDto> users = new ArrayList<>();
 
     public String toYaml() {
-        return _Yaml.toString(this).getValue().orElseThrow();
+        return YamlUtils.toStringUtf8(this);
     }
 
 }
diff --git a/tooling/cli/src/main/java/org/apache/causeway/tooling/cli/CliConfig.java b/tooling/cli/src/main/java/org/apache/causeway/tooling/cli/CliConfig.java
index b53402bdfb..427adc455e 100644
--- a/tooling/cli/src/main/java/org/apache/causeway/tooling/cli/CliConfig.java
+++ b/tooling/cli/src/main/java/org/apache/causeway/tooling/cli/CliConfig.java
@@ -24,7 +24,8 @@ import java.util.Optional;
 
 import org.yaml.snakeyaml.constructor.ConstructorException;
 
-import org.apache.causeway.commons.internal.resources._Yaml;
+import org.apache.causeway.commons.io.DataSource;
+import org.apache.causeway.commons.io.YamlUtils;
 import org.apache.causeway.tooling.j2adoc.format.UnitFormatter;
 import org.apache.causeway.tooling.j2adoc.format.UnitFormatterCompact;
 import org.apache.causeway.tooling.j2adoc.format.UnitFormatterWithSourceAndCallouts;
@@ -130,7 +131,7 @@ public class CliConfig {
     // -- LOADING
 
     public static CliConfig read(final @NonNull File file) {
-        return _Yaml.readYaml(CliConfig.class, file)
+        return YamlUtils.tryRead(CliConfig.class, DataSource.ofFile(file))
         .ifFailure(e->{
             if(e instanceof ConstructorException) {
                 final ConstructorException ce = (ConstructorException) e;
diff --git a/tooling/cli/src/test/java/org/apache/causeway/tooling/cli/test/CliConfigTest.java b/tooling/cli/src/test/java/org/apache/causeway/tooling/cli/test/CliConfigTest.java
index 6044738197..6f749a0848 100644
--- a/tooling/cli/src/test/java/org/apache/causeway/tooling/cli/test/CliConfigTest.java
+++ b/tooling/cli/src/test/java/org/apache/causeway/tooling/cli/test/CliConfigTest.java
@@ -26,7 +26,8 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertNotNull;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
-import org.apache.causeway.commons.internal.resources._Yaml;
+import org.apache.causeway.commons.io.DataSource;
+import org.apache.causeway.commons.io.YamlUtils;
 import org.apache.causeway.tooling.cli.CliConfig;
 
 import lombok.val;
@@ -43,15 +44,16 @@ class CliConfigTest {
 
     @Test
     void loadConfigFromYaml() {
-        val config = _Yaml.readYaml(CliConfig.class, this.getClass().getResourceAsStream("causeway-tooling.yml"))
+        val config = YamlUtils.tryRead(CliConfig.class, DataSource.ofResource(this.getClass(), "causeway-tooling.yml"))
                 .ifFailure(System.err::println)
-                .getValue().orElse(null);
+                .getValue()
+                .orElse(null);
         assertConfigIsPopulated(config);
     }
 
     // -- HELPER
 
-    private void assertConfigIsPopulated(CliConfig config) {
+    private void assertConfigIsPopulated(final CliConfig config) {
         assertNotNull(config);
         assertNotNull(config.getGlobal());
         assertNotNull(config.getCommands().getOverview());