We are using java.util.ResourceBundle
to load property information. Our property file has grown so huge and we are thinking of splitting the master property file into several sub modules. Is it possible to achieve this?
master.properties
==>
master.properties
include moduleA.properties
include moduleB.properties
Let me know?
Create a new resource bundleIn the Project tool window, select the directory where the new resource bundle should be created. From the main menu, select File | New | Resource Bundle, or press Alt+Insert and click Resource Bundle. In the dialog that opens, specify the base name of the resource bundle.
ResourceBundle property files contain locale-specific objects for use by Java classes. The ResourceBundle property file must be placed somewhere in the CLASSPATH . Typically this is best accomplished by placing the ResourceBundle properties file in the same directory as the gear message class that it maps to.
First you need a Locale instance. Then you pass that Locale instance to the ResourceBundle. getBundle() method along with the name of the resource bundle to load. Finally you can access the localized values in the ResourceBundle via its different getString() and getObject() etc.
Resource bundles contain locale-specific objects. Resource bundles contain key/value pairs. When your program needs a locale-specific resource, you keep all the keys common to all the locale but you can have translated values specific to locale. Resource bundles help in providing specific content to locale.
First of all, I wonder why you've chosen java.util.ResourceBundle
over java.util.Properties
. Given how your question is formulated, you don't seem to care about localization/internationalization nor about bundle file inheritance.
With Properties
it's extraordinary easy since it implements Map
which in turn offers a putAll()
method to merge another map. Kickoff example:
Properties master = new Properties();
master.load(masterInput);
Properties moduleA = new Properties();
moduleA.load(moduleAinput);
master.putAll(moduleA);
Properties moduleB = new Properties();
moduleB.load(moduleBinput);
master.putAll(moduleB);
// Now `master` contains the properties of all files.
If you really insist in using ResourceBundle
, your best bet is to create a custom ResourceBundle
wherein you contol the loading by a custom Control
.
Assuming that you've the following entry in master.properties
which represents a commaseparated string with base names of the module properties files:
include=moduleA,moduleB
Then the following custom ResourceBundle
example should work:
public class MultiResourceBundle extends ResourceBundle {
protected static final Control CONTROL = new MultiResourceBundleControl();
private Properties properties;
public MultiResourceBundle(String baseName) {
setParent(ResourceBundle.getBundle(baseName, CONTROL));
}
protected MultiResourceBundle(Properties properties) {
this.properties = properties;
}
@Override
protected Object handleGetObject(String key) {
return properties != null ? properties.get(key) : parent.getObject(key);
}
@Override
@SuppressWarnings("unchecked")
public Enumeration<String> getKeys() {
return properties != null ? (Enumeration<String>) properties.propertyNames() : parent.getKeys();
}
protected static class MultiResourceBundleControl extends Control {
@Override
public ResourceBundle newBundle(
String baseName, Locale locale, String format, ClassLoader loader, boolean reload)
throws IllegalAccessException, InstantiationException, IOException
{
Properties properties = load(baseName, loader);
String include = properties.getProperty("include");
if (include != null) {
for (String includeBaseName : include.split("\\s*,\\s*")) {
properties.putAll(load(includeBaseName, loader));
}
}
return new MultiResourceBundle(properties);
}
private Properties load(String baseName, ClassLoader loader) throws IOException {
Properties properties = new Properties();
properties.load(loader.getResourceAsStream(baseName + ".properties"));
return properties;
}
}
}
(trivial exception handling and localization handling is left aside, this is up to you)
This can be used as:
ResourceBundle bundle = new MultiResourceBundle("master");
You can programatically, however, construct ResourceBundle but as you are saying your file is huge then what if it is loaded into memory.
update
public class Resource extends java.util.ResourceBundle {
public Object handleGetObject(String key) {
//code
}
public Enumeration getKeys() {
//code
}
}
then for IN locale
import java.util.*;
public class Resource_en_IN extends Resource{
public Object handleGetObject(String key) {
//code
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With