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<String> getKeys()
{
return properties != null ? ((Enumeration<String>) 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<String> 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;
}
};
}
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…