i18n parameterized validation error messages

This commit is contained in:
Andreas Billmann
2015-12-17 22:09:32 +01:00
parent c9d13d4d58
commit 09834ab07f
9 changed files with 61 additions and 30 deletions

View File

@@ -63,7 +63,7 @@ public class ValidationErrorListCell extends ListCell<ValidationError> {
private void addContent(ValidationError validationError) { private void addContent(ValidationError validationError) {
setText(null); setText(null);
Text text = new Text(getI18nValidatioMessage(resourceBundle, validationError.getMessages())); Text text = new Text(getI18nValidatioMessage(resourceBundle, validationError));
text.setWrappingWidth(180); text.setWrappingWidth(180);
setGraphic(text); setGraphic(text);
} }

View File

@@ -77,7 +77,7 @@ public class EditableValidationCell extends TableCell<CSVRow, CSVValue> {
setTooltip(null); setTooltip(null);
} else if (item.getValidationError() != null) { } else if (item.getValidationError() != null) {
setStyle("-fx-background-color: #ff8888"); setStyle("-fx-background-color: #ff8888");
setTooltip(new Tooltip(getI18nValidatioMessage(resourceBundle, item.getValidationError().getMessages()))); setTooltip(new Tooltip(getI18nValidatioMessage(resourceBundle, item.getValidationError())));
} }
if (item == null || empty) { if (item == null || empty) {

View File

@@ -26,23 +26,32 @@
package ninja.javafx.smartcsv.fx.util; package ninja.javafx.smartcsv.fx.util;
import ninja.javafx.smartcsv.validation.ValidationError;
import ninja.javafx.smartcsv.validation.ValidationMessage; import ninja.javafx.smartcsv.validation.ValidationMessage;
import java.io.StringWriter; import java.io.StringWriter;
import java.util.List; import java.util.List;
import java.util.ResourceBundle; import java.util.ResourceBundle;
import static java.text.MessageFormat.format;
/** /**
* This class makes validation messages readable in supported languages * This class makes validation messages readable in supported languages
*/ */
public class I18nValidationUtil { public class I18nValidationUtil {
public static String getI18nValidatioMessage(ResourceBundle resourceBundle, List<ValidationMessage> validationMessages) { public static String getI18nValidatioMessage(ResourceBundle resourceBundle, ValidationError error) {
List<ValidationMessage> validationMessages = error.getMessages();
StringWriter message = new StringWriter(); StringWriter message = new StringWriter();
for (ValidationMessage validationMessage: validationMessages) { for (ValidationMessage validationMessage: validationMessages) {
if (resourceBundle.containsKey(validationMessage.getKey())) { if (resourceBundle.containsKey(validationMessage.getKey())) {
message.append(resourceBundle.getString(validationMessage.getKey())).append("\n"); String resourceText = resourceBundle.getString(validationMessage.getKey());
if (validationMessage.getParameters().length > 0) {
message.append(format(resourceText, validationMessage.getParameters())).append("\n");
} else {
message.append(resourceText).append("\n");
}
} else { } else {
message.append(validationMessage.getKey()).append("\n"); message.append(validationMessage.getKey()).append("\n");
} }

View File

@@ -68,4 +68,12 @@ public class ValidationMessage {
result = 31 * result + Arrays.hashCode(parameters); result = 31 * result + Arrays.hashCode(parameters);
return result; return result;
} }
@Override
public String toString() {
return "ValidationMessage{" +
"key='" + key + '\'' +
", parameters=" + Arrays.toString(parameters) +
'}';
}
} }

View File

@@ -128,11 +128,11 @@ public class Validator {
try { try {
groovyResult = script.run(); groovyResult = script.run();
} catch (CompilationFailedException e) { } catch (CompilationFailedException e) {
error.add("groovy script '"+groovyScript+"' throws exception: "+e.getMessage()); error.add("validation.message.groovy.exception", groovyScript, e.getMessage());
e.printStackTrace(); e.printStackTrace();
} }
if (groovyResult == null) { if (groovyResult == null) {
error.add("groovy script '"+groovyScript+"' returns null"); error.add("validation.message.groovy.return.null", groovyScript);
} }
if (!isScriptResultTrue(groovyResult)) { if (!isScriptResultTrue(groovyResult)) {
@@ -166,7 +166,7 @@ public class Validator {
Integer minLength = getInteger(columnConfig, "minlength"); Integer minLength = getInteger(columnConfig, "minlength");
if (minLength != null) { if (minLength != null) {
if (!minLength(value, minLength)) { if (!minLength(value, minLength)) {
error.add("has not min length of " + minLength); error.add("validation.message.min.length", minLength.toString());
} }
} }
} }
@@ -175,7 +175,7 @@ public class Validator {
Integer maxLength = getInteger(columnConfig, "maxlength"); Integer maxLength = getInteger(columnConfig, "maxlength");
if (maxLength != null) { if (maxLength != null) {
if (!maxLength(value, maxLength)) { if (!maxLength(value, maxLength)) {
error.add("has not max length of " + maxLength); error.add("validation.message.max.length", maxLength.toString());
} }
} }
} }
@@ -184,7 +184,7 @@ public class Validator {
String dateformat = getString(columnConfig, "date"); String dateformat = getString(columnConfig, "date");
if (dateformat != null && !dateformat.trim().isEmpty()) { if (dateformat != null && !dateformat.trim().isEmpty()) {
if (!isDate(value, dateformat, true)) { if (!isDate(value, dateformat, true)) {
error.add("is not a date of format " + dateformat); error.add("validation.message.date.format", dateformat);
} }
} }
} }
@@ -201,7 +201,7 @@ public class Validator {
String regexp = getString(columnConfig, "regexp"); String regexp = getString(columnConfig, "regexp");
if (regexp != null && !regexp.trim().isEmpty()) { if (regexp != null && !regexp.trim().isEmpty()) {
if (!matchRegexp(value, regexp)) { if (!matchRegexp(value, regexp)) {
error.add("does not match " + regexp); error.add("validation.message.regexp", regexp);
} }
} }
} }
@@ -237,10 +237,9 @@ public class Validator {
List<String> headerConfig = headerSectionConfig.getStringList("list"); List<String> headerConfig = headerSectionConfig.getStringList("list");
if (headerConfig != null) { if (headerConfig != null) {
if (headerNames.length != headerConfig.size()) { if (headerNames.length != headerConfig.size()) {
result = ValidationError.withoutLineNumber().add("number of headers is not correct! there are " + result = ValidationError.withoutLineNumber().add("validation.message.header.length",
headerNames.length + Integer.toString(headerNames.length),
" but there should be " + Integer.toString(headerConfig.size()));
headerConfig.size());
return result; return result;
} }
@@ -249,13 +248,10 @@ public class Validator {
for(int i=0; i<headerConfig.size(); i++) { for(int i=0; i<headerConfig.size(); i++) {
String header = headerConfig.get(i); String header = headerConfig.get(i);
if (!header.equals(headerNames[i])) { if (!header.equals(headerNames[i])) {
error.add("header number " + error.add("validation.message.header.match",
i + Integer.toString(i),
" does not match \"" + header,
header + headerNames[i]);
"\" should be \"" +
headerNames[i] +
"\"");
} }
} }
if (!error.isEmpty()) { if (!error.isEmpty()) {

View File

@@ -13,3 +13,12 @@ title.validation.errors = Validation Errors:
validation.message.not.empty = should not be empty validation.message.not.empty = should not be empty
validation.message.integer = should be an integer validation.message.integer = should be an integer
validation.message.alphanumeric = should be alphanumeric validation.message.alphanumeric = should be alphanumeric
validation.message.groovy.exception = groovy script '{0}' throws exception: {1}
validation.message.groovy.return.null = groovy script '{0}' returns null
validation.message.min.length = has not min length of {0}
validation.message.max.length = has not max length of {0}
validation.message.date.format = is not a date of format {0}
validation.message.regexp = does not match {0}
validation.message.header.length = number of headers is not correct! there are {0} but there should be {1}
validation.message.header.match = header number {0} does not match "{1}" should be "{3}"

View File

@@ -21,3 +21,12 @@ title.validation.errors = Fehler in der Datei:
validation.message.not.empty = Darf nicht leer sein. validation.message.not.empty = Darf nicht leer sein.
validation.message.integer = Muss eine Zahl sein. validation.message.integer = Muss eine Zahl sein.
validation.message.alphanumeric = Darf nur Zahlen und Buchstaben enthalten. validation.message.alphanumeric = Darf nur Zahlen und Buchstaben enthalten.
validation.message.groovy.exception = groovy script '{0}' wirft folgenden Fehler: {1}
validation.message.groovy.return.null = groovy script '{0}' meldet "null"
validation.message.min.length = Hat nicht die minimale L\u00e4nge von {0}
validation.message.max.length = Hat nicht die maximale L\u00e4nge von {0}
validation.message.date.format = Das Datumsformat entspricht nicht {0}
validation.message.regexp = entspricht nicht dem regul\u00e4ren Ausdruck {0}
validation.message.header.length = Anzahl der \u00dcberschriften ist nicht korrekt! Es sind {0} aber es sollten {1} sein
validation.message.header.match = \u00dcberschrift in Spalte {0} stimmt nicht. "{1}" sollte "{3}" sein

View File

@@ -108,9 +108,9 @@ public class HeaderValidationTest {
return asList(new Object[][] { return asList(new Object[][] {
{ new String[] {}, new String[] {}, true, null }, { new String[] {}, new String[] {}, true, null },
{ new String[] {"a"}, new String[] {"a"}, true, null }, { new String[] {"a"}, new String[] {"a"}, true, null },
{ new String[] {"a"}, new String[] {"b"}, false, singletonList(new ValidationMessage("header number 0 does not match \"a\" should be \"b\""))}, { new String[] {"a"}, new String[] {"b"}, false, singletonList(new ValidationMessage("validation.message.header.match", "0", "a", "b"))},
{ new String[] {"a"}, new String[] {"a","b"}, false, singletonList(new ValidationMessage("number of headers is not correct! there are 2 but there should be 1"))}, { new String[] {"a"}, new String[] {"a","b"}, false, singletonList(new ValidationMessage("validation.message.header.length", "2", "1"))},
{ new String[] {"a", "b"}, new String[] {"b", "a"}, false, asList(new ValidationMessage("header number 0 does not match \"a\" should be \"b\""), new ValidationMessage("header number 1 does not match \"b\" should be \"a\"")) } { new String[] {"a", "b"}, new String[] {"b", "a"}, false, asList(new ValidationMessage("validation.message.header.match", "0", "a", "b"), new ValidationMessage("validation.message.header.match", "1", "b", "a")) }
}); });
} }
} }

View File

@@ -90,15 +90,15 @@ public class ValidatorTest {
{ "column", "integer", true, "column", "999", true, null }, { "column", "integer", true, "column", "999", true, null },
{ "column", "integer", true, "column", "a", false, new ValidationMessage("validation.message.integer") }, { "column", "integer", true, "column", "a", false, new ValidationMessage("validation.message.integer") },
{ "column", "minlength", 2, "column", "12", true, null }, { "column", "minlength", 2, "column", "12", true, null },
{ "column", "minlength", 2, "column", "1", false, new ValidationMessage("has not min length of 2") }, { "column", "minlength", 2, "column", "1", false, new ValidationMessage("validation.message.min.length", "2") },
{ "column", "maxlength", 2, "column", "12", true, null }, { "column", "maxlength", 2, "column", "12", true, null },
{ "column", "maxlength", 2, "column", "123", false, new ValidationMessage("has not max length of 2") }, { "column", "maxlength", 2, "column", "123", false, new ValidationMessage("validation.message.max.length", "2") },
{ "column", "date", "yyyyMMdd", "column", "20151127", true, null }, { "column", "date", "yyyyMMdd", "column", "20151127", true, null },
{ "column", "date", "yyyyMMdd", "column", "27.11.2015", false, new ValidationMessage("is not a date of format yyyyMMdd") }, { "column", "date", "yyyyMMdd", "column", "27.11.2015", false, new ValidationMessage("validation.message.date.format", "yyyyMMdd") },
{ "column", "alphanumeric", true, "column", "abcABC123", true, null }, { "column", "alphanumeric", true, "column", "abcABC123", true, null },
{ "column", "alphanumeric", true, "column", "-abcABC123", false, new ValidationMessage("validation.message.alphanumeric") }, { "column", "alphanumeric", true, "column", "-abcABC123", false, new ValidationMessage("validation.message.alphanumeric") },
{ "column", "regexp", "[a-z]*", "column", "abc", true, null }, { "column", "regexp", "[a-z]*", "column", "abc", true, null },
{ "column", "regexp", "[a-z]*", "column", "abcA", false, new ValidationMessage("does not match [a-z]*") }, { "column", "regexp", "[a-z]*", "column", "abcA", false, new ValidationMessage("validation.message.regexp", "[a-z]*") },
{ "column", "groovy", "value.contains('a')? 'true' : 'no a inside'", "column", "abcdef", true, null }, { "column", "groovy", "value.contains('a')? 'true' : 'no a inside'", "column", "abcdef", true, null },
{ "column", "groovy", "value.contains('a')? 'true' : 'no a inside'", "column", "bcdefg", false, new ValidationMessage("no a inside") }, { "column", "groovy", "value.contains('a')? 'true' : 'no a inside'", "column", "bcdefg", false, new ValidationMessage("no a inside") },
}); });