private static boolean changeLocale(Locale newLocale, boolean force) { // set locale for startup (will override immediately it on locale change anyway) Locale.setDefault(newLocale); if (!isCurrentLocale(newLocale) || force) { Locale.setDefault(LOCALE_DEFAULT); ResourceBundle newResourceBundle = null; String bundleFolder = BUNDLE_NAME.replace('.', '/'); final String prefix = BUNDLE_NAME.substring(BUNDLE_NAME.lastIndexOf('.') + 1); final String extension = ".properties"; if (newLocale.equals(LOCALE_ENGLISH)) newLocale = LOCALE_DEFAULT; try { File userBundleFile = new File(SystemProperties.getUserPath()); File appBundleFile = new File(SystemProperties.getApplicationPath()); // Get the jarURL // XXX Is there a better way to get the JAR name? ClassLoader cl = MessageText.class.getClassLoader(); String sJar = cl.getResource(bundleFolder + extension).toString(); sJar = sJar.substring(0, sJar.length() - prefix.length() - extension.length()); URL jarURL = new URL(sJar); // User dir overrides app dir which overrides jar file bundles URL[] urls = {userBundleFile.toURL(), appBundleFile.toURL(), jarURL}; /* This is debugging code, use it when things go wrong :) The line number * is approximate as the input stream is buffered by the reader... { LineNumberInputStream lnis = null; try{ ClassLoader fff = new URLClassLoader(urls); java.io.InputStream stream = fff.getResourceAsStream("MessagesBundle_th_TH.properties"); lnis = new LineNumberInputStream( stream ); new java.util.PropertyResourceBundle(lnis); }catch( Throwable e ){ System.out.println( lnis.getLineNumber()); e.printStackTrace(); } } */ newResourceBundle = getResourceBundle("MessagesBundle", newLocale, new URLClassLoader(urls)); // do more searches if getBundle failed, or if the language is not the // same and the user wanted a specific country if ((!newResourceBundle.getLocale().getLanguage().equals(newLocale.getLanguage()) && !newLocale.getCountry().equals(""))) { Locale foundLocale = newResourceBundle.getLocale(); System.out.println( "changeLocale: " + (foundLocale.toString().equals("") ? "*Default Language*" : foundLocale.getDisplayLanguage()) + " != " + newLocale.getDisplayName() + ". Searching without country.."); // try it without the country Locale localeJustLang = new Locale(newLocale.getLanguage()); newResourceBundle = getResourceBundle("MessagesBundle", localeJustLang, new URLClassLoader(urls)); if (newResourceBundle == null || !newResourceBundle .getLocale() .getLanguage() .equals(localeJustLang.getLanguage())) { // find first language we have in our list System.out.println( "changeLocale: Searching for language " + newLocale.getDisplayLanguage() + " in *any* country.."); Locale[] locales = getLocales(); for (int i = 0; i < locales.length; i++) { if (locales[i].getLanguage() == newLocale.getLanguage()) { newResourceBundle = getResourceBundle("MessagesBundle", locales[i], new URLClassLoader(urls)); break; } } } } } catch (MissingResourceException e) { System.out.println("changeLocale: no resource bundle for " + newLocale); Debug.printStackTrace(e); return false; } catch (Exception e) { Debug.printStackTrace(e); } if (newResourceBundle != null) { if (!newLocale.equals(LOCALE_DEFAULT) && !newResourceBundle.getLocale().equals(newLocale)) { String sNewLanguage = newResourceBundle.getLocale().getDisplayName(); if (sNewLanguage == null || sNewLanguage.trim().equals("")) sNewLanguage = "English (default)"; System.out.println( "changeLocale: no message properties for Locale '" + newLocale.getDisplayName() + "' (" + newLocale + "), using '" + sNewLanguage + "'"); } newLocale = newResourceBundle.getLocale(); Locale.setDefault(newLocale.equals(LOCALE_DEFAULT) ? LOCALE_ENGLISH : newLocale); LOCALE_CURRENT = newLocale; setResourceBundle(new IntegratedResourceBundle(newResourceBundle, pluginLocalizationPaths)); if (newLocale.equals(LOCALE_DEFAULT)) DEFAULT_BUNDLE = RESOURCE_BUNDLE; return true; } else return false; } return false; }
public static Locale[] getLocales() { String bundleFolder = BUNDLE_NAME.replace('.', '/'); final String prefix = BUNDLE_NAME.substring(BUNDLE_NAME.lastIndexOf('.') + 1); final String extension = ".properties"; String urlString = MessageText.class .getClassLoader() .getResource(bundleFolder.concat(extension)) .toExternalForm(); // System.out.println("urlString: " + urlString); String[] bundles = null; if (urlString.startsWith("jar:file:")) { File jar = FileUtil.getJarFileFromURL(urlString); if (jar != null) { try { // System.out.println("jar: " + jar.getAbsolutePath()); JarFile jarFile = new JarFile(jar); Enumeration entries = jarFile.entries(); ArrayList list = new ArrayList(250); while (entries.hasMoreElements()) { JarEntry jarEntry = (JarEntry) entries.nextElement(); if (jarEntry.getName().startsWith(bundleFolder) && jarEntry.getName().endsWith(extension)) { // System.out.println("jarEntry: " + jarEntry.getName()); list.add(jarEntry.getName().substring(bundleFolder.length() - prefix.length())); // "MessagesBundle_de_DE.properties" } } bundles = (String[]) list.toArray(new String[list.size()]); } catch (Exception e) { Debug.printStackTrace(e); } } } else { File bundleDirectory = new File(URI.create(urlString)).getParentFile(); // System.out.println("bundleDirectory: " + // bundleDirectory.getAbsolutePath()); bundles = bundleDirectory.list( new FilenameFilter() { public boolean accept(File dir, String name) { return name.startsWith(prefix) && name.endsWith(extension); } }); } HashSet bundleSet = new HashSet(); // Add local first File localDir = new File(SystemProperties.getUserPath()); String localBundles[] = localDir.list( new FilenameFilter() { public boolean accept(File dir, String name) { return name.startsWith(prefix) && name.endsWith(extension); } }); // can be null if user path is borked if (localBundles != null) { bundleSet.addAll(Arrays.asList(localBundles)); } // Add AppDir 2nd File appDir = new File(SystemProperties.getApplicationPath()); String appBundles[] = appDir.list( new FilenameFilter() { public boolean accept(File dir, String name) { return name.startsWith(prefix) && name.endsWith(extension); } }); // can be null if app path is borked if (appBundles != null) { bundleSet.addAll(Arrays.asList(appBundles)); } // Any duplicates will be ignored bundleSet.addAll(Arrays.asList(bundles)); List foundLocalesList = new ArrayList(bundleSet.size()); foundLocalesList.add(LOCALE_ENGLISH); Iterator val = bundleSet.iterator(); while (val.hasNext()) { String sBundle = (String) val.next(); // System.out.println("ResourceBundle: " + bundles[i]); if (prefix.length() + 1 < sBundle.length() - extension.length()) { String locale = sBundle.substring(prefix.length() + 1, sBundle.length() - extension.length()); // System.out.println("Locale: " + locale); String[] sLocalesSplit = locale.split("_", 3); if (sLocalesSplit.length > 0 && sLocalesSplit[0].length() == 2) { if (sLocalesSplit.length == 3) { foundLocalesList.add(new Locale(sLocalesSplit[0], sLocalesSplit[1], sLocalesSplit[2])); } else if (sLocalesSplit.length == 2 && sLocalesSplit[1].length() == 2) { foundLocalesList.add(new Locale(sLocalesSplit[0], sLocalesSplit[1])); } else { foundLocalesList.add(new Locale(sLocalesSplit[0])); } } else { if (sLocalesSplit.length == 3 && sLocalesSplit[0].length() == 0 && sLocalesSplit[2].length() > 0) { foundLocalesList.add(new Locale(sLocalesSplit[0], sLocalesSplit[1], sLocalesSplit[2])); } } } } Locale[] foundLocales = new Locale[foundLocalesList.size()]; foundLocalesList.toArray(foundLocales); try { Arrays.sort( foundLocales, new Comparator() { public final int compare(Object a, Object b) { return ((Locale) a) .getDisplayName((Locale) a) .compareToIgnoreCase(((Locale) b).getDisplayName((Locale) b)); } }); } catch (Throwable e) { // user has a problem whereby a null-pointer exception occurs when sorting the // list - I've done some fixes to the locale list construction but am // putting this in here just in case Debug.printStackTrace(e); } return foundLocales; }