@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

Reply via email to