I am teaching myself Java program localization using java.util.Locale and java.util.ResourceBundle. To this end I wrote a very simple Java app to test English, French and default language message bundles. The program works fine. I am running Eclipse Kepler SR2 on Windows.
My question relates to the deployment of the properties files used by ResourceBundle.getBundle (I will get to my question below) but first a bit about what I have already tried in terms of laying out my demo app and deploying it.
When I first called ResourceBundle.getBundle (see LocaleWrapper.java, below) I discovered the path it searches defaults to the deployment bin folder.
The ResourceBundle Javadoc doesn't talk about deployment folders, nor does the Oracle tutorial on Java internationalization that I was following.
So, to avoid dumping my properties files all in bin, I settled on creating a separate package (demo.locale) for my locale wrapper class and added all of the properties files to that package, as follows:
My Eclipse project named LocaleDemo consists of 5 source files in 2 packages, as follows:
src/demo/DemoApp.java
src/demo.locale/LocaleWrapper.java (wraps java.util.Locale, java.util.ResourceBundle)
src/demo.locale/MessageBundle.properties (default messages, same as English/US)
src/demo.locale/MessageBundle_en_US.properties (English/US messages)
src/demo.locale/MessageBundle_fr_FR.properties (French/France messages)
When the application is deployed it ends up under the bin folder, as follows:
bin/demo/DemoApp.class
bin/demo/locale/LocaleWrapper.class
bin/demo/locale/MessageBundle.properties
bin/demo/locale/MessageBundle_en_US.properties
bin/demo/locale/MessageBundle_fr_FR.properties
(I excluded package info files from these lists for clarity.)
So to get to my actual question:
My concern with this type of deployment is that it mixes properties files with class files.
I tried to separate them by creating a data folder at the same level as my src folder in Ecipse, and I put all the properties files in there, and added the data folder to my build path; however, when I deployed the app all of the properties files simply end up in the bin folder at the top level above the package folders (e.g. bin/MessageBundle.properties).
This was not satisfactory, so I reverted to putting them with the demo.locale package. The layout I settled on was accepted as an answer in this stackoverflow question:
However, I do agree with another poster in that thread who said to separate classes and data, which is what I would prefer, but there was no example given how to do that.
So that is my question: is there a clean way in Eclipse to create a distinct data folder for the application and have the properties files deployed in that folder, not just dumped at the root folder of the project, which is what happened when I tried it.
I am looking for some specific examples of what programmers have done, or even better a reference to some official documentation on this subject -- I could not find anything specifically mentioning how this might be done in practice, only generalities.
As an appendix I have included the source code for my two Java classes below. The resource files I use are straight from the Oracle tutorial that I linked above.
DemoApp.java
package demo;
import demo.locale.LocaleWrapper;
public class DemoApp {
public static void main(String[] args) {
LocaleWrapper intl = null;
// English/USA
intl = new LocaleWrapper("en", "US");
doTest(intl);
// French/France
intl.changeLocale("fr", "FR");
doTest(intl);
// non-existent language/country will use default
intl.changeLocale("sp", "MX");
doTest(intl);
}
private static void doTest(LocaleWrapper intl) {
System.out.println("Testing: " + intl.getLanguage() + "_" + intl.getCountry());
System.out.println(" " + intl.getString("greetings"));
System.out.println(" " + intl.getString("farewell"));
System.out.println(" " + intl.getString("inquiry"));
System.out.println();
}
}
LocaleWrapper.java
package demo.locale;
import java.util.Locale;
import java.util.ResourceBundle;
/**
* Internationalization using java.util.Locale and java.util.ResourceBundle.
*/
public class LocaleWrapper {
private static final String PATH = "demo/locale/MessageBundle";
private String language = null;
private String country = null;
private Locale locale = null;
private ResourceBundle messages = null;
public LocaleWrapper(String language, String country) {
super();
this.language = language;
this.country = country;
this.locale = new Locale(language, country);
messages = ResourceBundle.getBundle(PATH, this.locale);
}
public void changeLocale(String language, String country) {
this.language = language;
this.country = country;
this.locale = new Locale(language, country);
messages = ResourceBundle.getBundle(PATH, this.locale);
}
/**
* Get an internationalized string based on it's key.
*
* @param key
* Message key.
* @return Internationalized message string.
*/
public String getString(String key) {
return messages.getString(key);
}
// getters
public String getLanguage() {
return language;
}
public String getCountry() {
return country;
}
}