Saturday Apr 19, 2008

VW user tip1: A workaround for validation messages translation issues

This useful tip was sent to me by Jorge Campins. In this tip Jorge gives a solution to fix the problem related to intermixing of translated messages (Spanish, applies to other languages also) and English, which he jokingly calls as "Spanglish". Especially, this is a case with standard components and its Converters and Validators.

For other user tips, visit  Netbeans Visualweb user tips and code snippets


We wouldn’t know about other languages, but if you are developing with NetBeans 6 there are some translation issues you should solve before releasing your applications to Spanish speaking end-users. Here we specifically address those issues at JSF core components such as Converters and Validators. These issues include not translated, partially translated and wrongfully translated messages; also visual component ids appearing as part of the message, which is very helpful for the programmer but very confusing for the end-user. Fortunately, we were able to deal with all these in an easy way, based on the approach suggested by Dr. Winston Prakash. All we had to do was to build a translation routine and execute it at the prerender event. It was particularly easy for us because we already had all our pages calling some helper methods at prerender, so we didn’t had to modify every page to call the new translator routine. The following is an example of a translation routine based on the one we built:

public static void fixFacesMessages() {
FacesContext facesContext = FacesContext.getCurrentInstance();
UIViewRoot uivr = facesContext.getViewRoot();
Iterator messageClientIds = facesContext.getClientIdsWithMessages();
while (messageClientIds.hasNext()) {
String clientId = messageClientIds.next();
if (clientId != null) {
UIComponent uic = uivr == null ? null : uivr.findComponent(clientId);
Iterator messages = facesContext.getMessages(clientId);
while (messages.hasNext()) {
FacesMessage facesMessage = messages.next();
// Get the messages
String detail = facesMessage.getDetail();
String summary = facesMessage.getSummary();
// translate
String detalle = getMensaje(uic, detail);
String resumen = getMensaje(uic, summary);
// Set your own message
facesMessage.setDetail(detalle);
facesMessage.setSummary(resumen);
}
}
}
}

private static String getMensaje(UIComponent uic, String message) {
FacesContext facesContext = FacesContext.getCurrentInstance();
String mensaje = StringUtils.trimToEmpty(message);
/\*\*/
if (uic != null) {
mensaje = trimPrefix(mensaje, uic.getClientId(facesContext));
mensaje = trimPrefix(mensaje, uic.getId());
}
mensaje = trimPrefix(mensaje, ": ");
mensaje = trimPrefix(mensaje, "Validation Error: ");
mensaje = trimPrefix(mensaje, "Error de Validación: ");
/\*\*/
mensaje = trimSuffix(mensaje, "Example:");
mensaje = trimSuffix(mensaje, "Ejemplo:");
/\*\*/
mensaje = mensaje.replace(
"is not a number",
"debe ser un número");
mensaje = mensaje.replace(
"must be a number consisting of one or more digits",
"debe ser un número");
mensaje = mensaje.replace(
"must be a number between",
"debe ser un número entre");
mensaje = mensaje.replace(
"Specified attribute is not between the expected values of",
"El valor debe estar comprendido entre");
mensaje = mensaje.replace(
" and ",
" y ");
/\*
\* We always use the maxLength property of the TextField component to avoid
\* length errors on string fields, so only TextArea components need a Length
\* validator. Therefore, only if the component is a TextArea we need to
\* change the subject of the sentence.
\*/
String sujeto = uic instanceof TextArea
? "La longitud del valor"
: "El valor";
mensaje = mensaje.replace(
"Valor es más grande de valor de máximo permitido:",
sujeto + " debe ser menor o igual que");
mensaje = mensaje.replace(
"Valor is menos de valor de mínimo permitido:",
sujeto + " debe ser mayor o igual que");
/\*\*/
return mensaje;
}

public static String trimPrefix(String message, String prefix) {
String mensaje = StringUtils.trimToEmpty(message);
int i = mensaje.indexOf(prefix);
if (i >= 0) {
mensaje = mensaje.substring(i + prefix.length());
}
return mensaje;
}

public static String trimSuffix(String message, String suffix) {
String mensaje = StringUtils.trimToEmpty(message);
int i = mensaje.indexOf(suffix);
if (i > 0) {
mensaje = mensaje.substring(0, i);
}
return mensaje;
}

Search

Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today