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 static java.util.Objects.requireNonNull; 020 021import org.checkerframework.checker.nullness.qual.NonNull; 022import org.spongepowered.configurate.ConfigurationNode; 023import org.spongepowered.configurate.ScopedConfigurationNode; 024import org.spongepowered.configurate.util.UnmodifiableCollections; 025 026import java.net.URL; 027import java.nio.file.Path; 028import java.util.ServiceLoader; 029import java.util.Set; 030import java.util.function.Supplier; 031 032/** 033 * An implementation of {@link ConfigurationFormat} designed to work 034 * with {@link AbstractConfigurationLoader}. 035 * 036 * <p>This reduces the boilerplate that would otherwise be required to implement 037 * a configuration format service.</p> 038 * 039 * @param <N> the node type 040 * @param <L> the loader type 041 * @param <B> the builder type 042 * @since 4.2.0 043 */ 044public abstract class AbstractConfigurationFormat< 045 N extends ScopedConfigurationNode<N>, 046 L extends AbstractConfigurationLoader<N>, 047 B extends AbstractConfigurationLoader.Builder<B, L> 048 > implements ConfigurationFormat { 049 050 private final String id; 051 private final Supplier<B> builderMaker; 052 private final Set<String> supportedExtensions; 053 054 /** 055 * Create a new configuration format. 056 * 057 * <p>Subclasses should have a zero-argument constructor to fulfil the 058 * requirements of {@link ServiceLoader}.</p> 059 * 060 * @param builderMaker a factory creating a new builder 061 * @param supportedExtensions the file extensions associated with 062 * this format 063 * @since 4.2.0 064 */ 065 protected AbstractConfigurationFormat(final String id, final Supplier<B> builderMaker, final Set<String> supportedExtensions) { 066 this.id = requireNonNull(id, "id"); 067 this.builderMaker = requireNonNull(builderMaker, "builderMaker"); 068 this.supportedExtensions = UnmodifiableCollections.copyOf(requireNonNull(supportedExtensions, "supportedExtensions")); 069 } 070 071 @Override 072 public String id() { 073 return this.id; 074 } 075 076 @Override 077 public Set<String> supportedExtensions() { 078 return this.supportedExtensions; 079 } 080 081 @Override 082 public ConfigurationLoader<? extends @NonNull Object> create(final Path file) { 083 return this.builderMaker.get() 084 .path(file) 085 .build(); 086 } 087 088 @Override 089 public ConfigurationLoader<? extends @NonNull Object> create(final Path file, final ConfigurationNode options) { 090 return this.builderMaker.get() 091 .from(LoaderOptionSource.node(options)) 092 .path(file) 093 .build(); 094 } 095 096 @Override 097 public ConfigurationLoader<? extends @NonNull Object> create(final URL url) { 098 return this.builderMaker.get() 099 .url(url) 100 .build(); 101 } 102 103 @Override 104 public ConfigurationLoader<? extends @NonNull Object> create(final URL url, final ConfigurationNode options) { 105 return this.builderMaker.get() 106 .from(LoaderOptionSource.node(options)) 107 .url(url) 108 .build(); 109 } 110 111}