001package com.mrivanplays.annotationconfig.core;
002
003import com.mrivanplays.annotationconfig.core.resolver.ConfigResolver;
004import com.mrivanplays.annotationconfig.core.resolver.MultilineString;
005import com.mrivanplays.annotationconfig.core.resolver.ValueReader;
006import com.mrivanplays.annotationconfig.core.resolver.ValueWriter;
007import com.mrivanplays.annotationconfig.core.resolver.options.CustomOptions;
008import com.mrivanplays.annotationconfig.core.resolver.settings.LoadSettings;
009import java.io.File;
010import java.io.IOException;
011import java.io.PrintWriter;
012import java.io.Reader;
013import java.util.LinkedHashMap;
014import java.util.List;
015import java.util.Map;
016import java.util.Properties;
017
018/**
019 * Represents configuration, utilising .conf/.properties configuration type.
020 *
021 * @since 1.0
022 * @author MrIvanPlays
023 */
024public final class PropertyConfig {
025
026  private static ConfigResolver configResolver;
027
028  /**
029   * Returns the {@link ConfigResolver} instance of PropertyConfig
030   *
031   * @return config resolver
032   */
033  public static ConfigResolver getConfigResolver() {
034    if (configResolver == null) {
035      generateConfigResolver();
036    }
037    return configResolver;
038  }
039
040  private static final ValueWriter PROPERTIES_VALUE_WRITER = new PropertyValueWriter();
041
042  private static void generateConfigResolver() {
043    configResolver =
044        ConfigResolver.newBuilder()
045            .withCommentPrefix("# ")
046            .withValueWriter(PROPERTIES_VALUE_WRITER)
047            .withValueReader(
048                new ValueReader() {
049                  @Override
050                  public Map<String, Object> read(Reader reader) throws IOException {
051                    Properties properties = new Properties();
052                    properties.load(reader);
053                    Map<String, Object> ret = new LinkedHashMap<>();
054                    for (Object key : properties.keySet()) {
055                      ret.put(String.valueOf(key), properties.get(key));
056                    }
057                    return ret;
058                  }
059                })
060            .build();
061  }
062
063  /**
064   * Loads the config object from the file. If the file does not exist, it creates one.
065   *
066   * @param annotatedConfig annotated config
067   * @param file file
068   * @deprecated use {@link #getConfigResolver()}. it has a much better description of methods. the
069   *     equivalent of this method there is {@link ConfigResolver#loadOrDump(Object, File,
070   *     LoadSettings)}
071   */
072  @Deprecated
073  public static void load(Object annotatedConfig, File file) {
074    getConfigResolver().loadOrDump(annotatedConfig, file);
075  }
076
077  private static final class PropertyValueWriter implements ValueWriter {
078
079    @Override
080    public void write(
081        Map<String, Object> values,
082        Map<String, List<String>> fieldComments,
083        PrintWriter writer,
084        CustomOptions options) {
085      int index = 0;
086      for (Map.Entry<String, Object> entry : values.entrySet()) {
087        if (entry.getValue() instanceof Map<?, ?>) {
088          throw new IllegalArgumentException(".properties does not support maps");
089        }
090        if (entry.getValue() instanceof List<?>) {
091          throw new IllegalArgumentException(".properties does not support lists");
092        }
093        if (fieldComments.containsKey(entry.getKey())) {
094          for (String comment : fieldComments.get(entry.getKey())) {
095            writer.println("# " + comment);
096          }
097        }
098        String toWrite;
099        if (entry.getValue() instanceof MultilineString) {
100          toWrite = ((MultilineString) entry.getValue()).getString();
101        } else {
102          toWrite = String.valueOf(entry.getValue());
103        }
104        writer.println(entry.getKey() + "=" + toWrite);
105        if ((index + 1) != values.size()) {
106          writer.append('\n');
107        }
108        index++;
109      }
110    }
111  }
112}