All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.nls.util.Countries Maven / Gradle / Ivy

There is a newer version: 1.0.14
Show newest version
package com.nls.util;

import com.google.common.base.Strings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.text.Collator;
import java.text.Normalizer;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;

public final class Countries {

    public static final Country NO_COUNTRY = new Country("___", "__", "Global");
    private static final Logger LOGGER = LoggerFactory.getLogger(Countries.class);

    private static Countries defaultCountries = build();

    private final List countries;
    private final Map isoMap;
    private final Map codeMap;
    private final Map nameMap;
    private final Map wordMap;


    private Countries(List countries) {
        this.countries = Collections.unmodifiableList(countries);
        this.isoMap = countries.stream().collect(Collectors.toMap(Country::getIso, Function.identity()));
        this.codeMap = countries.stream().collect(Collectors.toMap(Country::getCode, Function.identity()));
        this.nameMap = countries.stream().collect(Collectors.toMap(o -> Normalizer.normalize(o.getName().toUpperCase(), Normalizer.Form.NFD), Function.identity()));
        this.wordMap = buildWordMap(this.nameMap);
    }

    public static Countries build() {
        List countries = new ArrayList<>();

        for (String country : Locale.getISOCountries()) {
            Locale locale = new Locale("en", country);
            String iso = locale.getISO3Country();
            String code = locale.getCountry();
            String name = locale.getDisplayCountry();

            if (!"".equals(iso) && !"".equals(code) && !"".equals(name)) {
                countries.add(new Country(locale));
            }
        }
        countries.sort(getCountryComparator(Locale.UK));
        countries.add(0, NO_COUNTRY);

        return new Countries(countries);
    }

    public static Countries build(Set countryRestrictions) {
        List countries = new ArrayList<>();
        Set notfound = new HashSet<>(countryRestrictions);

        for (String country : Locale.getISOCountries()) {
            Locale locale = new Locale("en", country);
            String iso = locale.getISO3Country();
            String code = locale.getCountry();
            String name = locale.getDisplayCountry();

            if (!"".equals(iso) && !"".equals(code) && !"".equals(name) && countryRestrictions.contains(iso)) {
                countries.add(new Country(locale));
                notfound.remove(iso);
            }
        }
        countries.sort(getCountryComparator(Locale.UK));
        countries.add(0, NO_COUNTRY);

        if (!notfound.isEmpty()) {
            LOGGER.error("Country restriction list values that were not found = " + notfound);
        }

        return new Countries(countries);
    }

    public static void setDefault(Countries countries) {
        defaultCountries = countries;
    }

    public static Comparator getCountryComparator(Locale locale) {
        Collator collator = Collator.getInstance(locale);
        collator.setStrength(Collator.PRIMARY);
        return (l, r) -> {
            if (l == NO_COUNTRY) {
                return -1;
            }
            if (r == NO_COUNTRY) {
                return 1;
            }
            return collator.compare(l.getName(locale), r.getName(locale));
        };
    }

    private static Map buildWordMap(Map nameMap) {
        Set seenWords = new HashSet<>();
        Map wordMap = new HashMap<>();
        for (Map.Entry entry : nameMap.entrySet()) {
            String name = entry.getKey();
            Country country = entry.getValue();

            for (String word : name.split(" ")) {
                if (!seenWords.contains(word)) {
                    seenWords.add(word);
                    wordMap.put(word, country);
                    continue;
                }

                if (!wordMap.containsKey(word)) { // stripped it out already
                    continue;
                }

                if (wordMap.get(word).getCode().equals(country.getCode())) {
                    continue;
                }

                wordMap.remove(word);
            }
        }

        return wordMap;
    }

    public List getCountries() {
        return countries;
    }

    public List getCountries(Locale locale) {
        return countries.stream()
                .sorted(getCountryComparator(locale))
                .collect(Collectors.toList());
    }

    public Country findIso(String iso) {
        return isoMap.get(Normalizer.normalize(Strings.nullToEmpty(iso).toUpperCase(), Normalizer.Form.NFD));
    }

    public Country findCode(String code) {
        return codeMap.get(Normalizer.normalize(Strings.nullToEmpty(code).toUpperCase(), Normalizer.Form.NFD));
    }

    public Country findName(String name) {
        return nameMap.get(Normalizer.normalize(Strings.nullToEmpty(name).toUpperCase(), Normalizer.Form.NFD));
    }

    public Country findWordMap(String name) {
        return wordMap.get(Normalizer.normalize(Strings.nullToEmpty(name).toUpperCase(), Normalizer.Form.NFD));
    }

    public Country find(String token) {
        if (fromIso(token) != null) {
            return fromIso(token);
        }

        if (fromCode(token) != null) {
            return fromCode(token);
        }

        if (fromName(token) != null) {
            return fromName(token);
        }

        if (fromWordMap(token) != null) {
            return fromWordMap(token);
        }

        return null;
    }


    public static List get() {
        return defaultCountries.getCountries();
    }

    public static List get(Locale locale) {
        return defaultCountries.getCountries(locale);
    }

    public static Country fromIso(String iso) {
        return defaultCountries.findIso(iso);
    }

    public static Country fromCode(String code) {
        return defaultCountries.findCode(code);
    }

    public static Country fromName(String name) {
        return defaultCountries.findName(name);
    }

    public static Country fromWordMap(String name) {
        return defaultCountries.findWordMap(name);
    }

    public static Country from(String token) {
        return defaultCountries.find(token);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy