001package jmri.util.jdom;
002
003import java.util.Locale;
004import org.jdom2.Attribute;
005import org.jdom2.Element;
006import org.jdom2.Namespace;
007
008/**
009 * Select XML content based on current Locale.
010 *
011 * Tries locale and country separated by an underscore, language, and then uses
012 * the default Locale.
013 *
014 * _tlh is treated as a special case, for the ant locale target
015 *
016 * @author Bob Jacobsen Copyright 2010
017 * @since 2.9.3
018 */
019public class LocaleSelector {
020
021    static String[] suffixes
022            = new String[]{
023                Locale.getDefault().getLanguage() + "_" + Locale.getDefault().getCountry(),
024                Locale.getDefault().getLanguage(),
025                ""
026            };
027
028    static boolean testLocale = Locale.getDefault().getLanguage().equals("tlh");
029
030    /**
031     * Return the value of an attribute for the current locale.
032     * <p>
033     * {@code <foo temp="a">}
034     * {@code <temp xml:lang="hh">b</temp>}
035     * {@code </foo>}
036     * <p>
037     * Say it's looking for the attribute ATT. For each possible suffix, it
038     * first looks for a contained element named ATT with an XML 'lang'
039     * attribute for the suffix. If so, it takes that value. If none are found,
040     * the attribute value is taken from the original element.
041     *
042     * @param el   the element with the attribute or child element
043     * @param name the name of the attribute or child element
044     * @return the value of the attribute or null
045     */
046    static public String getAttribute(Element el, String name) {
047        String retval;
048        // look for each suffix first
049        for (String suffix : suffixes) {
050            retval = checkElement(el, name, suffix);
051            if (retval != null) {
052                if (testLocale) {
053                    return retval.toUpperCase(); // the I18N test case, return string in upper case
054                }
055                return retval;
056            }
057        }
058
059        // try default element
060        for (Object obj : el.getChildren(name)) {
061            Element e = (Element) obj;
062            Attribute a = e.getAttribute("lang", Namespace.XML_NAMESPACE);
063            if (a == null) {
064                // default element
065                if (testLocale) {
066                    return e.getText().toUpperCase(); // the I18N test case, return string in upper case
067                }
068                return e.getText();
069            }
070        }
071
072        // failed, go back to original attribute
073        Attribute a = el.getAttribute(name);
074        if (a == null) {
075            return null;
076        }
077        if (testLocale) {
078            return a.getValue().toUpperCase(); // the I18N test case, return string in upper case
079        }
080        return a.getValue();
081    }
082
083    /**
084     * Checks one element to see if it's the one for the current language else
085     * returns null.
086     *
087     * @param el     the element
088     * @param name   the attribute
089     * @param suffix the locale
090     * @return the value of the attribute or null
091     */
092    static String checkElement(Element el, String name, String suffix) {
093        for (Object obj : el.getChildren(name)) {
094            Element e = (Element) obj;
095            Attribute a = e.getAttribute("lang", Namespace.XML_NAMESPACE);
096            if (a != null) {
097                if (a.getValue().equals(suffix)) {
098                    return e.getText();
099                }
100            }
101        }
102        return null;
103    }
104
105    // for testing purposes
106    protected static void setSuffixes(String[] newSuffixes){
107        suffixes = java.util.Arrays.copyOf(newSuffixes, newSuffixes.length );
108    }
109
110}