001package com.mrivanplays.annotationconfig.yaml; 002 003import com.mrivanplays.annotationconfig.core.resolver.ConfigResolver; 004import com.mrivanplays.annotationconfig.core.resolver.ValueReader; 005import com.mrivanplays.annotationconfig.core.resolver.ValueWriter; 006import com.mrivanplays.annotationconfig.core.resolver.options.CustomOptions; 007import com.mrivanplays.annotationconfig.core.resolver.settings.LoadSettings; 008import java.io.File; 009import java.io.PrintWriter; 010import java.io.Reader; 011import java.util.Collections; 012import java.util.LinkedHashMap; 013import java.util.List; 014import java.util.Map; 015import org.yaml.snakeyaml.Yaml; 016 017/** 018 * Represents configuration, utilising YAML 019 * 020 * @since 1.0 021 * @author MrIvanPlays 022 */ 023public final class YamlConfig { 024 025 private static final Yaml YAML = new Yaml(); 026 private static final ValueWriter VALUE_WRITER = new YamlValueWriter(); 027 028 private static ConfigResolver configResolver; 029 030 /** 031 * Returns the {@link ConfigResolver} instance of YamlConfig 032 * 033 * @return config resolver 034 */ 035 public static ConfigResolver getConfigResolver() { 036 if (configResolver == null) { 037 generateConfigResolver(); 038 } 039 return configResolver; 040 } 041 042 private static void generateConfigResolver() { 043 configResolver = 044 ConfigResolver.newBuilder() 045 .withValueWriter(VALUE_WRITER) 046 .shouldReverseFields(true) 047 .withCommentPrefix("# ") 048 .withValueReader( 049 new ValueReader() { 050 @Override 051 public Map<String, Object> read(Reader reader) { 052 Map<String, Object> values = YAML.loadAs(reader, LinkedHashMap.class); 053 if (values == null) { 054 return Collections.emptyMap(); 055 } 056 return values; 057 } 058 }) 059 .build(); 060 } 061 062 /** 063 * Loads the config object from the file. If the file does not exist, it creates one. 064 * 065 * @param annotatedConfig annotated config 066 * @param file file 067 * @deprecated use {@link #getConfigResolver()}. it has a much better description of methods. the 068 * equivalent of this method there is {@link ConfigResolver#loadOrDump(Object, File, 069 * LoadSettings)} 070 */ 071 @Deprecated 072 public static void load(Object annotatedConfig, File file) { 073 getConfigResolver().loadOrDump(annotatedConfig, file); 074 } 075 076 private static final class YamlValueWriter implements ValueWriter { 077 078 @Override 079 public void write( 080 String key, 081 Object value, 082 PrintWriter writer, 083 CustomOptions options, 084 boolean sectionExists) { 085 write(key, value, writer, 2, sectionExists); 086 } 087 088 private void write( 089 String key, Object value, PrintWriter writer, int childIndents, boolean sectionExists) { 090 StringBuilder intentPrefixBuilder = new StringBuilder(); 091 for (int i = 0; i < childIndents; i++) { 092 intentPrefixBuilder.append(" "); 093 } 094 String intentPrefix = intentPrefixBuilder.toString(); 095 if (value instanceof Map<?, ?>) { 096 if (!sectionExists) { 097 writer.println(key + ":"); 098 } 099 for (Map.Entry<String, Object> entry : ((Map<String, Object>) value).entrySet()) { 100 String mapKey = entry.getKey(); 101 Object v = entry.getValue(); 102 if (v instanceof List<?>) { 103 writer.println(intentPrefix + mapKey + ":"); 104 for (Object b : (List<?>) v) { 105 if (!(b instanceof String)) { 106 writer.println(intentPrefix + " - " + b); 107 } else { 108 writer.println(intentPrefix + " - \"" + b + "\""); 109 } 110 } 111 } else if (v instanceof Map<?, ?>) { 112 write(mapKey, v, writer, childIndents + 2, sectionExists); 113 } else { 114 if (!(v instanceof String)) { 115 writer.println(intentPrefix + mapKey + ": " + v); 116 } else { 117 writer.println(intentPrefix + mapKey + ": \"" + v + "\""); 118 } 119 } 120 } 121 } else if (value instanceof List<?>) { 122 writer.println(key + ":"); 123 for (Object b : (List<?>) value) { 124 if (!(b instanceof String)) { 125 writer.println(intentPrefix + "- " + b); 126 } else { 127 writer.println(intentPrefix + "- \"" + b + "\""); 128 } 129 } 130 } else { 131 if (!(value instanceof String)) { 132 writer.println(key + ": " + value); 133 } else { 134 writer.println(key + ": \"" + value + "\""); 135 } 136 } 137 writer.append('\n'); 138 } 139 } 140}