[jboss-user] [JBoss Seam] - Re: ResourceBundle in Database
pbrewer_uk
do-not-reply at jboss.com
Sun Jul 8 08:33:37 EDT 2007
You can also retrieve the entity manager by calling:
| EntityManager em = (EntityManager) Component.getInstance("entityManager", true);
|
Sorry that this posting is delayed, it sounds like you're pretty much there. But here is a more expanded version of the steps I outlined earlier. Hopefully it'll help you and others...
1. Create the entity beans/ tables. (see my post earlier for table structure)
2. To understand how the new ResourceBundle works in jdk , have a look at these links (in addition those 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
Step 3. i) Create DBControl.java
| import java.util.ResourceBundle.Control ;
| import java.util.ResourceBundle ;
| ...
|
| public class DBControl extends Control {
|
| public static final String FORMAT_DATABASE = "database" ;
|
| public static final DBControl INSTANCE = new DBControl() ;
|
| @Override
| public List<String> getFormats(String baseName) {
| return Collections.singletonList(FORMAT_DATABASE);
| }
|
| @Override
| public ResourceBundle newBundle(String baseName, Locale locale, String format,
| ClassLoader loader, boolean reload) throws IllegalAccessException,
| InstantiationException, IOException {
|
| if ((baseName == null) || (locale == null) || (format == null) ) {
| throw new NullPointerException("baseName=" + baseName + ", locale=" + locale + " and format=" + format + " cannot be null.");
| }
|
| ResourceBundle bundle = null;
| if (format.equals(FORMAT_DATABASE)) {
| try {
| bundle = new DBResourceBundle(baseName, locale) ;
| } catch (MissingBundleException ex) {
| // bundle must return null
| }
| }
| return bundle;
| }
|
| @Override
| public boolean needsReload(String baseName,
| Locale locale,
| String format,
| ClassLoader loader,
| ResourceBundle bundle,
| long loadTime) {
| if (bundle == null) {
| return true ;
| } else if (format.equals(FORMAT_DATABASE) && bundle instanceof DBResourceBundle) {
| try {
| EntityManager em = (EntityManager) Component.getInstance("myEntityManager") ;
| Long bundleId = ( (DBResourceBundle) bundle).getResourceBundleId() ;
| uk.co.iblocks.iflow.data.ResourceBundle rb = em.find(uk.co.iblocks.iflow.data.ResourceBundle.class, bundleId) ;
|
| return rb.isDirty(new Date(loadTime)) ;
|
| } catch (Exception ex) {
| LOG.warn("Error checking dirty state of resource bundle, requesting reload anyway.", ex) ;
| return true ;
| }
| } else {
| return false ;
| }
| }
|
|
| }
|
Step 3. ii) Create DBResourceBundle.java
| public class DBResourceBundle extends java.util.ResourceBundle {
|
| private Map<String, String> messages = new HashMap<String, String>();
|
| private Long resourceBundleId = -1L;
|
| public DBResourceBundle (String baseName, Locale locale) throws MissingBundleException, BundleLoadException {
| try {
| loadBundle(baseName, locale) ;
| } catch (RuntimeException ex) {
| LOG.error("An error occurred loading the resource bundle, baseName=" + baseName + ", locale=" + locale, ex) ;
| BundleLoadException mbe = new BundleLoadException(baseName, locale) ;
| mbe.initCause(ex) ;
| throw mbe ;
| }
| }
|
|
| private void loadBundle(String baseName, Locale locale) throws MissingBundleException {
| // load from db...
| EntityManager em = (EntityManager) Component.getInstance("entityManager") ;
|
| // query the db and load your messages here - you'll need to handle when variant, country and language aren't defined,
| // but a simple example is:
| Query bundleQuery = em.createNamedQuery("loadBundleMessages") ;
| bundleQuery.setParameter("language", locale.getLanguage());
| bundleQuery.setParameter("country", locale.getLanguage());
| bundleQuery.setParameter("variant", locale.getLanguage());
| bundleQuery.setParameter("baseName", baseName) ;
|
| List<ResourceBundle> bundles = bundleQuery.getResultList() ;
| if (!bundles.isEmpty()) {
| // use the most specific bundle
| ResourceBundle resourceBundle = bundles.get(bundles.size()-1) ;
| this.resourceBundleId = resourceBundle.getBundleId() ;
| for (ResourceMessage msg : resourceBundle.getResourceMessages()) {
| messages.put(msg.getKey(), msg.getValue()) ;
| }
| } else {
| throw new MissingBundleException(baseName, locale) ;
| }
|
| em.clear() ;
|
| }
|
| @Override
| public Enumeration<String> getKeys() {
|
| Enumeration<String> keys = new Enumeration<String>() {
|
| private Iterator<String> keyIterator = messages.keySet().iterator() ;
|
| public boolean hasMoreElements() {
| return keyIterator.hasNext() ;
| }
|
| public String nextElement() {
| return keyIterator.next() ;
| }
|
| } ;
| return keys ;
| }
|
| @Override
| protected Object handleGetObject(String key) {
| return messages.get(key) ;
| }
|
|
| // returns id of the resource bundle stored in the database
| public Long getResourceBundleId() {
| return this.resourceBundleId;
| }
|
| public void setResourceBundleId(Long resourceBundleId) {
| this.resourceBundleId = resourceBundleId;
| }
|
| }
|
Step 4. Extend the standard seam resource bundle, SeamResourceBundle.java:
| @Name("org.jboss.seam.core.resourceBundle")
| public class SeamResourceBundle extends org.jboss.seam.core.ResourceBundle implements Serializable {
|
| @Logger
| private Log LOG ;
|
| private transient ResourceBundle bundle ;
|
| @Override
| protected ResourceBundle loadBundle(String bundleName) {
| try {
| ResourceBundle bundle = ResourceBundle.getBundle(bundleName, Locale.instance(), Thread.currentThread().getContextClassLoader(), DBControl.INSTANCE);
| return bundle;
| } catch (MissingResourceException mre) {
| LOG.debug("resource bundle is missing: #0", bundleName);
| return null;
| }
| }
|
| private void createUberBundle() {
| bundle = new java.util.ResourceBundle() {
|
| @Override
| public java.util.Locale getLocale() {
| return Locale.instance();
| }
|
| public List<ResourceBundle> getLittleBundles() {
| List<java.util.ResourceBundle> littleBundles = new ArrayList<ResourceBundle>();
| if (getBundleNames() != null) {
| for (String bundleName : getBundleNames()) {
| java.util.ResourceBundle littleBundle = SeamResourceBundle.this.loadBundle(bundleName);
| if (littleBundle != null)
| littleBundles.add(littleBundle);
| }
| }
|
| java.util.ResourceBundle validatorBundle = SeamResourceBundle.this.loadBundle("ValidatorMessages");
| if (validatorBundle != null) {
| littleBundles.add(validatorBundle);
| }
| java.util.ResourceBundle validatorDefaultBundle = SeamResourceBundle.this.loadBundle("org/hibernate/validator/resources/DefaultValidatorMessages");
| if (validatorDefaultBundle != null) {
| littleBundles.add(validatorDefaultBundle);
| }
| return littleBundles ;
| }
|
|
| @Override
| public Enumeration<String> getKeys() {
| List<ResourceBundle> pageBundles = getPageResourceBundles();
| Enumeration<String>[] enumerations = new Enumeration[getLittleBundles().size() + pageBundles.size()];
| int i = 0;
| for (; i < pageBundles.size(); i++) {
| enumerations[i++] = pageBundles.get(i).getKeys();
| }
| for (; i < getLittleBundles().size(); i++) {
| enumerations = getLittleBundles().get(i).getKeys();
| }
| return new EnumerationEnumeration<String>(enumerations);
| }
|
| @Override
| protected Object handleGetObject(String key) {
| List<ResourceBundle> pageBundles = getPageResourceBundles();
| for (ResourceBundle pageBundle : pageBundles) {
| try {
| return pageBundle.getObject(key);
| } catch (MissingResourceException mre) {
| }
| }
|
| for (ResourceBundle littleBundle : getLittleBundles()) {
| if (littleBundle != null) {
| try {
| return littleBundle.getObject(key);
| } catch (MissingResourceException mre) {
| }
| }
| }
|
| throw new MissingResourceException("Can't find resource in bundles: " + key, getClass().getName(), key);
| }
|
| private List<java.util.ResourceBundle> getPageResourceBundles() {
| FacesContext facesContext = FacesContext.getCurrentInstance();
| if (facesContext != null) {
| UIViewRoot viewRoot = facesContext.getViewRoot();
| if (viewRoot != null) {
| return Pages.instance().getResourceBundles(viewRoot.getViewId());
| }
| }
| return Collections.emptyList();
| }
|
| };
|
| }
|
| @Override
| public java.util.ResourceBundle getBundle() {
| if (bundle == null)
| createUberBundle();
| return bundle;
| }
|
|
|
| }
|
Step 5. Override seam messages to avoid caching. SeamMessages.java:
| @Name("org.jboss.seam.core.messages")
| public class SeamMessages extends Messages {
|
| private transient BundleMap resourceBundleMap = null ;
|
| @Override
| public Map getMessages() {
| java.util.ResourceBundle resourceBundle = ResourceBundle.instance() ;
|
| if ( getResourceBundleMap() == null || !getResourceBundleMap().getBundle().equals(resourceBundle) ) {
| setResourceBundleMap( new BundleMap(resourceBundle) );
| }
| return getResourceBundleMap() ;
| }
|
| protected BundleMap getResourceBundleMap() {
| return this.resourceBundleMap;
| }
|
| protected void setResourceBundleMap(BundleMap resourceBundleMap) {
| this.resourceBundleMap = resourceBundleMap;
| }
|
| }
|
Step 6. optional - use the code in step 5 as a template for extending the ThemeSelector
Step 7. Component.xml extract:
| <component name="org.jboss.seam.core.resourceBundle">
| <property name="bundleNames">
| <value>messages</value>
| </property>
| </component>
|
View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4061696#4061696
Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4061696
More information about the jboss-user
mailing list