Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to include resource bundle files within a resource bundle

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?

like image 720
Jason Avatar asked Jan 06 '11 11:01

Jason


People also ask

How do you add a ResourceBundle?

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.

Where does ResourceBundle properties file go?

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.

How do I use resource bundles?

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.

How can we use ResourceBundle properties file in JSP?

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.


2 Answers

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");
like image 101
BalusC Avatar answered Sep 23 '22 21:09

BalusC


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
  }
}
like image 31
jmj Avatar answered Sep 21 '22 21:09

jmj