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 org.spongepowered.configurate.loader;
018
019import org.checkerframework.checker.nullness.qual.NonNull;
020import org.checkerframework.checker.nullness.qual.Nullable;
021import org.spongepowered.configurate.BasicConfigurationNode;
022import org.spongepowered.configurate.ConfigurationNode;
023
024import java.net.URL;
025import java.nio.file.Path;
026import java.util.ServiceLoader;
027import java.util.Set;
028
029/**
030 * A service provider interface declaring a specific configuration format.
031 *
032 * <p>This is a service interface, designed to be implemented by modules
033 * that provide a {@link ConfigurationLoader} implementation. Service discovery
034 * follows the rules laid out in {@link ServiceLoader}.</p>
035 *
036 * @see AbstractConfigurationFormat
037 * @since 4.2.0
038 */
039public interface ConfigurationFormat {
040
041    /**
042     * Get a configuration format that can handle the specified extension.
043     *
044     * <p>If a format fails to load, it will be ignored when p</p>
045     *
046     * @param extension the extension to handle
047     * @return a format, or {@code null} if none is known
048     * @since 4.2.0
049     */
050    static @Nullable ConfigurationFormat forExtension(final String extension) {
051        final ConfigurationFormats.@Nullable Holder holder = ConfigurationFormats.BY_EXTENSION.get(extension);
052        return holder == null ? null : holder.get();
053    }
054
055    /**
056     * Get all supported configuration formats.
057     *
058     * <p>If any exceptions were thrown while discovering or loading
059     * configuration format services, they will be rethrown on calling
060     * this method.</p>
061     *
062     * @return all known formats
063     * @since 4.2.0
064     */
065    static Set<ConfigurationFormat> supportedFormats() {
066        return ConfigurationFormats.unwrappedFormats();
067    }
068
069    /**
070     * An identifier describing this loader.
071     *
072     * <p>This should match the naming used in other locations, such as the
073     * loader's artifact ID or class name.</p>
074     *
075     * @return the loader identifier
076     * @since 4.2.0
077     */
078    String id();
079
080    /**
081     * Get the file extensions known to be supported by this format.
082     *
083     * @return the supported extensions
084     * @since 4.2.0
085     */
086    Set<String> supportedExtensions();
087
088    /**
089     * Create a new loader configured to load from the provided file,
090     * with default style options.
091     *
092     * @param file the file to load from
093     * @return a newly configured loader
094     * @since 4.2.0
095     */
096    default ConfigurationLoader<? extends @NonNull Object> create(Path file) {
097        return create(file, BasicConfigurationNode.factory().createNode());
098    }
099
100    /**
101     * Create a new loader configured to load from the provided file.
102     *
103     * @param file the file to load from
104     * @param options the options to use to configure the node
105     * @return a newly configured loader
106     * @since 4.2.0
107     */
108    ConfigurationLoader<? extends @NonNull Object> create(Path file, ConfigurationNode options);
109
110    /**
111     * Create a new loader configured to load from the provided URL,
112     * with default style options.
113     *
114     * <p>This loader may not be able to write to the given URL</p>
115     *
116     * @param url the URL to load from
117     * @return a newly configured loader
118     * @since 4.2.0
119     */
120    default ConfigurationLoader<? extends @NonNull Object> create(URL url) {
121        return create(url, BasicConfigurationNode.factory().createNode());
122    }
123
124    /**
125     * Create a new loader configured to load from the provided URL.
126     *
127     * <p>This loader may not be able to write to the given URL.</p>
128     *
129     * @param url the URL to load from
130     * @param options the options to use to configure the node
131     * @return a newly configured loader
132     * @since 4.2.0
133     */
134    ConfigurationLoader<? extends @NonNull Object> create(URL url, ConfigurationNode options);
135
136}