The sling/i18n module, I added last week, provides the implementation of
the SlingHttpServletRequest.getResourceBundle(Locale) and
SlingHttpServletRequest.getLocale[s]() methods. In particular the
ResourceBundle is loaded from the repository. See also  for more
As can be seen resources for the ResourceBundle are found by quering the
JCR repository for certain nodes. This query might result in certain
resources being hidden by others. For example consider a resource
"Label"->"Etikett" in a node /apps/myapp/i18n/de/key and another
resource "Label"->"Kleber" /libs/otherapp/i18n/de/label. In this case -
agreed that it is esoteric, but perfectly possible - two resources with
the same key provide different messages.
To try to minimize the effects and risks, I would now like to propose
two extensions: (1) ResourceBundle base names and (2) resource hiding.
(1) Base Names
The concept for ResourceBundle base names is derived from the
ResourceBundle.getBundle(String baseName) factory method, which returns
a ResourceBundle for the given base name. While the
ResourceBundle.getBundle factory method looks for ResourceBundle
implementations (e.g. ListResourceBundle class or a properties file for
the PropertyResourceBundle class), the Sling implementation of a new
method uses an extended query to find the matching resources.
The basic query is to find the resources below nodes which have a node
type of mix:language and a property jcr:language whose value is the
string representation of the Locale. The extended query would also
consider a new property sling:basename: A lanugage node is considered if
the jcr:language property matches the Locale and the sling:basename
property matches the baseName.
The sling:basename property is defined in a new mixin node type
which allows requests to easily get "base-named" resource bundles.
(2) Resource hiding
The second concept, I would like to propose is that the
ResourceResolver.getSearchPath() is applied to resolve key collisions.
In the above example of /apps/myapp/i18n/de/key
and /libs/otherapp/i18n/de/label both providing a "Label" resource we
can select which resource to actually use by applying the search path
and using that entry whose path starts with the earlier search path.
Given the search path would be [ "/apps", "/libs" ], the "Label"
resource from /apps/myapp/i18n/de/key because the path /apps comes
before /libs (for /libs/otherapp/i18n/de/label).