All Downloads are FREE. Search and download functionalities are using the official Maven repository.

dev.dejvokep.boostedyaml.settings.general.GeneralSettings Maven / Gradle / Ivy

/*
 * Copyright 2024 https://dejvokep.dev/
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package dev.dejvokep.boostedyaml.settings.general;

import dev.dejvokep.boostedyaml.YamlDocument;
import dev.dejvokep.boostedyaml.block.implementation.Section;
import dev.dejvokep.boostedyaml.route.Route;
import dev.dejvokep.boostedyaml.serialization.YamlSerializer;
import dev.dejvokep.boostedyaml.serialization.standard.StandardSerializer;
import dev.dejvokep.boostedyaml.settings.Settings;
import dev.dejvokep.boostedyaml.utils.supplier.ListSupplier;
import dev.dejvokep.boostedyaml.utils.supplier.MapSupplier;
import dev.dejvokep.boostedyaml.utils.supplier.SetSupplier;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.*;
import java.util.regex.Pattern;

/**
 * General settings cover all options related to documents in general.
 * 

* Settings introduced by BoostedYAML follow builder design pattern, e.g. you may build your own settings using * GeneralSettings.builder() //configure// .build() */ @SuppressWarnings("unused") public class GeneralSettings implements Settings { /** * Key format for sections to use; specifies how the loaded/supplied keys should be formatted. */ public enum KeyFormat { /** * Allows only strings as keys. *

    *
  • All keys loaded are converted to strings via {@link Object#toString()} (e.g. 5 -> "5"), except null keys, which are considered illegal and will throw a {@link NullPointerException}. Please note that such conversion is irrevocable upon saving.
  • *
  • String routes should only be used, as all keys are guaranteed to be strings. {@link Route Routes} can still be used, however, due to their capabilities, it is considered to be an overkill; all non-string keys supplied via those will internally be converted to strings (without modifying the route itself, they are immutable).
  • *
*

* This key format ensures compatibility with Spigot/BungeeCord APIs. */ STRING, /** * Allows anything as the key per the YAML specification (that is, integers, strings, doubles...). *

    *
  • Preserves keys as they were loaded by SnakeYAML Engine (YAML processor), or supplied.
  • *
  • Note that the only way to refer to data at routes that contain non-string keys is using {@link Route}. String routes can still be used, however, only to the extent of their limitations.
  • *
*/ OBJECT } /** * The default string route separator. */ public static final char DEFAULT_ROUTE_SEPARATOR = '.'; /** * Escaped version of the default separator. */ public static final String DEFAULT_ESCAPED_SEPARATOR = Pattern.quote(String.valueOf(DEFAULT_ROUTE_SEPARATOR)); /** * Default key format. */ public static final KeyFormat DEFAULT_KEY_FORMATTING = KeyFormat.STRING; /** * Default serializer. */ public static final YamlSerializer DEFAULT_SERIALIZER = StandardSerializer.getDefault(); /** * If to use defaults by default. */ public static final boolean DEFAULT_USE_DEFAULTS = true; /** * Default object. */ public static final Object DEFAULT_OBJECT = null; /** * Default number. */ public static final Number DEFAULT_NUMBER = 0; /** * Default string. */ public static final String DEFAULT_STRING = null; /** * Default char. */ public static final Character DEFAULT_CHAR = ' '; /** * Default boolean. */ public static final Boolean DEFAULT_BOOLEAN = false; /** * Default list supplier. */ public static final ListSupplier DEFAULT_LIST = ArrayList::new; /** * Default set supplier. */ public static final SetSupplier DEFAULT_SET = LinkedHashSet::new; /** * Default map supplier. */ public static final MapSupplier DEFAULT_MAP = LinkedHashMap::new; /** * Default general settings. */ public static final GeneralSettings DEFAULT = builder().build(); //Key format private final KeyFormat keyFormat; //Route separator private final char separator; //Escaped route separator private final String escapedSeparator; //Serializer private final YamlSerializer serializer; //Use defaults private final boolean useDefaults; //Default object private final Object defaultObject; //Default number private final Number defaultNumber; //Default string private final String defaultString; //Default char private final Character defaultChar; //Default boolean private final Boolean defaultBoolean; //Default list supplier private final ListSupplier defaultList; //Default set supplier private final SetSupplier defaultSet; //Default map supplier private final MapSupplier defaultMap; /** * Creates final, immutable general settings from the given builder. * * @param builder the builder */ private GeneralSettings(Builder builder) { this.keyFormat = builder.keyFormat; this.separator = builder.routeSeparator; this.escapedSeparator = Pattern.quote(String.valueOf(separator)); this.serializer = builder.serializer; this.defaultObject = builder.defaultObject; this.defaultNumber = builder.defaultNumber; this.defaultString = builder.defaultString; this.defaultChar = builder.defaultChar; this.defaultBoolean = builder.defaultBoolean; this.defaultList = builder.defaultList; this.defaultSet = builder.defaultSet; this.defaultMap = builder.defaultMap; this.useDefaults = builder.useDefaults; } /** * Returns the key format to use. * * @return the key format to use * @see Builder#setKeyFormat(KeyFormat) */ public KeyFormat getKeyFormat() { return keyFormat; } /** * Sets route separator used to separate individual keys inside a string route and vice-versa. * * @return separator the separator to use */ public char getRouteSeparator() { return separator; } /** * Returns the escaped route separator. * * @return the escaped route separator * @see #getRouteSeparator() */ public String getEscapedSeparator() { return escapedSeparator; } /** * Returns serializer to use for custom object serialization/deserialization. * * @return the serializer to use */ public YamlSerializer getSerializer() { return serializer; } /** * Returns if to enable use of the defaults by {@link Section} methods (if any are present). * * @return if to use defaults */ public boolean isUseDefaults() { return useDefaults; } /** * Returns default object to use by {@link Section} getters if the return type is object. * * @return the default object */ public Object getDefaultObject() { return defaultObject; } /** * Returns default string to use by {@link Section} getters if the return type is string. * * @return the default string */ public String getDefaultString() { return defaultString; } /** * Returns default char to use by {@link Section} getters if the return type is char. * * @return the default char */ public Character getDefaultChar() { return defaultChar; } /** * Returns default number to use by {@link Section} getters if the return type is a number - integer, float, byte, * biginteger... (per the getter documentation). * * @return the default number */ public Number getDefaultNumber() { return defaultNumber; } /** * Returns default boolean to use by {@link Section} getters if the return type is boolean. * * @return the default boolean */ public Boolean getDefaultBoolean() { return defaultBoolean; } /** * Returns default list of the given size. * * @param size initial size (if supported) * @param content type * @return the default list of the given size */ public List getDefaultList(int size) { return defaultList.supply(size); } /** * Returns an empty default list. * * @param content type * @return the empty default list */ public List getDefaultList() { return getDefaultList(0); } /** * Returns default set of the given size. * * @param size initial size (if supported) * @param content type * @return the default set of the given size */ public Set getDefaultSet(int size) { return defaultSet.supply(size); } /** * Returns an empty default set. * * @param content type * @return the empty default set */ public Set getDefaultSet() { return getDefaultSet(0); } /** * Returns default map of the given size. * * @param size initial size (if supported) * @param key type * @param value type * @return the default map of the given size */ public Map getDefaultMap(int size) { return defaultMap.supply(size); } /** * Returns an empty default map. * * @param key type * @param value type * @return the empty default map */ public Map getDefaultMap() { return getDefaultMap(0); } /** * Returns default map supplier to use to supply map instances during loading/creating new sections/when needed. * * @return the supplier */ public MapSupplier getDefaultMapSupplier() { return defaultMap; } /** * Returns a new builder. * * @return the new builder */ public static Builder builder() { return new Builder(); } /** * Returns a new builder with the same configuration as the given settings. * * @param settings preset settings * @return the new builder */ public static Builder builder(GeneralSettings settings) { return builder() .setKeyFormat(settings.keyFormat) .setRouteSeparator(settings.separator) .setSerializer(settings.serializer) .setUseDefaults(settings.useDefaults) .setDefaultObject(settings.defaultObject) .setDefaultNumber(settings.defaultNumber) .setDefaultString(settings.defaultString) .setDefaultChar(settings.defaultChar) .setDefaultBoolean(settings.defaultBoolean) .setDefaultList(settings.defaultList) .setDefaultSet(settings.defaultSet) .setDefaultMap(settings.defaultMap); } /** * Builder for general settings. */ public static class Builder { //Key format private KeyFormat keyFormat = DEFAULT_KEY_FORMATTING; //Route separator private char routeSeparator = DEFAULT_ROUTE_SEPARATOR; //Serializer private YamlSerializer serializer = DEFAULT_SERIALIZER; //Use defaults private boolean useDefaults = DEFAULT_USE_DEFAULTS; //Default object private Object defaultObject = DEFAULT_OBJECT; //Default number private Number defaultNumber = DEFAULT_NUMBER; //Default string private String defaultString = DEFAULT_STRING; //Default char private Character defaultChar = DEFAULT_CHAR; //Default boolean private Boolean defaultBoolean = DEFAULT_BOOLEAN; //Default list supplier private ListSupplier defaultList = DEFAULT_LIST; //Default set supplier private SetSupplier defaultSet = DEFAULT_SET; //Default map supplier private MapSupplier defaultMap = DEFAULT_MAP; /** * Creates a new builder will all the default settings applied. */ private Builder() { } /** * Sets the key format to use. *

* Default: {@link #DEFAULT_KEY_FORMATTING} * * @param keyFormat the key format to use * @return the builder * @see #setRouteSeparator(char) */ public Builder setKeyFormat(@NotNull KeyFormat keyFormat) { this.keyFormat = keyFormat; return this; } /** * Sets route separator used to separate individual keys inside a string route and vice-versa. *

* Default: {@link #DEFAULT_ROUTE_SEPARATOR} * * @param separator the separator to use * @return the builder */ public Builder setRouteSeparator(char separator) { this.routeSeparator = separator; return this; } /** * Sets serializer used for custom object serialization/deserialization. *

* Default: {@link #DEFAULT_SERIALIZER} * * @param serializer the serializer to use * @return the builder */ public Builder setSerializer(@NotNull YamlSerializer serializer) { this.serializer = serializer; return this; } /** * Sets if to enable use of the defaults by {@link Section} methods (if any are present). *

* Not effective if there are no {@link YamlDocument#getDefaults() defaults associated} with the document. *

* If enabled (true): *

    *
  • * Bulk getter methods (which return a set/map of all keys, routes, values, blocks) will not only include * content from the file, but also from the equivalent section in the defaults. *
  • *
  • * Value getters with signature getX(route) will search the defaults as documented. You can also view the behaviour in the * call stack below: *
      *
    1. * Is there any value at the specified route? *
        *
      • * 1A. Yes: Is it compatible with the return type (see method documentation)? *
          *
        • 2A. Yes: Return it.
        • *
        • * 2B. No: Is there an equivalent of this section in the defaults ({@link Section#hasDefaults()})? *
            *
          • * 3A. Yes: Return the value returned by calling the same method on the default section equivalent ({@link Section#getDefaults()}). *
          • *
          • * 3B. No: Return the default value defined by the settings (see method documentation). *
          • *
          *
        • *
        *
      • *
      • * 1B. No: Continue with 2B. *
      • *
      *
    2. *
    *
  • *
* If disabled (false): *
    *
  • * None of the {@link Section} methods will interact with the defaults. *
  • *
  • * This is recommended if you would like to handle all value absences (present in the defaults, but not * in the file) and invalid values manually - e.g. notifying the user and then using the default value defined within * final fields, or obtained via {@link Section#getDefaults()}. *
  • *
*

* Default: {@link #DEFAULT_USE_DEFAULTS} * * @param useDefaults if to use defaults * @return the builder */ public Builder setUseDefaults(boolean useDefaults) { this.useDefaults = useDefaults; return this; } /** * Sets default object used by section getters if the return type is object. *

* Default: {@link #DEFAULT_OBJECT} * * @param defaultObject default object * @return the builder */ public Builder setDefaultObject(@Nullable Object defaultObject) { this.defaultObject = defaultObject; return this; } /** * Sets default number used by section getters if the return type is a number - integer, float, byte, * biginteger... (per the getter documentation). *

* Default: {@link #DEFAULT_NUMBER} *

* The given default can not be null as multiple section getters derive their defaults from * this default (using {@link Number#intValue()}...). * * @param defaultNumber default number * @return the builder */ public Builder setDefaultNumber(@NotNull Number defaultNumber) { this.defaultNumber = defaultNumber; return this; } /** * Sets default string used by section getters if the return type is string. *

* Default: {@link #DEFAULT_STRING} * * @param defaultString default string * @return the builder */ public Builder setDefaultString(@Nullable String defaultString) { this.defaultString = defaultString; return this; } /** * Sets default char used by section getters if the return type is char. *

* Default: {@link #DEFAULT_CHAR} *

* The parameter is not of a primitive type, to allow for null values. Setting the default to * such value might produce unexpected issues, unless your program is adapted for it. On the other hand, there * are methods returning optionals, so having default value like this is rather pointless. * * @param defaultChar default char * @return the builder */ public Builder setDefaultChar(@Nullable Character defaultChar) { this.defaultChar = defaultChar; return this; } /** * Sets default boolean used by section getters if the return type is boolean. *

* Default: {@link #DEFAULT_BOOLEAN} *

* The parameter is not of a primitive type, to allow for null values. Setting the default to * such value might produce unexpected issues, unless your program is adapted for it. On the other hand, there * are methods returning optionals, so having default value like this is rather pointless. * * @param defaultBoolean default boolean * @return the builder */ public Builder setDefaultBoolean(@Nullable Boolean defaultBoolean) { this.defaultBoolean = defaultBoolean; return this; } /** * Sets default list supplier used to supply list instances during loading/when needed. *

* Default: {@link #DEFAULT_LIST} * * @param defaultList the supplier * @return the builder */ public Builder setDefaultList(@NotNull ListSupplier defaultList) { this.defaultList = defaultList; return this; } /** * Sets default set supplier used to supply set instances during loading/when needed. *

* Default: {@link #DEFAULT_SET} * * @param defaultSet the supplier * @return the builder */ public Builder setDefaultSet(@NotNull SetSupplier defaultSet) { this.defaultSet = defaultSet; return this; } /** * Sets default map supplier used to supply map instances during loading/creating new sections/when needed. *

* Default: {@link #DEFAULT_MAP} * * @param defaultMap the supplier * @return the builder */ public Builder setDefaultMap(@NotNull MapSupplier defaultMap) { this.defaultMap = defaultMap; return this; } /** * Builds the settings. * * @return the settings */ public GeneralSettings build() { return new GeneralSettings(this); } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy