How do I know where the ResourceBundle came from?

Given the ResourceBundle object, is there a way to get the url or other indicator of where it was found when it was viewed?

The ResourceBundle is created with:

ResourceBundle rb = ResourceBundle.getBundle("filename");

      

And in most cases it is loaded from the subdir / filename.properties file. I would like to be able to programmatically reference this location rather than hardcoding it.

+2


source to share


3 answers


Try the following:

URL location = getClass().getClassLoader().getResource("filename.properties");

      



This is the mechanism used ResourceBundle

to find a resource. Check out the [Javadoc for ResourceBundle

] [1] for how it maps a package name to an underlying resource. You may need to be smarter if you have local and other items.

[1]: http://java.sun.com/javase/6/docs/api/java/util/ResourceBundle.html#getBundle(java.lang.String , java.util.Locale, java.lang.ClassLoader, java.util.ResourceBundle.Control)

+2


source


Judging from the documentation , you can't, because it is a class that can be subclassed in arbitrary ways (not necessarily related to the URL or class name) and there is no reference to the creator.



Also note the constructor for PropertyResourceBundle : an InputStream is required, which can be obtained anywhere: you can provide your own InputStream by subclassing it to provide arbitrary data that is generated out of thin air.

+2


source


If you can modify all calls to ResourceBundle.getResource, you can pass your own ResourceBundle.Control implementation to cache the url from which the allowed bundle is actually loaded

public class ResourceBundleSourceControl extends ResourceBundle.Control {

private static final Map<ResourceBundle, URL> sources = 
    new HashMap<ResourceBundle, URL>();     

private String bundleName;

@Override
public ResourceBundle newBundle(String baseName, Locale locale, String format,
        ClassLoader loader, boolean reload) throws IllegalAccessException,
        InstantiationException, IOException {
    ResourceBundle rb =  super.newBundle(baseName, locale, format, loader, reload);
    URL sourceURL = loader.getResource(toResourceName(bundleName, "properties"));
    if(rb != null && sourceURL != null) {
        synchronized(sources) {
            sources.put(rb, sourceURL);
        }
    }
    return rb;
}

@Override
public String toBundleName(String arg0, Locale arg1) {
    bundleName = super.toBundleName(arg0, arg1);
    return bundleName;
}

public static URL getSourceURL(ResourceBundle b) {
    synchronized (sources) {
        return sources.get(b);              
    }
}

      

The downside is that you need to pass an instance of this class for every call to ResourceBundle.getBundle. Since resource bundles are lazily cached, you cannot be sure that every retrieval of the bundle will actually load it, which is what Control needs to implement to catch it.

After downloading the package, you can use the static getSourceURL method to find the URL from which it was downloaded:

ResourceBundle rb = ResourceBundle.getBundle(
    "props.Default", new ResourceBundleSourceControl()); 
System.out.println(
    "URL: " + ResourceBundleSourceControl.getSourceURL(rb));

      

+2


source







All Articles