Database backed i18n for java web-app

后端 未结 4 1515
夕颜
夕颜 2020-12-03 09:05

I\'d like to use a database to store i18n key/value pairs so we can modify / reload the i18n data at runtime. Has anyone done this? Or does anyone have an idea of how to imp

4条回答
  •  难免孤独
    2020-12-03 09:41

    I finally got this working with danb's help above.

    This is my resource bundle class and resource bundle control class.

    I used this code from @[danb]'s.

    ResourceBundle bundle = ResourceBundle.getBundle("AwesomeBundle", locale, DbResourceBundle.getMyControl());
    javax.servlet.jsp.jstl.core.Config.set(actionBeanContext.getRequest(), Config.FMT_LOCALIZATION_CONTEXT, new LocalizationContext(bundle, locale));
    

    and wrote this class.

    public class DbResourceBundle extends ResourceBundle
    {
        private Properties properties;
    
        public DbResourceBundle(Properties inProperties)
        {
            properties = inProperties;
        }
    
        @Override
        @SuppressWarnings(value = { "unchecked" })
        public Enumeration getKeys()
        {
            return properties != null ? ((Enumeration) properties.propertyNames()) : null;
        }
    
        @Override
        protected Object handleGetObject(String key)
        {
            return properties.getProperty(key);
        }
    
        public static ResourceBundle.Control getMyControl()
        {
            return new ResourceBundle.Control()
            {
    
                @Override
                public List getFormats(String baseName)
                {
                    if (baseName == null)
                    {
                        throw new NullPointerException();
                    }
                    return Arrays.asList("db");
                }
    
                @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) || (loader == null))
                        throw new NullPointerException();
                    ResourceBundle bundle = null;
                    if (format.equals("db"))
                    {
                        Properties p = new Properties();
                        DataSource ds = (DataSource) ContextFactory.getApplicationContext().getBean("clinicalDataSource");
                        Connection con = null;
                        Statement s = null;
                        ResultSet rs = null;
                        try
                        {
                            con = ds.getConnection();
                            StringBuilder query = new StringBuilder();
                            query.append("select label, value from i18n where bundle='" + StringEscapeUtils.escapeSql(baseName) + "' ");
    
                            if (locale != null)
                            {
                                if (StringUtils.isNotBlank(locale.getCountry()))
                                {
                                    query.append("and country='" + escapeSql(locale.getCountry()) + "' ");
    
                                }
                                if (StringUtils.isNotBlank(locale.getLanguage()))
                                {
                                    query.append("and language='" + escapeSql(locale.getLanguage()) + "' ");
    
                                }
                                if (StringUtils.isNotBlank(locale.getVariant()))
                                {
                                    query.append("and variant='" + escapeSql(locale.getVariant()) + "' ");
    
                                }
                            }
                            s = con.createStatement();
                            rs = s.executeQuery(query.toString());
                            while (rs.next())
                            {
                                p.setProperty(rs.getString(1), rs.getString(2));
                            }
                        }
                        catch (Exception e)
                        {
                            e.printStackTrace();
                            throw new RuntimeException("Can not build properties: " + e);
                        }
                        finally
                        {
                            DbUtils.closeQuietly(con, s, rs);
                        }
                        bundle = new DbResourceBundle(p);
                    }
                    return bundle;
                }
    
                @Override
                public long getTimeToLive(String baseName, Locale locale)
                {
                    return 1000 * 60 * 30;
                }
    
                @Override
                public boolean needsReload(String baseName, Locale locale, String format, ClassLoader loader, ResourceBundle bundle, long loadTime)
                {
                    return true;
                }
    
            };
        }
    

提交回复
热议问题