[jboss-user] [JBoss Seam] - Re: ResourceBundle in Database
Zerg-Spirit
do-not-reply at jboss.com
Tue Sep 11 03:15:34 EDT 2007
@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
More information about the jboss-user
mailing list