diff --git a/src/org/hwo/i18n/Messages.java b/src/org/hwo/i18n/Messages.java index 4025140..d7f2b02 100644 --- a/src/org/hwo/i18n/Messages.java +++ b/src/org/hwo/i18n/Messages.java @@ -1,13 +1,24 @@ package org.hwo.i18n; +import java.io.File; +import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.InvalidPropertiesFormatException; import java.util.LinkedList; import java.util.List; import java.util.Locale; import java.util.MissingResourceException; import java.util.Properties; +import java.util.PropertyResourceBundle; import java.util.ResourceBundle; +import static org.hwo.logging.LogLevel.*; +import static org.hwo.logging.Logging.*; + + public class Messages { @@ -15,7 +26,15 @@ public class Messages { protected static List instanceList; protected static Locale activeLocale; - protected String BUNDLE_NAME = "org.hwo.i18n.messages"; + protected static List + resourceBundles; + protected static List + properties; + + protected String + BUNDLE_NAME = "org.hwo.i18n.messages"; + protected Class + BUNDLE_CLASS = null; private ResourceBundle defaultResourceBundle; @@ -32,7 +51,7 @@ public class Messages { BUNDLE_NAME = bundleName; initialize(); } - + public void saveMissingStrings() { if (missingKeys != null) @@ -42,7 +61,7 @@ public class Messages { fos = new FileOutputStream(missingKeysFileName); System.err.println(String.format("Writing missing strings to %s",missingKeysFileName)); - missingKeys.store(fos, ""); + missingKeys.storeToXML(fos, "missing translations"); fos.close(); } catch (Exception e) { e.printStackTrace(); @@ -52,7 +71,8 @@ public class Messages { private void initialize() { - System.err.println(this.getClass().getName() + ": Using Locale:" + activeLocale.getCountry() + " / " + activeLocale.getLanguage()); + System.err.println(this.getClass().getName() + ": Using Locale:" + activeLocale.getCountry() + " / " + activeLocale.getLanguage()); + defaultResourceBundle = ResourceBundle.getBundle(BUNDLE_NAME); localeResourceBundle = ResourceBundle.getBundle(BUNDLE_NAME,activeLocale); @@ -65,23 +85,48 @@ public class Messages { } public void setMissingKeysFileName(String fileName) { + if (missingKeys == null){ + enableMissingKeys(); + } + missingKeysFileName = fileName; + try { + missingKeys.loadFromXML(new FileInputStream(fileName)); + } catch (Exception e){ + log(e); + } } public void enableMissingKeys() { - missingKeys = new Properties(); + if (missingKeys == null) + missingKeys = new Properties(); } public static String getString(String key) { + + for (ResourceBundle bundle: resourceBundles){ + if (bundle.containsKey(key)) + return bundle.getString(key); + } + for (Messages messages: instanceList) { if (messages.hasKey(key)) return messages.getInstanceString(key); } + + for (Properties p: properties){ + if (p.containsKey(key)) + return p.getProperty(key); + } + if (getInstance().missingKeys != null) { - getInstance().missingKeys.setProperty(key, ""); + if (getInstance().missingKeys.containsKey(key)) + return getInstance().missingKeys.getProperty(key); + + getInstance().missingKeys.setProperty(key, key); } return key; } @@ -104,8 +149,89 @@ public class Messages { { return pInstance; } + + + private static String[] generateFileNamesForBase(Class clazz,Locale locale){ + + if (locale == null) + locale = activeLocale; + + return new String[]{ + String.format("%s.msg_%s_%s", clazz.getCanonicalName(), locale.getLanguage(), locale.getCountry()), + String.format("%s.msg_%s_%s", clazz.getSimpleName(), locale.getLanguage(), locale.getCountry()), + String.format("%s.msg_%s", clazz.getCanonicalName(), locale.getLanguage()), + String.format("%s.msg_%s", clazz.getSimpleName(), locale.getLanguage()), + String.format("%s.msg", clazz.getCanonicalName()), + String.format("%s.msg", clazz.getSimpleName()) + }; + } + + private static File[] possibleFilesFor(Class clazz){ + LinkedList files = new LinkedList<>(); + + for (String fn: generateFileNamesForBase(clazz, null)){ + File f = new File(fn); + if (f.exists()) + files.add(f); + } + + return files.toArray(new File[0]); + } + + + private static ResourceBundle tryLoad(InputStream is){ + try { + return new PropertyResourceBundle(is); + } catch (Exception e){ + log(e); + } + + return null; + } + + public static boolean loadMessages(Class clazz){ + boolean leastOne = false; + String[] fileNames = generateFileNamesForBase(clazz, null); + + for (String fn: fileNames){ + InputStream is = clazz.getClassLoader().getResourceAsStream(fn); + if (is == null){ + if (new File(fn).exists()) + try { + is = new FileInputStream(fn); + } catch (FileNotFoundException e) { + log(e); + } + } + if (is != null){ + ResourceBundle rb = tryLoad(is); + if (rb != null){ + log(INFO,"I18N: loaded %s",fn); + resourceBundles.add(rb); + continue; + } + } + + Properties prop = new Properties(); + try { + String xfn = String.format("%s.xml", fn); + prop.loadFromXML(new FileInputStream(xfn)); + properties.add(prop); + log(INFO,"I18N: loaded %s",xfn); + continue; + } catch (Exception e) { + } + + log(INFO,"I18N: does not exist: %s",fn); + } + + return leastOne; + } static { + resourceBundles = new ArrayList<>(); + properties = new ArrayList<>(); + if (activeLocale == null) activeLocale = Locale.getDefault();