@Scope(APPLICATION) | @BypassInterceptors | @Name("org.jboss.seam.core.resourceLoader") | public class ExtendedResourceLoader extends | org.jboss.seam.core.ResourceLoader { | | /** | * Method called to load a bundle | * @param bundleName the name of the bundle to load. | * @return the ResourceBundle. | */ | public ResourceBundle loadBundle(final String bundleName) { | return new CustomResourceBundle(); | } | | /** | * Private ResourceBundle fetching messages from the database | */ | private class CustomResourceBundle extends ResourceBundle{ | java.util.Locale locale; | //the Locale of that ResourceBundle | Map<String,String> map; | //this map store the messages in the database | | public CustomResourceBundle(){ | locale = Locale.instance(); | } | | @Override | public Enumeration<String> getKeys() { | if(map == null){ | map = new HashMap<String,String>(); | } | map = fetchExpressionsForLocale(locale.toString()); | Vector v = new Vector(map.keySet()); | return v.elements(); | } | | @Override | protected Object handleGetObject(String key) { | java.util.Locale locale = org.jboss.seam.core.Locale.instance(); | if(map==null) | getKeys(); | if(DBControl.instance().isDirtyLocale(locale.toString()) || DBControl.instance().isDirtyLocale("ALL")){ | /*checking if this ResourceBundle is dirty, if so, re-fetching updated datas from the database. It might not be a nice way to check it, but I didn't find an other way.*/ | getKeys(); | DBControl.instance().removeDirtyLocale(locale.toString()); | } | if(map.containsKey(key)) | return map.get(key); | else | return key; | //returning the key if no proper message were found | } | } | | /** | * Fetching the expressions from the database matching the current Locale | * @param locale | * @return a map containing the translation | */ | private Map<String,String> fetchExpressionsForLocale(String locale){ | EntityManager entityManager = (EntityManager) Component.getInstance("entityManager"); | Map<String,String> map = new HashMap<String,String>(); | boolean found = false; | List<Message> messages = entityManager.createQuery("select message from Message message").getResultList(); | for(Message m: messages){ | entityManager.refresh(m); | /*I'm obliged to do so, cause if 2 Locales are loaded in a short time, and a change was performed in the database, the entityManager seems to use its cache and not the proper data from the db.*/ | for(Expression e: m.getExpressions()){ | //seeking the proper Expression for the current Locale | if(e.getLanguage().getCode().equals(locale.toString())){ | map.put(m.getKeyValue(), e.getText()); | found = true; | } | } | if(!found){ | //If no proper Expression found for the current locale, adding the expression for the default Locale | for(Expression e: m.getExpressions()){ | if(e.getLanguage().isDefaultLanguage()){ | map.put(m.getKeyValue(), e.getText()); | found = true; | } | } | if(!found){ | //else, we put the key as its own translation | map.put(m.getKeyValue(), m.getKeyValue()); | } | } | found = false; | } | return map; | } | } Note: in my code, a 'Message' is an Entity containing the message keys, and an expression is its translation for a given Locale (Expression table has a link to Language table, Language.code being for example 'en'). Note that I also have a 'default' language to fetch an expression if none was found for a given Locale. Now my little class DBControl, just a singleton to handle 'dirty locales':
| /** | * Little singleton class handling dirty Locales | */ | public class DBControl{ | | private static DBControl instance; | private List<String> dirtyLocales; | | private DBControl(){} | | public static DBControl instance(){ | if(instance==null) | instance = new DBControl(); | return instance; | } | | public void setDirtyLocale(String locale){ | if(dirtyLocales==null) | dirtyLocales = new ArrayList<String>(); | if(!dirtyLocales.contains(locale)) | dirtyLocales.add(locale); | } | | public void removeDirtyLocale(String locale){ | if(dirtyLocales!=null){ | for(String s: dirtyLocales){ | if(s.equals(locale)){ | dirtyLocales.remove(s); | break; | } | } | } | } | public boolean isDirtyLocale(String locale){ | if(dirtyLocales!=null){ | for(String s: dirtyLocales){ | if(s.equals(locale)) | return true; | } | return false; | } | else | return false; | } | } Thanks to that class, I can access the 'dirtyLocales' list in both my Beans and my ResourceLoader. Again, don't know if that's really a proper way to do it, waiting for feedback. View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4082856#4082856 Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4082856 _______________________________________________ jboss-user mailing list jboss-user@lists.jboss.org https://lists.jboss.org/mailman/listinfo/jboss-user