001/*
002 * Configurate
003 * Copyright (C) zml and Configurate contributors
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License");
006 * you may not use this file except in compliance with the License.
007 * You may obtain a copy of the License at
008 *
009 *    http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package ninja.leaping.configurate.loader;
018
019import ninja.leaping.configurate.ConfigurationNode;
020import ninja.leaping.configurate.ConfigurationOptions;
021import ninja.leaping.configurate.reference.ConfigurationReference;
022import org.checkerframework.checker.nullness.qual.NonNull;
023
024import java.io.IOException;
025import java.nio.file.Path;
026import java.util.function.Function;
027
028/**
029 * Represents an object which can load and save {@link ConfigurationNode} objects in a specific
030 * configuration format.
031 *
032 * <p>An abstract implementation is provided by {@link AbstractConfigurationLoader}.</p>
033 *
034 * @param <NodeType> The {@link ConfigurationNode} type produced by the loader
035 */
036public interface ConfigurationLoader<NodeType extends ConfigurationNode> {
037
038    /**
039     * Gets the default {@link ConfigurationOptions} used by the loader.
040     *
041     * <p>New nodes will be created using the default options if a specific set is not defined.</p>
042     *
043     * @return The default options
044     */
045    @NonNull
046    ConfigurationOptions getDefaultOptions();
047
048    /**
049     * Attempts to load a {@link ConfigurationNode} using this loader, from the defined source.
050     *
051     * <p>The resultant node represents the root of the configuration being loaded.</p>
052     *
053     * <p>The {@link #getDefaultOptions() default options} will be used to construct the resultant
054     * configuration nodes.</p>
055     *
056     * @return The newly constructed node
057     * @throws IOException if any sort of error occurs with reading or parsing the configuration
058     */
059    @NonNull
060    default NodeType load() throws IOException {
061        return load(getDefaultOptions());
062    }
063
064    /**
065     * Attempts to load data from the defined source into a {@link ConfigurationReference}.
066     * The returned reference will not reload automatically.
067     *
068     * @return The created reference
069     * @throws IOException when an error occurs within the loader
070     * @see ninja.leaping.configurate.reference.WatchServiceListener#listenToConfiguration(Function, Path) to create an auto-reloading configuration.
071     */
072    default ConfigurationReference<NodeType> loadToReference() throws IOException {
073        return ConfigurationReference.createFixed(this);
074    }
075
076    /**
077     * Attempts to load a {@link ConfigurationNode} using this loader, from the defined source.
078     *
079     * <p>The resultant node represents the root of the configuration being loaded.</p>
080     *
081     * @param options The options to load with
082     * @return The newly constructed node
083     * @throws IOException if any sort of error occurs with reading or parsing the configuration
084     */
085    @NonNull
086    NodeType load(@NonNull ConfigurationOptions options) throws IOException;
087
088    /**
089     * Attempts to save a {@link ConfigurationNode} using this loader, to the defined sink.
090     *
091     * @param node The node to save
092     * @throws IOException if any sort of error occurs with writing or generating the configuration
093     */
094    void save(@NonNull ConfigurationNode node) throws IOException;
095
096    /**
097     * Return an empty node of the most appropriate type for this loader, using the default options.
098     *
099     * @return The appropriate node type
100     */
101    @NonNull
102    default NodeType createEmptyNode() {
103        return createEmptyNode(getDefaultOptions());
104    }
105
106    /**
107     * Return an empty node of the most appropriate type for this loader
108     *
109     * @param options The options to use with this node. Must not be null (see {@link ConfigurationOptions#defaults()})
110     * @return The appropriate node type
111     */
112    @NonNull
113    NodeType createEmptyNode(@NonNull ConfigurationOptions options);
114
115    /**
116     * Gets if this loader is capable of loading configurations.
117     *
118     * @return If this loader can load
119     */
120    default boolean canLoad() {
121        return true;
122    }
123
124    /**
125     * Gets if this loader is capable of saving configurations.
126     *
127     * @return If this loader can save
128     */
129    default boolean canSave() {
130        return true;
131    }
132}