this.type = type;
this.name = name;
this.changeMap = new HashMap<String, String>();
- setBundle(name, Locale.getDefault());
+ setBundle(name, Locale.getDefault(), false);
}
/**
/**
* Reload the {@link Bundle} data files.
+ *
+ * @param resetToDefault
+ * reset to the default configuration (do not look into the
+ * possible user configuration files, only take the original
+ * configuration)
*/
- public void reload() {
- setBundle(name, null);
+ public void reload(boolean resetToDefault) {
+ setBundle(name, null, resetToDefault);
}
/**
return true;
}
- try {
- map.getObject(key);
- return true;
- } catch (MissingResourceException e) {
- return false;
+ if (map != null) {
+ try {
+ map.getObject(key);
+ return true;
+ } catch (MissingResourceException e) {
+ }
}
+
+ return false;
}
/**
return changeMap.get(key);
}
- if (containsKey(key)) {
+ if (map != null && containsKey(key)) {
return map.getString(key);
}
* the name of the bundle to load
* @param locale
* the {@link Locale} to use
+ * @param resetToDefault
+ * reset to the default configuration (do not look into the
+ * possible user configuration files, only take the original
+ * configuration)
*/
- protected void setBundle(Enum<?> name, Locale locale) {
+ protected void setBundle(Enum<?> name, Locale locale, boolean resetToDefault) {
map = null;
changeMap.clear();
String dir = Bundles.getDirectory();
- if (dir != null) {
+ if (!resetToDefault && dir != null) {
try {
File file = getPropertyFile(dir, name.name(), locale);
if (file != null) {
}
if (map == null) {
- map = ResourceBundle.getBundle(type.getPackage().getName() + "."
- + name.name(), locale, new FixedResourceBundleControl());
+ try {
+ map = ResourceBundle.getBundle(type.getPackage().getName()
+ + "." + name.name(), locale,
+ new FixedResourceBundleControl());
+ } catch (Exception e) {
+ // We have no bundle for this Bundle
+ map = null;
+ }
+ }
+ }
+
+ /**
+ * Take a snapshot of the changes in memory in this {@link Bundle} made by
+ * the "set" methods ( {@link Bundle#setString(Enum, String)}...) at the
+ * current time.
+ *
+ * @return a snapshot to use with {@link Bundle#restoreChanges(Object)}
+ */
+ protected Object takeChangesSnapshot() {
+ return new HashMap<String, String>(changeMap);
+ }
+
+ /**
+ * Restore a snapshot taken with {@link Bundle}, or reset the current
+ * changes if the snapshot is NULL.
+ *
+ * @param snap
+ * the snapshot or NULL
+ */
+ @SuppressWarnings("unchecked")
+ protected void restoreChanges(Object snap) {
+ if (snap == null) {
+ changeMap.clear();
+ } else {
+ if (snap instanceof Map) {
+ changeMap = (Map<String, String>) snap;
+ } else {
+ throw new Error(
+ "Restoring changes in a Bundle must be done on a changes snapshot, "
+ + "or NULL to discard current changes");
+ }
}
}
import java.util.Locale;
import java.util.regex.Pattern;
-import be.nikiroo.utils.resources.Bundles;
-
/**
* This class manages a translation-dedicated Bundle.
* <p>
private void setLanguage(String language) {
defaultLocale = (language == null || language.length() == 0);
locale = getLocaleFor(language);
- setBundle(name, locale);
+ setBundle(name, locale, false);
}
@Override
- public void reload() {
- setBundle(name, locale);
+ public void reload(boolean resetToDefault) {
+ setBundle(name, locale, resetToDefault);
}
@Override
@Override
public void updateFile(String path) throws IOException {
String prev = locale.getLanguage();
+ Object status = takeChangesSnapshot();
- setLanguage(null); // default locale
+ // default locale
+ setLanguage(null);
+ if (prev.equals(getLocaleFor(null).getLanguage())) {
+ // restore snapshot if default locale = current locale
+ restoreChanges(status);
+ }
super.updateFile(path);
for (String lang : getKnownLanguages()) {
setLanguage(lang);
+ if (lang.equals(prev)) {
+ restoreChanges(status);
+ }
super.updateFile(path);
}
setLanguage(prev);
+ restoreChanges(status);
}
@Override
package be.nikiroo.utils.test;
import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
import be.nikiroo.utils.IOUtils;
import be.nikiroo.utils.resources.Bundle;
private File tmp;
private B b = new B();
- protected boolean isMain() {
- return true;
- }
-
public BundleTest(String[] args) {
this("Bundle test", args);
}
protected BundleTest(String name, String[] args) {
super(name, args);
- addTests();
-
- if (isMain()) {
- addSeries(new BundleTest("After saving/reloading the resources",
- args) {
- @Override
- protected void start() throws Exception {
- tmp = File.createTempFile("nikiroo-utils", ".test");
- tmp.delete();
- tmp.mkdir();
- b.updateFile(tmp.getAbsolutePath());
- Bundles.setDirectory(tmp.getAbsolutePath());
- b.reload();
- }
+ for (TestCase test : getSimpleTests()) {
+ addTest(test);
+ }
- @Override
- protected void stop() {
- IOUtils.deltree(tmp);
+ addSeries(new TestLauncher("After saving/reloading the resources", args) {
+ {
+ for (TestCase test : getSimpleTests()) {
+ addTest(test);
}
+ }
- @Override
- protected boolean isMain() {
- return false;
- }
- });
- }
+ @Override
+ protected void start() throws Exception {
+ tmp = File.createTempFile("nikiroo-utils", ".test");
+ tmp.delete();
+ tmp.mkdir();
+ b.updateFile(tmp.getAbsolutePath());
+ Bundles.setDirectory(tmp.getAbsolutePath());
+ b.reload(false);
+ }
+
+ @Override
+ protected void stop() {
+ IOUtils.deltree(tmp);
+ }
+ });
+
+ addSeries(new TestLauncher("Read/Write support", args) {
+ {
+ 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);
+ 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));
+
+ // reset values for next tests
+ b.reload(false);
+ }
+ });
+
+ addTest(new TestCase("Set/Get") {
+ @Override
+ public void test() throws Exception {
+ String val = "Newp";
+ b.setString(E.ONE, val);
+ String setGet = b.getString(E.ONE);
+
+ assertEquals(val, setGet);
+
+ // reset values for next tests
+ b.restoreChanges(null);
+ }
+ });
+
+ addTest(new TestCase("Snapshots") {
+ @Override
+ public void test() throws Exception {
+ String val = "Newp";
+ String def = b.getString(E.ONE);
+
+ b.setString(E.ONE, val);
+ Object snap = b.takeChangesSnapshot();
+
+ b.restoreChanges(null);
+ assertEquals(
+ "restoreChanges(null) should clear the changes",
+ def, b.getString(E.ONE));
+ b.restoreChanges(snap);
+ assertEquals(
+ "restoreChanges(snapshot) should restore the changes",
+ val, b.getString(E.ONE));
+
+ // reset values for next tests
+ b.restoreChanges(null);
+ }
+ });
+
+ addTest(new TestCase("updateFile with changes") {
+ @Override
+ public void test() throws Exception {
+ String val = "Go to disk! (UTF-8 test: 日本語)";
+
+ String def = b.getString(E.ONE);
+ b.setString(E.ONE, val);
+ b.updateFile(tmp.getAbsolutePath());
+ b.reload(false);
+
+ assertEquals(val, b.getString(E.ONE));
+
+ // reset values for next tests
+ b.setString(E.ONE, def);
+ b.updateFile(tmp.getAbsolutePath());
+ b.reload(false);
+ }
+ });
+ }
+
+ @Override
+ protected void start() throws Exception {
+ tmp = File.createTempFile("nikiroo-utils", ".test");
+ tmp.delete();
+ tmp.mkdir();
+ b.updateFile(tmp.getAbsolutePath());
+ Bundles.setDirectory(tmp.getAbsolutePath());
+ b.reload(false);
+ }
+
+ @Override
+ protected void stop() {
+ IOUtils.deltree(tmp);
+ }
+ });
}
- private void addTests() {
+ private List<TestCase> getSimpleTests() {
String pre = "";
- addTest(new TestCase(pre + "getString simple") {
+ List<TestCase> list = new ArrayList<TestCase>();
+
+ list.add(new TestCase(pre + "getString simple") {
@Override
public void test() throws Exception {
assertEquals("un", b.getString(E.ONE));
}
});
- addTest(new TestCase(pre + "getStringX with null suffix") {
+ list.add(new TestCase(pre + "getStringX with null suffix") {
@Override
public void test() throws Exception {
assertEquals("un", b.getStringX(E.ONE, null));
}
});
- addTest(new TestCase(pre + "getStringX with empty suffix") {
+ list.add(new TestCase(pre + "getStringX with empty suffix") {
@Override
public void test() throws Exception {
assertEquals(null, b.getStringX(E.ONE, ""));
}
});
- addTest(new TestCase(pre + "getStringX with existing suffix") {
+ list.add(new TestCase(pre + "getStringX with existing suffix") {
@Override
public void test() throws Exception {
assertEquals("un + suffix", b.getStringX(E.ONE, "suffix"));
}
});
- addTest(new TestCase(pre + "getStringX with not existing suffix") {
+ list.add(new TestCase(pre + "getStringX with not existing suffix") {
@Override
public void test() throws Exception {
assertEquals(null, b.getStringX(E.ONE, "fake"));
}
});
- addTest(new TestCase(pre + "getString with UTF-8 content") {
+ list.add(new TestCase(pre + "getString with UTF-8 content") {
@Override
public void test() throws Exception {
assertEquals("日本語 Nihongo", b.getString(E.JAPANESE));
}
});
+
+ return list;
}
/**
super(E.class, N.bundle_test);
}
+ @Override
+ // ...and make it public
+ public Object takeChangesSnapshot() {
+ return super.takeChangesSnapshot();
+ }
+
+ @Override
+ // ...and make it public
+ public void restoreChanges(Object snap) {
+ super.restoreChanges(snap);
+ }
}
/**
private class SetupException extends Exception {
private static final long serialVersionUID = 1L;
- public SetupException(Exception e) {
+ public SetupException(Throwable e) {
super(e);
}
}
private class TearDownException extends Exception {
private static final long serialVersionUID = 1L;
- public TearDownException(Exception e) {
+ public TearDownException(Throwable e) {
super(e);
}
}
for (TestCase test : tests) {
print(depth, test.getName());
- Exception ex = null;
+ Throwable ex = null;
try {
try {
test.setUp();
- } catch (Exception e) {
+ } catch (Throwable e) {
throw new SetupException(e);
}
test.test();
try {
test.tearDown();
- } catch (Exception e) {
+ } catch (Throwable e) {
throw new TearDownException(e);
}
- } catch (Exception e) {
+ } catch (Throwable e) {
ex = e;
}
* @param error
* the {@link Exception} it ran into if any
*/
- private void print(int depth, Exception error) {
+ private void print(int depth, Throwable error) {
if (error != null) {
System.out.println(" " + koString);
StringWriter sw = new StringWriter();