-
1. Re: Resource Bundle for view
nathandennis Dec 19, 2009 1:47 AM (in response to mseminaro)having the same issue after referencing a message from a backing bean. did you ever figure this out?
-
2. Re: Resource Bundle for view
mseminaro Jan 5, 2010 3:10 PM (in response to mseminaro)Unfortunately not. Looking at the SEAM source, there doesn't appear to be any way to disable this feature.
Resource files are cached for a period of time, if they exist. But the lookup failure is not cached, unfortunately, so the classpath is searched every time. A workaround I have considered is to just create empty bundles per page so that the caching would be activated. But I haven't tried this as yet.
I will report back on this thread when I do have time to learn more.
-
3. Re: Resource Bundle for view
rajendra247 Jul 9, 2010 12:27 PM (in response to mseminaro)Hopefully you got the solution already,
We had the same problem earlier,
Seam gives us the feature of page level message overrides, unfortunately this does mean that when viewId is an EL we evaluate the bean again and again.Got it resolved by bypassing seam's default behavior just by overriding
org.jboss.seam.international.Messages and SeamResourceBundle classes.Its very simple, can send you the details if you still having the problem.
-
4. Re: Resource Bundle for view
mseminaro Jul 9, 2010 12:38 PM (in response to mseminaro)No, I never did figure out a solution to this. I would appreciate it if you could share the details so I can leverage that.
Thanks!
-
5. Re: Resource Bundle for view
rajendra247 Jul 12, 2010 5:13 PM (in response to mseminaro)Hi,
First one just override the SeamResourceBunlde, Most of the code just copied from source code, here still using Seam 2.0.1GA version.
SeamResourceBundle will use the Page level ResourceBundles, i.e, method getPageResourceBundles().
We should bypass this behavior by using locale resource bundle always.
Here most of the code from super class other than getKeys() and handleGetObject() methods.
public class CustomResourceBundle extends SeamResourceBundle {
private static Map<Locale, List<ResourceBundle>> bundleCache = new ConcurrentHashMap<Locale, List<ResourceBundle>>();
public static java.util.ResourceBundle getBundle() {
return java.util.ResourceBundle.getBundle(CustomResourceBundle.class.getName(), org.jboss.seam.core.Locale.instance());
}
@Override
public Enumeration<String> getKeys() {
List<ResourceBundle> bundles = getBundlesForCurrentLocale();
Enumeration<String>[] enumerations = new Enumeration[bundles.size()];
int i = 0;
for (ResourceBundle bundle : bundles) {
enumerations[i++] = bundle.getKeys();
}
return new EnumerationEnumeration<String>(enumerations);
}
@Override
public Locale getLocale() {
return org.jboss.seam.core.Locale.instance();
}
@Override
protected Object handleGetObject(String key) {
if (!Contexts.isApplicationContextActive()) {
return null;
}
for (java.util.ResourceBundle littleBundle : getBundlesForCurrentLocale()) {
try {
return interpolate(littleBundle.getObject(key));
} catch (MissingResourceException mre) {
}
}
return null; // superclass is responsible for throwing MRE
}
/**
* Gets bundles for current locale from the cache, creating them if need be.
* @return
*/
private List<java.util.ResourceBundle> getBundlesForCurrentLocale() {
Locale instance = org.jboss.seam.core.Locale.instance();
List<ResourceBundle> bundles = bundleCache.get(instance);
if (bundles == null) {
bundles = loadBundlesForCurrentLocale();
bundleCache.put(instance, bundles);
}
return bundles;
}
/**
* One time load of bundles for a locale
* @return
*/
private List<ResourceBundle> loadBundlesForCurrentLocale() {
List<ResourceBundle> bundles = new ArrayList<ResourceBundle>();
ResourceLoader resourceLoader = ResourceLoader.instance();
for (String bundleName : resourceLoader.getBundleNames()) {
ResourceBundle bundle = resourceLoader.loadBundle(bundleName);
if (bundle != null)
bundles.add(bundle);
}
ResourceBundle bundle = resourceLoader.loadBundle("ValidatorMessages");
if (bundle != null) {
bundles.add(bundle);
}
bundle = resourceLoader.loadBundle("org/hibernate/validator/resources/DefaultValidatorMessages");
if (bundle != null)
bundles.add(bundle);
bundle = resourceLoader.loadBundle("javax.faces.Messages");
if (bundle != null)
bundles.add(bundle);
return Collections.unmodifiableList(bundles);
}
private Object interpolate(Object message) {
return message != null && message instanceof String ? Interpolator.instance().interpolate((String) message) : message;
}
}
And the second part is our application need to use our CustomResourceBundle instead SeamResourceBundle,
this can be done by overriding the Messages behavior.
Extend the Messages with same @Name as it super class with @Install(precedence=APPLICATION).
Override createMap method, just to copy from the source, only change is need to get the bundle instance from our custom implementation of ResourceBundle.
The Implementation goes something like this.
@Scope(ScopeType.STATELESS)
@BypassInterceptors
@Name("org.jboss.seam.international.messagesFactory")
@Install(precedence = APPLICATION)
public class Messages extends org.jboss.seam.international.Messages {
@SuppressWarnings("unchecked")
protected Map createMap() {
// AbstractMap uses the implementation of entrySet to perform all its
// operations - for a resource bundle this is very inefficient for keys
return new AbstractMap<String, String>() {
private java.util.ResourceBundle bundle = CustomResourceBundle.getBundle();
@Override
public String get(Object key) {
if (key instanceof String) {
String resourceKey = (String) key;
String resource = null;
if (bundle != null) {
try {
resource = bundle.getString(resourceKey);
} catch (MissingResourceException mre) {
// Just swallow
}
}
return resource == null ? resourceKey : resource;
} else {
return null;
}
}
@Override
public Set<Map.Entry<String, String>> entrySet() {
Enumeration<String> keys = bundle.getKeys();
Map<String, String> map = new HashMap<String, String>();
while (keys.hasMoreElements()) {
String key = keys.nextElement();
map.put(key, get(key));
}
return Collections.unmodifiableSet(map.entrySet());
}
@Override
public boolean containsKey(Object key) {
return get(key) != null;
}
@Override
public Set<String> keySet() {
Enumeration<String> keys = bundle.getKeys();
return new HashSet<String>(Collections.list(keys));
}
@Override
public int size() {
return keySet().size();
}
};
}
}
Thats it..
Hope this will help you.