001/* 002 * SPDX-License-Identifier: Apache-2.0 003 * 004 * Copyright 2024-2026 The Enola <https://enola.dev> Authors 005 * 006 * Licensed under the Apache License, Version 2.0 (the "License"); 007 * you may not use this file except in compliance with the License. 008 * You may obtain a copy of the License at 009 * 010 * https://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package dev.enola.common.yamljson; 019 020import dev.enola.common.io.resource.ReadableResource; 021import dev.enola.common.io.resource.WritableResource; 022 023import org.snakeyaml.engine.v2.api.Dump; 024import org.snakeyaml.engine.v2.api.DumpSettings; 025import org.snakeyaml.engine.v2.api.Load; 026import org.snakeyaml.engine.v2.api.LoadSettings; 027import org.snakeyaml.engine.v2.common.ScalarStyle; 028 029import java.io.IOException; 030import java.util.Map; 031import java.util.function.Consumer; 032 033/** 034 * YAML Utility. 035 * 036 * @deprecated Consider using the (newer) {@code 037 * dev.enola.common.io.object.jackson.YamlObjectReaderWriter} and/or {@code 038 * dev.enola.common.jackson.ObjectMappers} instead. 039 */ 040@Deprecated 041public final class YAML { 042 043 private YAML() {} 044 045 private static Load newLoad() { 046 // NB: No need for new SafeConstructor(), here; because that's 047 // for org.yaml.snakeyaml, whereas this is for org.snakeyaml.engine. 048 var loadSettings = LoadSettings.builder(); 049 // NB: Keep in-sync with similar (but not same, different API!) in 050 // dev.enola.common.jackson.ObjectMappers 051 loadSettings.setAllowDuplicateKeys(false); 052 loadSettings.setAllowRecursiveKeys(false); 053 loadSettings.setCodePointLimit(10 * 1024 * 1024); // 10 MB 054 return new Load(loadSettings.build()); 055 } 056 057 private static Map<?, ?> iterable2singleMap(Iterable<?> iterable) { 058 var iterator = iterable.iterator(); 059 if (!iterator.hasNext()) return Map.of(); 060 var root = iterator.next(); 061 if (root instanceof Map<?, ?> map) { 062 if (iterator.hasNext()) 063 throw new IllegalArgumentException("YAML with multiple --- documents"); 064 return map; 065 } else throw new IllegalArgumentException("YAML document is not Map"); 066 } 067 068 @Deprecated 069 public static Iterable<?> read(String yaml) { 070 return newLoad().loadAllFromString(yaml); 071 } 072 073 @Deprecated 074 public static Map<?, ?> readSingleMap(String yaml) { 075 return iterable2singleMap(read(yaml)); 076 } 077 078 @Deprecated 079 public static void read(ReadableResource yaml, Consumer<Iterable> itery) throws IOException { 080 try (var is = yaml.byteSource().openBufferedStream()) { 081 itery.accept(newLoad().loadAllFromInputStream(is)); 082 } 083 } 084 085 @Deprecated 086 public static void readSingleMap(ReadableResource yaml, Consumer<Map<?, ?>> mappy) 087 throws IOException { 088 read(yaml, iterable -> mappy.accept(iterable2singleMap(iterable))); 089 } 090 091 @Deprecated 092 public static String write(Object object) { 093 DumpSettings settings = 094 DumpSettings.builder().setDefaultScalarStyle(ScalarStyle.PLAIN).build(); 095 Dump dump = new Dump(settings); 096 return dump.dumpToString(object); 097 } 098 099 @Deprecated 100 public static void write(Object object, WritableResource yaml) throws IOException { 101 yaml.charSink().write(write(object)); 102 } 103}