1 2 3 4 Previous Next 52 Replies Latest reply on Nov 17, 2007 3:10 PM by pmuir

    ResourceBundle in Database

    udo.krass

      Hi,

      in JDK 6 it is possible to store the ResourceBundle in a database.
      http://forum.java.sun.com/thread.jspa?threadID=360447&tstart=0,
      http://blogs.sun.com/norbert/entry/more_control_over_resourcebundle.

      I want to do that with Seam also. In Spring it is just implemented.
      What can be the right way to integrate a Database-ResourceBundle in Seam.

      Thanx in Advance,

      Udo.

        • 1. Re: ResourceBundle in Database
          gavin.king

          Easy. Extend the built-in ResourceBundle component, and override some methods. We are targetting JDK5, not JDK6.

          • 2. Re: ResourceBundle in Database
            pbrewer_uk

            How would a subclass of org.jboss.seam.core.ResourceBundle be annotated in this case - are the annotations below correct?

            Also, would some extra configuration in components.xml be required too?

            ExtendedResourceBundle.java

            ...
            @Scope(ScopeType.SESSION)
            @Intercept(NEVER)
            @Name("org.jboss.seam.core.resourceBundle")
            @Install(precedence=BUILT_IN)
            public class ExtendedResourceBundle extends org.jboss.seam.core.ResourceBundle
            ...
             @Override
             protected ResourceBundle loadBundle(String bundleName) {
             try {
             ResourceBundle bundle =
             ResourceBundle.getBundle(bundleName,
             Locale.instance(),
             Thread.currentThread().getContextClassLoader(),
             DBControl.INSTANCE);
             LOG.debug("loaded resource bundle: " + bundleName);
             return bundle;
             } catch (MissingResourceException mre) {
             LOG.debug("db resource bundle missing: " + bundleName);
             return super.loadBundle(bundleName);
             }
             }
            ...
            }
            


            • 3. Re: ResourceBundle in Database
              pmuir

              Not quite

              ExtendedResourceBundle.java

              ...
              @Name("org.jboss.seam.core.resourceBundle")
              public class ExtendedResourceBundle extends org.jboss.seam.core.ResourceBundle
              ...
               @Override
               protected ResourceBundle loadBundle(String bundleName) {
               try {
               ResourceBundle bundle =
               ResourceBundle.getBundle(bundleName,
               Locale.instance(),
               Thread.currentThread().getContextClassLoader(),
               DBControl.INSTANCE);
               LOG.debug("loaded resource bundle: " + bundleName);
               return bundle;
               } catch (MissingResourceException mre) {
               LOG.debug("db resource bundle missing: " + bundleName);
               return super.loadBundle(bundleName);
               }
               }
              ...
              }
              


              and no config in components.xml

              • 4. Re: ResourceBundle in Database
                pmuir

                But beware, if you are using core:resourceBundle in components.xml, you'll need to change it to point at your overridden resource bundle

                • 5. Re: ResourceBundle in Database

                  I find that my users want to frequently change messages and text throughout my applications.

                  I would prefer to use an entity to store and update messages and text.

                  I believe that I would only need 3 fields: key, text, locale

                  or possibly key, text, en, fr (an extra column of each locale)

                  My application is only in English so I am not that concerned about locale.

                  Instead of getting the text or message from a file in the application I would like them to be loaded from this table on startup.

                  If I get this working will I be able to reload this in a running seam application of one of the properties is modified?

                  Does someone else already have a example of this type of thing?

                  • 6. Re: ResourceBundle in Database
                    pbrewer_uk

                    I have implemented a database resource bundle using entities in Seam - its too verbose to post, but here are the steps to implement it:

                    1. Create the entity beans/ tables. To accurately match the ResourceBundle concept, I created a Resource Bundle table and a child Resource Message table (see below)

                    2. Have a look at (in addition to the links provided by Udo):
                    http://java.sun.com/developer/JDCTechTips/2005/tt1018.html#2
                    http://java.sun.com/javase/6/docs/api/java/util/ResourceBundle.html

                    3. Implement a DBContol (to control caching of the resource bundle) and create a DBResourceBundle that is a subclass of java.util.ResourceBundle to load the data from your entities.

                    4. Override the "org.jboss.seam.core.resourceBundle" component to use the DBControl and DBResourceBundle.

                    5. Override the "org.jboss.seam.core.messages" component to avoid indefinite caching of the resource bundle - caching will now be done by your DBControl created in step 3.

                    6. You may also need to override the "org.jboss.seam.theme.themeSelector" component to look at your DBControl / DBResourceBundle.

                    7. Update your components.xml to use the "component" tag instead of "core:XXX" tags for the overridden seam components.

                    Table layout:

                    create table RESOURCE_BUNDLE
                    (
                     BUNDLE_ID NUMBER(19) not null,
                     LANGUAGE VARCHAR(2),
                     COUNTRY VARCHAR(2),
                     VARIANT VARCHAR(50),
                     BASE_NAME VARCHAR(500) not null,
                     LAST_MODIFIED DATE, -- can use this on the DBControl to clear cache
                     IB_DESCRIPTION VARCHAR(50)
                    )
                    
                    create table RESOURCE_MESSAGE
                    (
                     MESSAGE_ID VARCHAR(10) not null, -- PK
                     BUNDLE_ID VARCHAR(10) not null, -- FK to RESOURCE_BUNDLE
                     KEY VARCHAR(500) not null,
                     VALUE VARCHAR(4000) not null
                    )
                    


                    Hope that helps a little, Pete.


                    • 7. Re: ResourceBundle in Database
                      matt.drees

                      Nifty. I might end up using something like that. Thanks.

                      • 8. Re: ResourceBundle in Database
                        zerg-spirit

                        Hi,

                        I'm trying to have my resource bundles stored in a database aswell, and wanted to follow pete's post, but I don't really understand some part of it.

                        What do you mean by:

                        3. Implement a DBContol (to control caching of the resource bundle)

                        What's that? Is it supposed to be a class? What class is it supposed to extends from (or to implements)? What is it supposed to do exactly?

                        What about those overrides also. How am I supposed to override those component?


                        • 9. Re: ResourceBundle in Database
                          zerg-spirit

                          I up the topic cause I still couldn't implements that DataBase Resource Bundle.

                          I now have all the needed classes, following the steps described by pbrewer_uk, but I'm having trouble knowing what code to implements in what class. For example, I don't know what DBControl class is exactly supposed to do and when, and I don't know where to put the code to retrieve the messages from the DB neither (probably in the getKeys method of the ResourceBundle extended class?).

                          Moreover, I don't know how to set up my Resource Bundle to be used instead of the default one (using Seam 2.0).

                          Thanks for your help.

                          • 10. Re: ResourceBundle in Database
                            pmuir

                             

                            "Zerg-Spirit" wrote:
                            Moreover, I don't know how to set up my Resource Bundle to be used instead of the default one (using Seam 2.0).


                            Give it these annotations:

                            @Scope(ScopeType.SESSION)
                            @BypassInterceptors
                            @Name("org.jboss.seam.core.resourceBundle")
                            public class MyResourceBundle extends org.jboss.seam.international.ResourceBundle


                            • 11. Re: ResourceBundle in Database
                              zerg-spirit

                              Thanks, it helped me a lot!
                              Now, I kinda understood how it's working, but my very last problem is pretty tough: I can't retrieve the EntityManager in my Session Bean extending ResourceBundle.

                              @Stateless
                              @Scope(SESSION)
                              @Name("dbResourceBundle")
                              public class DBResourceBundle extends ResourceBundle implements iDBResourceBundle{
                              
                               @PersistenceContext
                               private EntityManager em;
                              
                               private List<CustomResourceBundle> availableResourceBundles;
                              
                               public DBResourceBundle(){
                               System.out.println("EntityManager: "+em); //em is null :/
                               try{
                               availableResourceBundles = em.createQuery("select rb from CustomResourceBundle rb").getResultList();
                               }
                               catch(Exception e){
                               //null pointer exception cause em is null.
                               e.printStackTrace();
                              
                               }
                               }
                              ...
                              


                              CustomResourceBundle being an entity bean representing a 'bundle' for the given language.
                              How to retrieve a workable EntityManager?
                              My guess is that when this Session Bean is instanciated, the PersistenceContext isn't created yet.

                              • 12. Re: ResourceBundle in Database
                                pmuir

                                1) You will need to use *exactly* the @Name annotation I gave you, otherwise it won't replace Seam's resource bundle.

                                2) Use an @PostConstruct/@Create method rather than doing it in the constructor - injected resources are never available in the constructor.

                                • 13. Re: ResourceBundle in Database
                                  zerg-spirit

                                  The class I pasted isn't the one extending Seam ResourceBundle, but java.util.ResourceBundle.

                                  I'll try with a @Create annotation then!
                                  Thanks.

                                  • 14. Re: ResourceBundle in Database
                                    zerg-spirit

                                    Still can't make it work.
                                    I changed my bean so that it's now a SFSB (in order to use @Create):

                                    @Stateful
                                    @Name("dbResourceBundle")
                                    @Scope(SESSION)
                                    public class DBResourceBundle extends ResourceBundle implements iDBResourceBundle{
                                    ...

                                    Here's the @Create method:
                                    @Create
                                     public void fillAvailableResourceBundle(){
                                     try{
                                     availableResourceBundles = em.createQuery("select rb from CustomResourceBundle rb").getResultList();
                                     }
                                     catch(Exception e){
                                    
                                     e.printStackTrace();
                                    
                                     }
                                    
                                    
                                     }


                                    According to my tests, this method is never called.
                                    I think my implementation of the ResourceBundle is correct though, since it calls the handleGetObject method in my DBResourceBundle class when I refer to "messages['something'] in my jsf pages.

                                    So I just have to fix that EntiyManager issue.

                                    1 2 3 4 Previous Next