Obviously ResourceBundle
requires a property file like syntax in the files it finds.
We have a situation where we want to use entire files (in our case HTML-files) as "values". This means that we don't have keys as such. Well, maybe the filename would work as the key.
Here's a directory tree:
src/
main/
resources/
html/
content.html
content_de.html
content_fr.html
content_es.html
order.html
order_de.html
order_fr.html
order_es.html
Now we need logic to find the correct file based on the current locale. If the current locale is German and I'm looking for html/content.html
file, it should find html/content_de.html
. It doesn't necessarily need to load it right away. Is there some existing mechanism in Java? Do we need to do this manually?
Due to some restrictions, we are currently planning to not use any third-party libraries. So if there is something available in Java 6 SE, it would be our best choice; however, if you know of a third-party library, feel free to name it.
EDIT #1:
An obvious solution would be to have a key in messages.properties
to name that HTML-file. While that would work it may become a pain in the butt on the long run (and besides that I don't think this would solve all our issues with this).
EDIT #2: I forgot to say that this is a desktop application.
To show that I wasn't doing nothing, here are two attempts using an "on our own"-approach:
The first attempt with locale-postfix build up and straight forward loading of resources:
public void attempt1(String baseName, String extension) {
List<String> locales = buildLocaleStrings(Locale.getDefault());
String resourceFound = null;
for (String locale : locales) {
String resourceName = baseName + locale + "." + extension;
URL resource = getClass().getClassLoader().getResource(resourceName);
if (resource != null) {
resourceFound = resourceName;
break;
}
}
System.out.println("found #1: " + resourceFound);
}
private List<String> buildLocaleStrings(Locale localeBase) {
String locale = "_" + localeBase;
List<String> locales = new ArrayList<String>();
while (locale.length() > 0) {
locales.add(locale);
locale = locale.replaceFirst("_[^_]*?$", "");
}
locales.add("");
return locales;
}
The second attempt "abusing" ResourceBundle
and its toString()
:
public void attempt2(String baseName, final String extension) {
ResourceBundle.Control control = new ResourceBundle.Control() {
private String resourceFound = null;
@Override
public List<String> getFormats(String baseName) {
return Arrays.asList(extension);
}
@Override
public ResourceBundle newBundle(String baseName, Locale locale, String format, ClassLoader loader, boolean reload) throws IllegalAccessException, InstantiationException, IOException {
String bundleName = toBundleName(baseName, locale);
String resourceName = toResourceName(bundleName, format);
if (loader.getResource(resourceName) != null) {
resourceFound = resourceName;
return new ResourceBundle() {
@Override
public Enumeration<String> getKeys() {
return null;
}
@Override
protected Object handleGetObject(String key) {
return null;
}
};
}
return null;
}
@Override
public String toString() {
return resourceFound;
}
};
ResourceBundle.getBundle(baseName, control);
System.out.println("found #2: " + control.toString());
}
Sample calls:
public void proof() {
attempt1("html/content", "html");
attempt2("html/content", "html");
}
Both find the same file.
To be honest, I don't like neither.