First of all, I wonder why you selected java.util.ResourceBundle over java.util.Properties . Given how your question is worded, you don't seem to care about localization / internationalization, nor about inheriting package files.
With Properties this is unusually simple because it implements a Map , which in turn offers a putAll() method to combine 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);
If you really insist on using a ResourceBundle , it's best to create a custom ResourceBundle in which you load the custom Control .
Assuming you have the following entry in master.properties , which is a delimited string with the 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 are left out, it's up to you)
This can be used as:
ResourceBundle bundle = new MultiResourceBundle("master");
Balusc
source share