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 mod开发者_JAVA技巧ules. Is it possible to achieve this?
master.properties
==>
master.properties
include moduleA.properties
include moduleB.properties
Let me know?
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
}
}
More Food for thought than a tested solution.
XML files support entities to inline text from other files during parsing. If seen complex xml files, where this technique has been used to modularise the files.
Properties
now supports two file formats, the common .properties
format with key/value pairs and an xml formats. Properties
can load and store to/from xml files.
ResourceBundle
has one direct subclass: PropertyResourceBundle
. It looks like this class is actually limited to the older key/value pair format, but it could be used to implement another class, like XMLPropertyResourceBundle
which is capable of reading properties from xml files where the entity
trick could help to modularize those files.
If this works - transforming the existing property files to xml properties files should be easy, just use the Properties
class, read from standard format and store to XML.
精彩评论