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

    ResourceBundle in Database

    Udo Krass Newbie

      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 Master

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

          • 2. Re: ResourceBundle in Database
            Peter Brewer Novice

            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
              Pete Muir Master

              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
                Pete Muir Master

                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
                  Jason Long Master

                  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
                    Peter Brewer Novice

                    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 Master

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

                      • 8. Re: ResourceBundle in Database
                        Orsier Adrien Newbie

                        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
                          Orsier Adrien Newbie

                          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
                            Pete Muir Master

                             

                            "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
                              Orsier Adrien Newbie

                              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
                                Pete Muir Master

                                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
                                  Orsier Adrien Newbie

                                  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
                                    Orsier Adrien Newbie

                                    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