From 487926f7ddbf951064dac50cc468afceb8b0b232 Mon Sep 17 00:00:00 2001 From: Niki Roo Date: Tue, 7 Mar 2017 19:32:40 +0100 Subject: [PATCH] Bundle: some fixes + update tests --- src/be/nikiroo/utils/resources/Bundle.java | 114 ++++++++++++------ .../nikiroo/utils/resources/TransBundle.java | 8 +- src/be/nikiroo/utils/test/BundleTest.java | 36 +++--- 3 files changed, 104 insertions(+), 54 deletions(-) diff --git a/src/be/nikiroo/utils/resources/Bundle.java b/src/be/nikiroo/utils/resources/Bundle.java index 4420109c..9da8d748 100644 --- a/src/be/nikiroo/utils/resources/Bundle.java +++ b/src/be/nikiroo/utils/resources/Bundle.java @@ -36,8 +36,8 @@ import java.util.ResourceBundle; public class Bundle> { protected Class type; protected Enum name; - private ResourceBundle map; - private Map changeMap; + private Map map; // R/O map + private Map changeMap; // R/W map /** * Create a new {@link Bundles} of the given name. @@ -51,6 +51,7 @@ public class Bundle> { protected Bundle(Class type, Enum name) { this.type = type; this.name = name; + this.map = new HashMap(); this.changeMap = new HashMap(); setBundle(name, Locale.getDefault(), false); } @@ -65,7 +66,7 @@ public class Bundle> { * resource file) */ public String getString(E id) { - return getStringX(id, null); + return getString(id.name()); } /** @@ -78,12 +79,14 @@ public class Bundle> { * */ public void setString(E id, String value) { - setStringX(id, null, value); + setString(id.name(), value); } /** * Return the value associated to the given id as a {@link String} suffixed * with the runtime value "_suffix" (that is, "_" and suffix). + *

+ * Will only accept suffixes that form an existing id. * * @param mame * the id of the value to get @@ -97,8 +100,11 @@ public class Bundle> { String key = id.name() + (suffix == null ? "" : "_" + suffix.toUpperCase()); - if (containsKey(key)) { - return getString(key).trim(); + try { + id = Enum.valueOf(type, key); + return getString(id); + } catch (IllegalArgumentException e) { + } return null; @@ -107,6 +113,8 @@ public class Bundle> { /** * Set the value associated to the given id as a {@link String} suffixed * with the runtime value "_suffix" (that is, "_" and suffix). + *

+ * Will only accept suffixes that form an existing id. * * @param mame * the id of the value to get @@ -119,7 +127,12 @@ public class Bundle> { String key = id.name() + (suffix == null ? "" : "_" + suffix.toUpperCase()); - setString(key, value); + try { + id = Enum.valueOf(type, key); + setString(id, value); + } catch (IllegalArgumentException e) { + + } } /** @@ -287,6 +300,23 @@ public class Bundle> { setString(id, "#" + r + g + b + a); } + /** + * Create/update the .properties file. + *

+ * Will use the most likely candidate as base if the file does not already + * exists and this resource is translatable (for instance, "en_US" will use + * "en" as a base if the resource is a translation file). + *

+ * Will update the files in {@link Bundles#getDirectory()}; it MUST + * be set. + * + * @throws IOException + * in case of IO errors + */ + public void updateFile() throws IOException { + updateFile(Bundles.getDirectory()); + } + /** * Create/update the .properties file. *

@@ -295,7 +325,8 @@ public class Bundle> { * "en" as a base if the resource is a translation file). * * @param path - * the path where the .properties files are + * the path where the .properties files are, MUST NOT be + * NULL * * @throws IOException * in case of IO errors @@ -337,7 +368,7 @@ public class Bundle> { * configuration) */ public void reload(boolean resetToDefault) { - setBundle(name, null, resetToDefault); + setBundle(name, Locale.getDefault(), resetToDefault); } /** @@ -349,19 +380,7 @@ public class Bundle> { * @return true if it does */ protected boolean containsKey(String key) { - if (changeMap.containsKey(key)) { - return true; - } - - if (map != null) { - try { - map.getObject(key); - return true; - } catch (MissingResourceException e) { - } - } - - return false; + return changeMap.containsKey(key) || map.containsKey(key); } /** @@ -378,8 +397,8 @@ public class Bundle> { return changeMap.get(key); } - if (map != null && containsKey(key)) { - return map.getString(key); + if (map.containsKey(key)) { + return map.get(key); } return null; @@ -395,7 +414,7 @@ public class Bundle> { * the associated value */ protected void setString(String key, String value) { - changeMap.put(key, value); + changeMap.put(key, value == null ? null : value.trim()); } /** @@ -550,31 +569,56 @@ public class Bundle> { * configuration) */ protected void setBundle(Enum name, Locale locale, boolean resetToDefault) { - map = null; changeMap.clear(); String dir = Bundles.getDirectory(); + boolean found = false; if (!resetToDefault && dir != null) { try { File file = getPropertyFile(dir, name.name(), locale); if (file != null) { Reader reader = new InputStreamReader(new FileInputStream( file), "UTF8"); - map = new PropertyResourceBundle(reader); + resetMap(new PropertyResourceBundle(reader)); + found = true; } } catch (IOException e) { e.printStackTrace(); } } - if (map == null) { + if (!found) { + String bname = type.getPackage().getName() + "." + name.name(); try { - map = ResourceBundle.getBundle(type.getPackage().getName() - + "." + name.name(), locale, - new FixedResourceBundleControl()); + resetMap(ResourceBundle + .getBundle(bname, locale, type.getClassLoader(), + new FixedResourceBundleControl())); } catch (Exception e) { // We have no bundle for this Bundle - map = null; + System.err.println("No bundle found for: " + bname); + resetMap(null); + } + } + } + + /** + * Reset the backing map to the content of the given bundle, or empty if + * bundle is NULL. + * + * @param bundle + * the bundle to copy + */ + private void resetMap(ResourceBundle bundle) { + this.map.clear(); + + if (bundle != null) { + for (E field : type.getEnumConstants()) { + try { + String value = bundle.getString(field.name()); + this.map.put(field.name(), + value == null ? null : value.trim()); + } catch (MissingResourceException e) { + } } } } @@ -584,9 +628,9 @@ public class Bundle> { * the "set" methods ( {@link Bundle#setString(Enum, String)}...) at the * current time. * - * @return a snapshot to use with {@link Bundle#restoreChanges(Object)} + * @return a snapshot to use with {@link Bundle#restoreSnapshot(Object)} */ - protected Object takeChangesSnapshot() { + public Object takeSnapshot() { return new HashMap(changeMap); } @@ -598,7 +642,7 @@ public class Bundle> { * the snapshot or NULL */ @SuppressWarnings("unchecked") - protected void restoreChanges(Object snap) { + public void restoreSnapshot(Object snap) { if (snap == null) { changeMap.clear(); } else { diff --git a/src/be/nikiroo/utils/resources/TransBundle.java b/src/be/nikiroo/utils/resources/TransBundle.java index 125075a8..51101b04 100644 --- a/src/be/nikiroo/utils/resources/TransBundle.java +++ b/src/be/nikiroo/utils/resources/TransBundle.java @@ -197,26 +197,26 @@ public class TransBundle> extends Bundle { @Override public void updateFile(String path) throws IOException { String prev = locale.getLanguage(); - Object status = takeChangesSnapshot(); + Object status = takeSnapshot(); // default locale setLanguage(null); if (prev.equals(getLocaleFor(null).getLanguage())) { // restore snapshot if default locale = current locale - restoreChanges(status); + restoreSnapshot(status); } super.updateFile(path); for (String lang : getKnownLanguages()) { setLanguage(lang); if (lang.equals(prev)) { - restoreChanges(status); + restoreSnapshot(status); } super.updateFile(path); } setLanguage(prev); - restoreChanges(status); + restoreSnapshot(status); } @Override diff --git a/src/be/nikiroo/utils/test/BundleTest.java b/src/be/nikiroo/utils/test/BundleTest.java index 4b9ac7dd..a8818172 100644 --- a/src/be/nikiroo/utils/test/BundleTest.java +++ b/src/be/nikiroo/utils/test/BundleTest.java @@ -52,18 +52,24 @@ class BundleTest extends TestLauncher { addTest(new TestCase("Reload") { @Override public void test() throws Exception { - String now = b.getString(E.ONE); - b.reload(true); String def = b.getString(E.ONE); + String val = "Something"; + + b.setString(E.ONE, val); + b.updateFile(); + b.reload(true); + + assertEquals("We should have reset the bundle", def, + b.getString(E.ONE)); + b.reload(false); - assertEquals("We should not have a bundle to load", - null, def); assertEquals("We should have reloaded the same files", - now, b.getString(E.ONE)); + val, b.getString(E.ONE)); // reset values for next tests - b.reload(false); + b.reload(true); + b.updateFile(); } }); @@ -77,7 +83,7 @@ class BundleTest extends TestLauncher { assertEquals(val, setGet); // reset values for next tests - b.restoreChanges(null); + b.restoreSnapshot(null); } }); @@ -88,19 +94,19 @@ class BundleTest extends TestLauncher { String def = b.getString(E.ONE); b.setString(E.ONE, val); - Object snap = b.takeChangesSnapshot(); + Object snap = b.takeSnapshot(); - b.restoreChanges(null); + b.restoreSnapshot(null); assertEquals( "restoreChanges(null) should clear the changes", def, b.getString(E.ONE)); - b.restoreChanges(snap); + b.restoreSnapshot(snap); assertEquals( "restoreChanges(snapshot) should restore the changes", val, b.getString(E.ONE)); // reset values for next tests - b.restoreChanges(null); + b.restoreSnapshot(null); } }); @@ -203,14 +209,14 @@ class BundleTest extends TestLauncher { @Override // ...and make it public - public Object takeChangesSnapshot() { - return super.takeChangesSnapshot(); + public Object takeSnapshot() { + return super.takeSnapshot(); } @Override // ...and make it public - public void restoreChanges(Object snap) { - super.restoreChanges(snap); + public void restoreSnapshot(Object snap) { + super.restoreSnapshot(snap); } } -- 2.27.0