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