MirrorService.java

/*
 * Copyright © 2023-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.mirrors;

import java.io.IOException;
import java.util.Collection;
import java.util.Properties;

import org.ctan.site.domain.mirrors.Mirrors;
import org.ctan.site.stores.MirrorStore;

import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import lombok.NonNull;

/**
 * The class <code>MirrorService</code> contains the service to deal with
 * mirrors.
 *
 * @author <a href="mailto:gene@ctan.org">Gerd Neugebauer</a>
 */
public class MirrorService {

    /**
     * The field <code>continents</code> contains the mapping of the continent.
     */
    private Properties continents = null;

    /**
     * The field <code>countries</code> contains the mapping of country names as
     * used in the mirror database to their ISO code.
     */
    private Properties countries = null;

    /**
     * The field <code>store</code> contains the underlying store.
     */
    private MirrorStore store;

    /**
     * This is the constructor for the class <code>MirrorService</code>.
     *
     * @param store the underlying store
     *
     * @throws IOException in case of an I/O error
     */
    @SuppressFBWarnings(value = {"CT_CONSTRUCTOR_THROW", "EI_EXPOSE_REP2"})
    public MirrorService(@NonNull MirrorStore store) throws IOException {

        this.store = store;
        if (this.continents == null) {
            this.continents = loadProperties("/data/continents.properties");
        }
        if (this.countries == null) {
            this.countries = loadProperties("/data/countries.properties");
        }
    }

    /**
     * The method <code>findAll</code> provides means to retrieve all mirrors.
     *
     * @return the collection of mirrors
     */
    public Collection<Mirrors> findAll() {

        return store.findAll();
    }

    /**
     * The method <code>loadProperties</code> provides means to load properties
     * form a file on the class path.
     *
     * @param file the file
     * @return the properties
     * @throws IOException in case of an I/O error
     */
    private Properties loadProperties(String file) throws IOException {

        var props = new Properties();
        try (var is = MirrorService.class
            .getResourceAsStream(file)) {
            props.load(is);
        }
        return props;
    }

    /**
     * The method <code>mapContinent</code> provides means to get a connected
     * name of the continent. This means that spaces are replaced by minus.
     *
     * @param name the internal name of the continent
     * @return the continent name
     */
    public String mapContinent(String name) {

        return (String) continents.get(name.replace(' ', '-'));
    }

    /**
     * The method <code>mapCountry</code> provides means to get a connected name
     * of the country. This means that spaces are replaced by minus.
     *
     * @param name the internal name of the country
     * @return The country name
     */
    public String mapCountry(String name) {

        return (String) countries.get(name.replace(' ', '-'));
    }
}