001/* 002 * SPDX-FileCopyrightText: none 003 * SPDX-License-Identifier: CC0-1.0 004 */ 005 006package dev.metaschema.databind.io; 007 008import java.util.Arrays; 009import java.util.HashSet; 010import java.util.List; 011import java.util.Locale; 012import java.util.Set; 013import java.util.stream.Collectors; 014 015import dev.metaschema.core.metapath.format.IPathFormatter; 016import dev.metaschema.core.metapath.format.PathFormatSelection; 017import dev.metaschema.core.util.CollectionUtil; 018import edu.umd.cs.findbugs.annotations.NonNull; 019import edu.umd.cs.findbugs.annotations.Nullable; 020import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; 021 022/** 023 * Selections of serialization formats. 024 */ 025public enum Format { 026 /** 027 * The <a href="https://www.w3.org/XML/">Extensible Markup Language</a> format. 028 */ 029 XML(".xml", Set.of()), 030 /** 031 * The <a href="https://www.json.org/">JavaScript Object Notation</a> format. 032 */ 033 JSON(".json", Set.of()), 034 /** 035 * The <a href="https://yaml.org/">YAML Ain't Markup Language</a> format. 036 */ 037 YAML(".yaml", Set.of(".yml")); 038 039 private static final List<String> NAMES; 040 041 @NonNull 042 private final String defaultExtension; 043 @NonNull 044 private final Set<String> recognizedExtensions; 045 046 static { 047 NAMES = Arrays.stream(values()) 048 .map(format -> format.name().toLowerCase(Locale.ROOT)) 049 .collect(Collectors.toUnmodifiableList()); 050 } 051 052 /** 053 * Get a list of all format names in lowercase. 054 * 055 * @return the list of names 056 */ 057 @SuppressFBWarnings(value = "MS_EXPOSE_REP", justification = "Exposes names provided by the enum") 058 public static List<String> names() { 059 return NAMES; 060 } 061 062 Format(@NonNull String defaultExtension, Set<String> otherExtensions) { 063 this.defaultExtension = defaultExtension; 064 065 Set<String> recognizedExtensions = new HashSet<>(); 066 recognizedExtensions.add(defaultExtension); 067 recognizedExtensions.addAll(otherExtensions); 068 069 this.recognizedExtensions = CollectionUtil.unmodifiableSet(recognizedExtensions); 070 } 071 072 /** 073 * Get the default extension to use for the format. 074 * 075 * @return the default extension 076 */ 077 @NonNull 078 public Set<String> getRecognizedExtensions() { 079 return recognizedExtensions; 080 } 081 082 /** 083 * Get the default extension to use for the format. 084 * 085 * @return the default extension 086 */ 087 @NonNull 088 public String getDefaultExtension() { 089 return defaultExtension; 090 } 091 092 /** 093 * Get the appropriate path formatter for this format. 094 * <p> 095 * Returns: 096 * <ul> 097 * <li>{@link IPathFormatter#XPATH_PATH_FORMATTER} for XML</li> 098 * <li>{@link IPathFormatter#JSON_POINTER_PATH_FORMATTER} for JSON and YAML</li> 099 * </ul> 100 * 101 * @return the path formatter appropriate for this format 102 */ 103 @NonNull 104 public IPathFormatter getPathFormatter() { 105 return this == XML 106 ? IPathFormatter.XPATH_PATH_FORMATTER 107 : IPathFormatter.JSON_POINTER_PATH_FORMATTER; 108 } 109 110 /** 111 * Resolve the path formatter based on the selection and document format. 112 * <p> 113 * When {@link PathFormatSelection#AUTO} is specified, the formatter is 114 * determined by the document format. For explicit selections, the corresponding 115 * formatter is returned regardless of document format. 116 * 117 * @param selection 118 * the path format selection 119 * @param format 120 * the document format, used when selection is AUTO; may be null 121 * @return the resolved path formatter 122 */ 123 @NonNull 124 public static IPathFormatter resolvePathFormatter( 125 @NonNull PathFormatSelection selection, 126 @Nullable Format format) { 127 switch (selection) { 128 case AUTO: 129 return format != null ? format.getPathFormatter() : IPathFormatter.METAPATH_PATH_FORMATER; 130 case METAPATH: 131 return IPathFormatter.METAPATH_PATH_FORMATER; 132 case XPATH: 133 return IPathFormatter.XPATH_PATH_FORMATTER; 134 case JSON_POINTER: 135 return IPathFormatter.JSON_POINTER_PATH_FORMATTER; 136 default: 137 return IPathFormatter.METAPATH_PATH_FORMATER; 138 } 139 } 140}