com.limegroup.gnutella.gui.LanguageUtils.java Source code

Java tutorial

Introduction

Here is the source code for com.limegroup.gnutella.gui.LanguageUtils.java

Source

/*
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package com.limegroup.gnutella.gui;

import java.awt.Font;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.limewire.util.FileUtils;
import org.limewire.util.OSUtils;

import com.limegroup.gnutella.settings.ApplicationSettings;

/**
 * This class provides utility methods retrieving supported languages and
 * changing language settings.
 */
public class LanguageUtils {

    private static Log LOG = LogFactory.getLog(LanguageUtils.class);

    private static final String BUNDLE_PREFIX = "org/limewire/i18n/Messages_";

    private static final String BUNDLE_POSTFIX = ".class";

    private static final String BUNDLE_MARKER = "org/limewire/i18n/Messages.class";

    /**
     * Applies this language code to be the new language of the program.
     */
    public static void setLocale(Locale locale) {
        ApplicationSettings.LANGUAGE.setValue(locale.getLanguage());
        ApplicationSettings.COUNTRY.setValue(locale.getCountry());
        ApplicationSettings.LOCALE_VARIANT.setValue(locale.getVariant());

        GUIMediator.resetLocale();
    }

    /**
     * Returns an array of supported language as a LanguageInfo[], always having
     * the English language as the first element.
     * 
     * This will only include languages that can be displayed using the given
     * font. If the font is null, all languages are returned.
     */
    public static Locale[] getLocales(Font font) {
        final List<Locale> locales = new LinkedList<Locale>();

        File jar = FileUtils.getJarFromClasspath(LanguageUtils.class.getClassLoader(), BUNDLE_MARKER);
        if (jar != null) {
            addLocalesFromJar(locales, jar);
        } else {
            LOG.warn("Could not find bundle jar to determine locales");
        }

        Collections.sort(locales, new Comparator<Locale>() {
            public int compare(Locale o1, Locale o2) {
                return o1.getDisplayName(o1).compareToIgnoreCase(o2.getDisplayName(o2));
            }
        });

        locales.remove(Locale.ENGLISH);
        locales.add(0, Locale.ENGLISH);

        // remove languages that cannot be displayed using this font
        if (font != null && !OSUtils.isMacOSX()) {
            for (Iterator<Locale> it = locales.iterator(); it.hasNext();) {
                Locale locale = it.next();
                if (!GUIUtils.canDisplay(font, locale.getDisplayName(locale))) {
                    it.remove();
                }
            }
        }

        return locales.toArray(new Locale[0]);
    }

    /**
     * Returns the languages as found from the classpath in messages.jar
     */
    static void addLocalesFromJar(List<Locale> locales, File jar) {
        ZipFile zip = null;
        try {
            zip = new ZipFile(jar);
            Enumeration<? extends ZipEntry> entries = zip.entries();
            while (entries.hasMoreElements()) {
                String name = entries.nextElement().getName();
                if (!name.startsWith(BUNDLE_PREFIX) || !name.endsWith(BUNDLE_POSTFIX) || name.indexOf("$") != -1) {
                    continue;
                }

                String iso = name.substring(BUNDLE_PREFIX.length(), name.length() - BUNDLE_POSTFIX.length());
                List<String> tokens = new ArrayList<String>(Arrays.asList(iso.split("_", 3)));
                if (tokens.size() < 1) {
                    continue;
                }
                while (tokens.size() < 3) {
                    tokens.add("");
                }

                Locale locale = new Locale(tokens.get(0), tokens.get(1), tokens.get(2));
                locales.add(locale);
            }
        } catch (IOException e) {
            LOG.warn("Could not determine locales", e);
        } finally {
            if (zip != null) {
                try {
                    zip.close();
                } catch (IOException ioe) {
                }
            }
        }
    }

    /**
     * Returns true if the language of <code>locale</code> is English.
     */
    public static boolean isEnglishLocale(Locale locale) {
        return Locale.ENGLISH.getLanguage().equals(locale.getLanguage());
    }

    /**
     * Returns a score between -1 and 3 how well <code>specificLocale</code>
     * matches <code>genericLocale</code>.
     * 
     * @return -1, if locales do not match, 3 if locales are equal
     */
    public static int getMatchScore(Locale specificLocale, Locale genericLocale) {
        int i = 0;
        if (specificLocale.getLanguage().equals(genericLocale.getLanguage())) {
            i += 1;
        } else if (genericLocale.getLanguage().length() > 0) {
            return -1;
        }
        if (specificLocale.getCountry().equals(genericLocale.getCountry())) {
            i += 1;
        } else if (genericLocale.getCountry().length() > 0) {
            return -1;
        }
        if (specificLocale.getVariant().equals(genericLocale.getVariant())) {
            i += 1;
        } else if (genericLocale.getVariant().length() > 0) {
            return -1;
        }

        return i;
    }

    /**
     * Returns true, if <code>locale</code> is less specific than the system
     * default locale.
     * 
     * @see Locale#getDefault()
     */
    public static boolean matchesDefaultLocale(Locale locale) {
        Locale systemLocale = Locale.getDefault();
        if (matchesOrIsMoreSpecific(systemLocale.getLanguage(), locale.getLanguage())
                && matchesOrIsMoreSpecific(systemLocale.getCountry(), locale.getCountry())
                && matchesOrIsMoreSpecific(systemLocale.getVariant(), locale.getVariant())) {
            return true;
        }
        return false;
    }

    private static boolean matchesOrIsMoreSpecific(String detailed, String generic) {
        return generic.length() == 0 || detailed.equals(generic);
    }

}