001/* 002 * SPDX-FileCopyrightText: none 003 * SPDX-License-Identifier: CC0-1.0 004 */ 005 006package gov.nist.secauto.metaschema.databind.io.yaml; 007 008import gov.nist.secauto.metaschema.core.util.ObjectUtils; 009 010import org.json.JSONException; 011import org.json.JSONObject; 012import org.yaml.snakeyaml.DumperOptions; 013import org.yaml.snakeyaml.LoaderOptions; 014import org.yaml.snakeyaml.Yaml; 015import org.yaml.snakeyaml.constructor.Constructor; 016import org.yaml.snakeyaml.nodes.Tag; 017import org.yaml.snakeyaml.representer.Representer; 018import org.yaml.snakeyaml.resolver.Resolver; 019 020import java.io.BufferedInputStream; 021import java.io.IOException; 022import java.net.URI; 023import java.util.Map; 024 025import edu.umd.cs.findbugs.annotations.NonNull; 026 027public final class YamlOperations { 028 private static final Yaml YAML_PARSER; 029 030 static { 031 LoaderOptions loaderOptions = new LoaderOptions(); 032 loaderOptions.setCodePointLimit(Integer.MAX_VALUE - 1); // 2GB 033 Constructor constructor = new Constructor(loaderOptions); 034 DumperOptions dumperOptions = new DumperOptions(); 035 Representer representer = new Representer(dumperOptions); 036 YAML_PARSER = new Yaml(constructor, representer, dumperOptions, loaderOptions, new Resolver() { 037 @Override 038 protected void addImplicitResolvers() { 039 addImplicitResolver(Tag.BOOL, BOOL, "yYnNtTfFoO"); 040 addImplicitResolver(Tag.INT, INT, "-+0123456789"); 041 addImplicitResolver(Tag.FLOAT, FLOAT, "-+0123456789."); 042 addImplicitResolver(Tag.MERGE, MERGE, "<"); 043 addImplicitResolver(Tag.NULL, NULL, "~nN\0"); 044 addImplicitResolver(Tag.NULL, EMPTY, null); 045 // addImplicitResolver(Tag.TIMESTAMP, TIMESTAMP, "0123456789"); 046 } 047 }); 048 } 049 050 private YamlOperations() { 051 // disable construction 052 } 053 054 /** 055 * Parse the data represented in YAML in the provided {@code target}, producing 056 * an mapping of field names to Java object values. 057 * 058 * @param target 059 * the YAML file to parse 060 * @return the mapping of field names to Java object values 061 * @throws IOException 062 * if an error occurred while parsing the YAML content 063 */ 064 @SuppressWarnings({ "unchecked", "null" }) 065 @NonNull 066 public static Map<String, Object> parseYaml(URI target) throws IOException { 067 try (BufferedInputStream is = new BufferedInputStream(ObjectUtils.notNull(target.toURL().openStream()))) { 068 return (Map<String, Object>) YAML_PARSER.load(is); 069 } 070 } 071 072 /** 073 * Converts the provided YAML {@code map} into JSON. 074 * 075 * @param map 076 * the YAML map 077 * @return the JSON object 078 * @throws JSONException 079 * if an error occurred while building the JSON tree 080 */ 081 public static JSONObject yamlToJson(@NonNull Map<String, Object> map) { 082 return new JSONObject(map); 083 } 084}