In Java how do I find out what languages I have available my Resource Bundle

后端 未结 4 2028
梦如初夏
梦如初夏 2021-01-01 11:26

I have some resource bundles packaged in my main jar

widget_en.properties
widget_de.properties

I retrieve a resource bundle based on my de

相关标签:
4条回答
  • 2021-01-01 11:47

    If you really package the resource files inside your JAR, then I would do it like this:

    public static void main(String[] args) {
      Set<ResourceBundle> resourceBundles = getResourceBundles(A.class.getName());
      if (resourceBundles.isEmpty())
        // ...
    }
    
    public static Set<ResourceBundle> getResourceBundles(String baseName) {
      Set<ResourceBundle> resourceBundles = new HashSet<>();
    
      for (Locale locale : Locale.getAvailableLocales()) {
        try {
          resourceBundles.add(ResourceBundle.getBundle(baseName, locale));
        } catch (MissingResourceException ex) {
          // ...
        }
      }
    
      return Collections.unmodifiableSet(resourceBundles);
    }
    

    If you care about your JARs then you would at least get a set containing the default resource for a given baseName.

    If you have only resources with names like baseName_<country> this method works perfectly, because only those ResourceBundles will be added to the set which are present in your JAR. It'll work even if you decide you need separate baseName_en_US and baseName_en_UK resources, which is not unheard of.

    Shameless self-plug: I wrote a ResourceBundle.Control which takes a Charset as its argument, you might be interested in it if you want to load UTF-8 encoded resources files. It's available at GitHub.

    0 讨论(0)
  • 2021-01-01 11:47

    A solve it by listing files.

    public class JavaApplication1 {
    
        public static final ArrayList<String> LOCALES = new ArrayList<>();
    
        static {
            try {
                File f = new File(JavaApplication1.class.getResource("/l10n").toURI());
                final String bundle = "widget_";// Bundle name prefix.
                for (String s : f.list(new FilenameFilter() {
                    @Override
                    public boolean accept(File dir, String name) {
                        return name.startsWith(bundle);
                    }
                })) {
                    LOCALES.add(s.substring(bundle.length(), s.indexOf('.')));
                }
            } catch (URISyntaxException x) {
                throw new RuntimeException(x);
            }
            LOCALES.trimToSize();
        }
    
        ...
    
    }
    
    0 讨论(0)
  • 2021-01-01 11:52

    I don't think there is an API for this because new valid locale objects can be created on the fly:

    Locale locale = new Locale("abcd");
    

    without the need to register it somewhere. And then you can use a resource bundle widget_abcd.properties without restrictions:

    ResourceBundle resource= ResourceBundle.getBundle("widget", new Locale("abcd"));
    

    From the java.util.Locale API docs:

    Because a Locale object is just an identifier for a region, no validity check is performed when you construct a Locale. If you want to see whether particular resources are available for the Locale you construct, you must query those resources.

    To solve the problem you can still iterate over all files called "widget_" in the resource directory and discover the new added resource bundles.

    Note that Locale.getAvailableLocales() is not 100% sure for the above reason: you might some day define a non standard locale. But if you'll add only a few standard locales you can use this static method to iterate over the system locales and get the corresponding bundles.

    0 讨论(0)
  • 2021-01-01 12:06

    If you can make two basic assumptions:

    1) You have a default resource bundle with no locale, or at least one locale that you know is there.

    2) All your resources are in the same location (ie. the same path within a single jar file)

    Then you can get the URL for a single resource:

    URL url = SomeClass.class.getClassLoader().getResource("widget.properties");
    

    once you have that, you should be able to parse the URL.

    If you use commons-vfs, you should be able to convert the URL into a FileObject:

    FileSystemManager manager = VFS.getManager();
    FileObject resource = manager.resolveFile(url.toExternalForm());
    FileObject parent = resource.getParent();
    FileObject children[] = parent.getChildren();
    // figure out which ones are bundles, and parse the names into a list of locales.
    

    This will save you the trouble of dealing with the complexities of jar: style url's and such, since vfs will handle that for you.

    0 讨论(0)
提交回复
热议问题