ConfigUtils.java

/*
 * Copyright © 2024-2025 The CTAN Team and individual authors
 *
 * This file is distributed under the 3-clause BSD license.
 * See file LICENSE for details.
 */

package org.ctan.site.services.util;

import java.util.Arrays;

import org.ctan.site.CtanConfiguration;
import org.ctan.site.CtanConfiguration.CtanConfig;

import lombok.NonNull;

/**
 * The class <code>ConfigUtils</code> contains utilities for the configuration.
 */
public interface ConfigUtils {

    /**
     * The field <code>DEFAULT_LANGUAGE</code> contains the index of the default
     * language.
     */
    static final int DEFAULT_LANGUAGE = 0;

    /**
     * The method <code>defaultLanguage</code> provides means to check the
     * CtanConfiguration and extract the default language.
     *
     * @param config the CTAN configuration
     * @return the default language
     */
    static String defaultLanguage(@NonNull CtanConfig config) {

        var languages = config.getLanguages();
        if (languages == null || languages.length == 0) {
            throw new IllegalArgumentException("languages missing");
        }
        return languages[0];
    }

    /**
     * The method <code>defaultLanguage</code> provides means to check the
     * CtanConfiguration and extract the default language.
     *
     * @param config the CTAN configuration
     * @return the default language
     */
    static String defaultLanguage(@NonNull CtanConfiguration config) {

        return defaultLanguage(config.getCtan());
    }

    /**
     * The method <code>fallbackLanguage</code> provides means to check the
     * language or extract the default language from the configuration.
     *
     * @param config the CTAN configuration
     * @param locale the language
     * @return the language
     */
    static String fallbackLanguage(@NonNull CtanConfig config,
            String locale) {

        var languages = languages(config);
        if (locale == null) {
            locale = languages[DEFAULT_LANGUAGE];

        } else if (!locale.matches("\\p{Lower}\\p{Lower}")) {
            throw new IllegalArgumentException("illegal lang " + locale);
        } else if (Arrays.asList(languages).indexOf(locale) < 0) {
            throw new IllegalArgumentException("unsupported locale " + locale);
        }
        return locale;
    }

    /**
     * The method <code>languages</code> provides means to extract the supported
     * languages from the configuration.
     *
     * @param config the CTAN configuration
     * @return the supported languages
     */
    static String[] languages(@NonNull CtanConfig config) {

        var languages = config.getLanguages();
        if (languages == null || languages.length == 0) {
            throw new IllegalArgumentException("config.languages is missing");
        }

        for (String lang : languages) {
            if (!lang.matches("\\p{Lower}\\p{Lower}")) {
                throw new IllegalArgumentException("illegal locale: " + lang);
            }
        }
        return languages;
    }
}