jsf - otro - managed bean concepto
Leer las propiedades del paquete de recursos en un bean administrado (3)
Aquí hay una solución que estoy usando, no es tan simple, pero al menos funciona:
Primera clase :
package com.spectotechnologies.website.util;
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.hibernate.validator.messageinterpolation.ResourceBundleMessageInterpolator;
/**
*
* @author Alexandre Lavoie
*/
public class MessageInterpolator extends ResourceBundleMessageInterpolator
{
public static final String LANGUAGE_TAG_PATTERN = "//{[^}]*//}";
@Override
public String interpolate(String p_sMessage, Context p_oContext)
{
return super.interpolate(replaceMessages(p_sMessage),p_oContext);
}
@Override
public String interpolate(String p_sMessage, Context p_oContext, Locale p_oLocale)
{
StringManager.setLocale(p_oLocale);
return super.interpolate(replaceMessages(p_sMessage),p_oContext,p_oLocale);
}
private String replaceMessages(String p_sMessage)
{
Matcher oMatcher;
String sKey;
String sReplacement;
StringBuffer sbTemp = new StringBuffer();
oMatcher = Pattern.compile(LANGUAGE_TAG_PATTERN).matcher(p_sMessage);
while(oMatcher.find())
{
sKey = oMatcher.group().substring(1,oMatcher.group().length() - 1);
sReplacement = StringManager.getString(sKey);
if(!sReplacement.startsWith("???"))
{
oMatcher.appendReplacement(sbTemp,sReplacement);
}
}
oMatcher.appendTail(sbTemp);
return sbTemp.toString();
}
}
Segunda clase :
package com.spectotechnologies.website.util;
import com.spectotechnologies.util.BundleManager;
import com.spectotechnologies.util.FacesSessionManager;
import java.util.Locale;
/**
* set-up and interface a BundleManager
* save the bundleManager into the session
* @author Charles Montigny
*/
public final class StringManager
{
/** the session name of this class bundle manager */
public static final String BUNDLE_MANAGER_SESSION_NAME = "StringManager_BundleManager";
/** List of ResourceBundle names to load.
* Will be load in order.
* The last ones values may overrite the first ones values. */
private final static String[] BUNDLE_LIST = {
"com.spectotechnologies.hibernate.validation.resources.ValidationMessages",
"com.spectotechnologies.website.general.resources.ValidationMessages",
"com.spectotechnologies.website.general.resources.General"};
/** bundle manager */
private static BundleManager m_oBundleManager = null;
private static BundleManager getBundleManager()
{
if(m_oBundleManager == null)
{
// get the bundle into the session
m_oBundleManager = (BundleManager)FacesSessionManager.getObject(BUNDLE_MANAGER_SESSION_NAME);
if(m_oBundleManager == null)
{
// session was empty, load a new one
m_oBundleManager = new BundleManager();
for(int iIndex = 0; iIndex < BUNDLE_LIST.length; iIndex++)
{
m_oBundleManager.addBundle(BUNDLE_LIST[iIndex]);
}
// add the bundle to the session
FacesSessionManager.setObject(BUNDLE_MANAGER_SESSION_NAME, m_oBundleManager);
}
}
return m_oBundleManager;
}
/**
* get a string value in the bundle manager by a string key
* @param p_sKey the string key
* @return the value of the string key
*/
public static String getString(String p_sKey)
{
return getBundleManager().getStringValue(p_sKey);
}
/**
* set the locale
* @param p_oLocale the locale to set
*/
public static void setLocale(Locale p_oLocale)
{
getBundleManager().setLocale(p_oLocale);
// update the session
FacesSessionManager.setObject(BUNDLE_MANAGER_SESSION_NAME,
getBundleManager());
}
}
Después de que necesite anular BUNDLE_LIST con sus archivos de propiedades. Una vez hecho esto, úsalo así:
sMessage = StringManager.getString("website.validation.modifySystem.modified");
Si tienes preguntas, ¡no lo dudes!
EDITAR:
También necesita declarar el MessageInterpolator
META-INF / validation.xml
<validation-config
xmlns="http://jboss.org/xml/ns/javax/validation/configuration"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://jboss.org/xml/ns/javax/validation/configuration">
<message-interpolator>com.spectotechnologies.website.util.MessageInterpolator</message-interpolator>
</validation-config>
Usando archivos <resource-bundle>
puedo tener texto i18n en mis páginas JSF.
Pero, ¿es posible acceder a estas mismas propiedades en mi bean administrado para poder configurar mensajes de rostros con valores de i18n?
Otra posibilidad:
faces-config.xml
<?xml version=''1.0'' encoding=''UTF-8''?>
<faces-config ...>
<application>
<locale-config>
<default-locale>de</default-locale>
</locale-config>
<resource-bundle>
<base-name>de.fhb.resources.text.backend</base-name>
<var>backendText</var>
</resource-bundle>
</application>
</faces-config>
YourBean.java
FacesContext context = FacesContext.getCurrentInstance();
Application app = context.getApplication();
ResourceBundle backendText = app.getResourceBundle(context, "backendText");
backendText.getString("your.property.key");
Suponiendo que lo haya configurado de la siguiente manera:
<resource-bundle>
<base-name>com.example.i18n.text</base-name>
<var>text</var>
</resource-bundle>
Si su bean tiene un alcance de solicitud, puede simplemente inyectar <resource-bundle>
como @ManagedProperty
mediante su <var>
:
@ManagedProperty("#{text}")
private ResourceBundle text;
public void someAction() {
String someKey = text.getString("some.key");
// ...
}
O si solo necesitas una clave específica:
@ManagedProperty("#{text[''some.key'']}")
private String someKey;
public void someAction() {
// ...
}
Sin embargo, si su bean tiene un alcance más amplio, evalúe #{text}
programáticamente en el alcance local del método:
public void someAction() {
FacesContext context = FacesContext.getCurrentInstance();
ResourceBundle text = context.getApplication().evaluateExpressionGet(context, "#{text}", ResourceBundle.class);
String someKey = text.getString("some.key");
// ...
}
O si solo necesitas una clave específica:
public void someAction() {
FacesContext context = FacesContext.getCurrentInstance();
String someKey = context.getApplication().evaluateExpressionGet(context, "#{text[''some.key'']}", String.class);
// ...
}
Incluso puede obtenerlo mediante la API estándar ResourceBundle
la misma forma que JSF ya lo está haciendo bajo las cubiertas, solo tendría que repetir el nombre base en el código:
public void someAction() {
FacesContext context = FacesContext.getCurrentInstance();
ResourceBundle text = ResourceBundle.getBundle("com.example.i18n.text", context.getViewRoot().getLocale());
String someKey = text.getString("some.key");
// ...
}
O si está administrando beans por CDI en lugar de JSF, puede crear un @Producer
para eso:
public class BundleProducer {
@Produces
public PropertyResourceBundle getBundle() {
FacesContext context = FacesContext.getCurrentInstance();
return context.getApplication().evaluateExpressionGet(context, "#{text}", PropertyResourceBundle.class);
}
}
E inyectarlo de la siguiente manera:
@Inject
private PropertyResourceBundle text;
Alternativamente, si está utilizando la clase Messages
de la biblioteca de utilidades JSF OmniFaces , puede simplemente configurar su resolver una vez para permitir que todos los métodos de Message
utilicen el paquete.
Messages.setResolver(new Messages.Resolver() {
public String getMessage(String message, Object... params) {
ResourceBundle bundle = ResourceBundle.getBundle("com.example.i18n.text", Faces.getLocale());
if (bundle.containsKey(message)) {
message = bundle.getString(message);
}
return MessageFormat.format(message, params);
}
});
Vea también el ejemplo en el javadoc y la página del escaparate .