package org.ovirt.engine.ui.frontend;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.MissingResourceException;
import com.google.gwt.core.client.GWT;
import com.google.gwt.i18n.client.ConstantsWithLookup;
import com.google.gwt.regexp.shared.MatchResult;
import com.google.gwt.regexp.shared.RegExp;
import org.ovirt.engine.core.compat.StringHelper;
public class ErrorTranslator {
private ConstantsWithLookup errors;
public ErrorTranslator() {
}
public ErrorTranslator(ConstantsWithLookup errors) {
this.errors = errors;
}
/**
* Translate errors from error types, error messages contains errors and variables. Variable used in messages,
* Variable definition must be in format: $variableName variableValue. Variable usage must be in format
* #variableName
*
* @param errorMsg
* messages to be translated
* @param changeIfNotFound
* If true: if message key is not found in the resource, return a beautified key. If false, returned
* unfound key as is.
* @return
*/
public ArrayList<String> translateErrorText(ArrayList<String> errorMsg,
Boolean changeIfNotFound) {
ArrayList<String> translatedMessages = translateMessages(errorMsg,
changeIfNotFound);
return resolveMessages(translatedMessages);
}
/**
* Translates and resolves errors from error types. error messages contains errors and variables. Variable used in
* messages. Variable definition must be in format: $variableName variableValue. Variable usage must be in format
* #variableName Note: Unfound message keys will be beautified!
*
* @param errorMsg
* messages to be translated
* @return
*/
public ArrayList<String> translateErrorText(ArrayList<String> errorMsg) {
return translateErrorText(errorMsg, true);
}
public ArrayList<String> translateMessages(ArrayList<String> errorMsg,
Boolean changeIfNotFound) {
ArrayList<String> translatedMessages = new ArrayList<String>();
if (errorMsg != null && errorMsg.size() > 0) {
for (String curError : errorMsg) {
translatedMessages.add(translateErrorTextSingle(curError,
changeIfNotFound));
}
}
return translatedMessages;
}
/**
* Translates a single error message.
*
* @param errorMsg
* The message to be translated
* @param changeIfNotFound
* If true: if message key is not found in the resource, return a beautified key. If false, returned
* unfound key as is.
* @return
*/
public String translateErrorTextSingle(String errorMsg,
Boolean changeIfNotFound) {
String ret = "";
try {
if ((errorMsg != null) && (errorMsg.length() > 0)) {
errorMsg = errorMsg.replace('.', '_');
if (errors.getString(errorMsg) != null) {
// if (mMessages.containsKey(errorMsg)) {
ret = errors.getString(errorMsg).replace("\n", "<br/>");
} else {
if ((isDynamicVariable(errorMsg)) || (!changeIfNotFound)) {
ret = errorMsg;
} else {
// just a message that doesn't have a value in the resource:
String[] splitted = errorMsg.toLowerCase().split("_");
ret = StringHelper.join(" ", splitted);
}
}
}
}
catch(MissingResourceException e) {
ret = errorMsg;
}
return ret;
}
/**
* Translates a single error message. Note: if message key not found, a beautified message will return!
*
* @param errorMsg
* the message to translate
* @return the translated message or a beautifed message key
*/
public String TranslateErrorTextSingle(String errorMsg) {
return translateErrorTextSingle(errorMsg, true);
}
/**
* Replacing variables ('#...') within translatedMessages with their values ('$...') that are also within
* translatedMessages.
*
* @param translatedMessages
* @return
*/
public ArrayList<String> resolveMessages(ArrayList<String> translatedMessages) {
ArrayList<String> translatedErrors = new ArrayList<String>();
Map<String, String> variables = new HashMap<String, String>();
for (String currentMessage : translatedMessages) {
if (currentMessage.startsWith("$")) {
addVariable(currentMessage, variables);
} else {
translatedErrors.add(currentMessage);
}
}
// /Place to global variable adding
ArrayList<String> returnValue = new ArrayList<String>();
for (String error : translatedErrors) {
returnValue.add(resolveMessage(error, variables));
}
return returnValue;
}
private void addVariable(String variable, Map<String, String> variables) {
int firstSpace = variable.indexOf(' ');
if (firstSpace != -1 && firstSpace < variable.length()) {
String key = variable.substring(1, firstSpace);
String value = variable.substring(firstSpace + 1);
if (!variables.containsKey(key)) {
variables.put(key, value);
}
}
}
private String resolveMessage(String message, Map<String, String> variables) {
String returnValue = message;
RegExp regex = RegExp.compile("\\$\\{\\w*\\}*", "gi");
int fromIndex = 0;
int length = message.length();
MatchResult result;
while (fromIndex < length) {
result = regex.exec(message);
if (result == null) {
// No more matches
break;
}
int index = result.getIndex();
String match = result.getGroup(0);
String value = match.substring(2, match.length() - 1);
if (variables.containsKey(value)) {
returnValue = returnValue.replace(match, variables.get(value));
}
}
return returnValue;
}
/**
* Returns true if the specified strMessage is in the format: "$variable-name variable-value", false otherwise.
*
* @param strMessage
* the string that may be a dynamic variable
* @return true if input is dynamic variable, false otherwise.
*/
private final boolean isDynamicVariable(String strMessage) {
return strMessage.startsWith("$");
}
}