<commit_before>package pluginbase.bukkit.config;

import pluginbase.config.ConfigSerializer;
import pluginbase.config.SerializationRegistrar;
import com.google.common.io.Files;
import org.apache.commons.lang.Validate;
import org.bukkit.Bukkit;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.configuration.file.FileConfiguration;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import pluginbase.config.field.FieldMapper;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.nio.charset.Charset;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;

public abstract class BukkitConfiguration extends FileConfiguration {

    private static final Charset UTF8 = Charset.forName("UTF-8");

    /**
     * Creates a new {@link YamlConfiguration}, loading from the given file.
     * <p>
     * Any errors loading the Configuration will be logged and then ignored.
     * If the specified input is not a valid config, a blank config will be returned.
     *
     * @param file Input file
     * @return Resulting configuration
     * @throws IllegalArgumentException Thrown if file is null
     */
    public static YamlConfiguration loadYamlConfig(File file) {
        Validate.notNull(file, "File cannot be null");

        YamlConfiguration config = new YamlConfiguration();

        try {
            config.load(file);
        } catch (FileNotFoundException ex) {
        } catch (IOException ex) {
            Bukkit.getLogger().log(Level.SEVERE, "Cannot load " + file, ex);
        } catch (InvalidConfigurationException ex) {
            Bukkit.getLogger().log(Level.SEVERE, "Cannot load " + file , ex);
        }

        return config;
    }

    /**
     * Creates a new {@link YamlConfiguration}, loading from the given stream.
     * <p>
     * Any errors loading the Configuration will be logged and then ignored.
     * If the specified input is not a valid config, a blank config will be returned.
     *
     * @param stream Input stream
     * @return Resulting configuration
     * @throws IllegalArgumentException Thrown if stream is null
     */
    public static YamlConfiguration loadYamlConfig(InputStream stream) {
        Validate.notNull(stream, "Stream cannot be null");

        YamlConfiguration config = new YamlConfiguration();

        try {
            config.load(stream);
        } catch (IOException ex) {
            Bukkit.getLogger().log(Level.SEVERE, "Cannot load configuration from stream", ex);
        } catch (InvalidConfigurationException ex) {
            Bukkit.getLogger().log(Level.SEVERE, "Cannot load configuration from stream", ex);
        }

        return config;
    }

    @Override
    public void load(@NotNull final InputStream stream) throws IOException, InvalidConfigurationException {
        InputStreamReader reader = new InputStreamReader(stream, UTF8);
        StringBuilder builder = new StringBuilder();
        BufferedReader input = new BufferedReader(reader);

        try {
            String line;
            while ((line = input.readLine()) != null) {
                builder.append(line);
                builder.append('\n');
            }
        } finally {
            input.close();
        }

        loadFromString(builder.toString());
    }

    @Override
    public void save(@NotNull final File file) throws IOException {
        Files.createParentDirs(file);

        final String data = saveToString();

        BufferedWriter writer = null;
        try {
            writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), UTF8));
            writer.write(data);
        } finally {
            if (writer != null) {
                writer.close();
            }
        }
    }

    @Override
    protected abstract String buildHeader();

    /**
     * Retrieves the object data at the specified path and attempts to insert it into an object of the given type, if
     * possible.
     * <p/>
     * If the specified path contains an object of the given type, the object at the specified path will be returned.
     * <p/>
     * If the specified path contains valid data for filling an object of the given type, this will be done and the data
     * at the specified path will be replaced by the returned object.
     *
     * @param path The path to retrieve data from.
     * @param clazz The type of object expected from the given data.
     * @param <T> The object's type.
     * @return An object from the specified path or made from data at the specified path.  If there is nothing at the
     * specified path or the data cannot be parsed into the correct type of object, null will be returned.
     */

    @Nullable
    public <T> T getAs(@NotNull String path, @NotNull Class<T> clazz) {
        Object o = get(path);
        if (o != null && o.getClass().equals(clazz)) {
            return (T) o;
        }
        if (o instanceof ConfigurationSection) {
            o = convertSectionToMap((ConfigurationSection) o);
        }
        if (o instanceof List) {
            o = convertList((List) o);
        }
        if (o != null && SerializationRegistrar.isClassRegistered(clazz)) {
            try {
                T object = (T) ConfigSerializer.deserializeAs(o, clazz);
                set(path, object);
                return object;
            } catch (Exception e) {
                return null;
            }
        } else if (clazz.isInstance(o)) {
            return (T) o;
        } else {
            return null;
        }
    }

    @Nullable <T> T getToObject(@NotNull String path, @NotNull T destination) {
        T source = getAs(path, (Class<T>) destination.getClass());
        if (source != null) {
            return FieldMapper.mapFields(source, destination);
        } else {
            return null;
        }
    }

    private Map convertSectionToMap(@NotNull ConfigurationSection section) {
        Map<String, Object> values = section.getValues(false);
        Map<String, Object> result = new LinkedHashMap<String, Object>(values.size());
        for (Map.Entry<String, Object> entry : values.entrySet()) {
            String key = entry.getKey();
            Object value = entry.getValue();
            int lastSeparatorIndex = key.lastIndexOf(options().pathSeparator());
            if (lastSeparatorIndex >= 0) {
                key = key.substring(lastSeparatorIndex + 1, key.length());<commit_msg>Made getToObject() public!<commit_after>package pluginbase.bukkit.config;

import pluginbase.config.ConfigSerializer;
import pluginbase.config.SerializationRegistrar;
import com.google.common.io.Files;
import org.apache.commons.lang.Validate;
import org.bukkit.Bukkit;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.configuration.file.FileConfiguration;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import pluginbase.config.field.FieldMapper;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.nio.charset.Charset;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;

public abstract class BukkitConfiguration extends FileConfiguration {

    private static final Charset UTF8 = Charset.forName("UTF-8");

    /**
     * Creates a new {@link YamlConfiguration}, loading from the given file.
     * <p>
     * Any errors loading the Configuration will be logged and then ignored.
     * If the specified input is not a valid config, a blank config will be returned.
     *
     * @param file Input file
     * @return Resulting configuration
     * @throws IllegalArgumentException Thrown if file is null
     */
    public static YamlConfiguration loadYamlConfig(File file) {
        Validate.notNull(file, "File cannot be null");

        YamlConfiguration config = new YamlConfiguration();

        try {
            config.load(file);
        } catch (FileNotFoundException ex) {
        } catch (IOException ex) {
            Bukkit.getLogger().log(Level.SEVERE, "Cannot load " + file, ex);
        } catch (InvalidConfigurationException ex) {
            Bukkit.getLogger().log(Level.SEVERE, "Cannot load " + file , ex);
        }

        return config;
    }

    /**
     * Creates a new {@link YamlConfiguration}, loading from the given stream.
     * <p>
     * Any errors loading the Configuration will be logged and then ignored.
     * If the specified input is not a valid config, a blank config will be returned.
     *
     * @param stream Input stream
     * @return Resulting configuration
     * @throws IllegalArgumentException Thrown if stream is null
     */
    public static YamlConfiguration loadYamlConfig(InputStream stream) {
        Validate.notNull(stream, "Stream cannot be null");

        YamlConfiguration config = new YamlConfiguration();

        try {
            config.load(stream);
        } catch (IOException ex) {
            Bukkit.getLogger().log(Level.SEVERE, "Cannot load configuration from stream", ex);
        } catch (InvalidConfigurationException ex) {
            Bukkit.getLogger().log(Level.SEVERE, "Cannot load configuration from stream", ex);
        }

        return config;
    }

    @Override
    public void load(@NotNull final InputStream stream) throws IOException, InvalidConfigurationException {
        InputStreamReader reader = new InputStreamReader(stream, UTF8);
        StringBuilder builder = new StringBuilder();
        BufferedReader input = new BufferedReader(reader);

        try {
            String line;
            while ((line = input.readLine()) != null) {
                builder.append(line);
                builder.append('\n');
            }
        } finally {
            input.close();
        }

        loadFromString(builder.toString());
    }

    @Override
    public void save(@NotNull final File file) throws IOException {
        Files.createParentDirs(file);

        final String data = saveToString();

        BufferedWriter writer = null;
        try {
            writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), UTF8));
            writer.write(data);
        } finally {
            if (writer != null) {
                writer.close();
            }
        }
    }

    @Override
    protected abstract String buildHeader();

    /**
     * Retrieves the object data at the specified path and attempts to insert it into an object of the given type, if
     * possible.
     * <p/>
     * If the specified path contains an object of the given type, the object at the specified path will be returned.
     * <p/>
     * If the specified path contains valid data for filling an object of the given type, this will be done and the data
     * at the specified path will be replaced by the returned object.
     *
     * @param path The path to retrieve data from.
     * @param clazz The type of object expected from the given data.
     * @param <T> The object's type.
     * @return An object from the specified path or made from data at the specified path.  If there is nothing at the
     * specified path or the data cannot be parsed into the correct type of object, null will be returned.
     */

    @Nullable
    public <T> T getAs(@NotNull String path, @NotNull Class<T> clazz) {
        Object o = get(path);
        if (o != null && o.getClass().equals(clazz)) {
            return (T) o;
        }
        if (o instanceof ConfigurationSection) {
            o = convertSectionToMap((ConfigurationSection) o);
        }
        if (o instanceof List) {
            o = convertList((List) o);
        }
        if (o != null && SerializationRegistrar.isClassRegistered(clazz)) {
            try {
                T object = (T) ConfigSerializer.deserializeAs(o, clazz);
                set(path, object);
                return object;
            } catch (Exception e) {
                return null;
            }
        } else if (clazz.isInstance(o)) {
            return (T) o;
        } else {
            return null;
        }
    }

    @Nullable
    public <T> T getToObject(@NotNull String path, @NotNull T destination) {
        T source = getAs(path, (Class<T>) destination.getClass());
        if (source != null) {
            return FieldMapper.mapFields(source, destination);
        } else {
            return null;
        }
    }

    private Map convertSectionToMap(@NotNull ConfigurationSection section) {
        Map<String, Object> values = section.getValues(false);
        Map<String, Object> result = new LinkedHashMap<String, Object>(values.size());
        for (Map.Entry<String, Object> entry : values.entrySet()) {
            String key = entry.getKey();
            Object value = entry.getValue();
            int lastSeparatorIndex = key.lastIndexOf(options().pathSeparator());
            if (lastSeparatorIndex >= 0) {
                key = key.substring(lastSeparatorIndex + 1, key.length());
{'fraction_non_alphanumeric': 0.09161147902869757, 'fraction_numerical': 0.0008830022075055188, 'mean_word_length': 2.497426659804426, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 31, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4631964', 'n_tokens_mistral': 3507, 'n_tokens_neox': 3453, 'n_words': 1160}