switched from config to Gson for better json support as the validation config will be editable in the application directly

This commit is contained in:
Andreas Billmann
2016-02-02 03:20:14 +01:00
parent d9405eb536
commit 10c2592510
12 changed files with 312 additions and 229 deletions

View File

@@ -21,8 +21,8 @@ dependencies {
compile group: 'org.codehaus.groovy', name: 'groovy-all', version: '2.4.5' compile group: 'org.codehaus.groovy', name: 'groovy-all', version: '2.4.5'
compile group: 'org.springframework', name:'spring-context', version: '4.2.4.RELEASE' compile group: 'org.springframework', name:'spring-context', version: '4.2.4.RELEASE'
compile group: 'net.sf.supercsv', name: 'super-csv', version: '2.4.0' compile group: 'net.sf.supercsv', name: 'super-csv', version: '2.4.0'
compile group: 'com.typesafe', name: 'config', version: '1.3.0'
compile group: 'commons-validator', name: 'commons-validator', version: '1.5.0' compile group: 'commons-validator', name: 'commons-validator', version: '1.5.0'
compile group: 'de.jensd', name: 'fontawesomefx', version: '8.8' compile group: 'de.jensd', name: 'fontawesomefx', version: '8.8'
compile group: 'org.controlsfx', name: 'controlsfx', version: '8.40.10' compile group: 'org.controlsfx', name: 'controlsfx', version: '8.40.10'
compile group: 'com.google.code.gson', name: 'gson', version: '2.5'
} }

View File

@@ -30,6 +30,7 @@ import javafx.beans.property.BooleanProperty;
import javafx.beans.property.ObjectProperty; import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleBooleanProperty; import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleObjectProperty; import javafx.beans.property.SimpleObjectProperty;
import javafx.concurrent.WorkerStateEvent;
import javafx.event.ActionEvent; import javafx.event.ActionEvent;
import javafx.event.EventHandler; import javafx.event.EventHandler;
import javafx.fxml.FXML; import javafx.fxml.FXML;
@@ -378,9 +379,9 @@ public class SmartCSVController extends FXMLController {
private void loadCsvPreferencesFromFile() { private void loadCsvPreferencesFromFile() {
if (PREFERENCES_FILE.exists()) { if (PREFERENCES_FILE.exists()) {
useLoadFileService(preferencesLoader, PREFERENCES_FILE); useLoadFileService(preferencesLoader, PREFERENCES_FILE,
event -> setCsvPreference(preferencesLoader.getCSVpreference()));
} }
setCsvPreference(preferencesLoader.getCSVpreference());
} }
private void saveCsvPreferences(CsvPreference csvPreference) { private void saveCsvPreferences(CsvPreference csvPreference) {
@@ -431,7 +432,10 @@ public class SmartCSVController extends FXMLController {
//Show open file dialog //Show open file dialog
File file = fileChooser.showOpenDialog(applicationPane.getScene().getWindow()); File file = fileChooser.showOpenDialog(applicationPane.getScene().getWindow());
if (file != null) { if (file != null) {
useLoadFileService(fileReader, file); useLoadFileService(fileReader, file, event -> runLater(() -> {
resetContent();
fileChanged.setValue(false);
}));
return file; return file;
} else { } else {
return initChildFile; return initChildFile;
@@ -462,14 +466,11 @@ public class SmartCSVController extends FXMLController {
return file; return file;
} }
private void useLoadFileService(FileReader fileReader, File file) { private void useLoadFileService(FileReader fileReader, File file, EventHandler<WorkerStateEvent> value) {
loadFileService.setFile(file); loadFileService.setFile(file);
loadFileService.setFileReader(fileReader); loadFileService.setFileReader(fileReader);
loadFileService.restart(); loadFileService.restart();
loadFileService.setOnSucceeded(event -> runLater(() -> { loadFileService.setOnSucceeded(value);
resetContent();
fileChanged.setValue(false);
}));
} }
private void useSaveFileService(FileWriter writer, File file) { private void useSaveFileService(FileWriter writer, File file) {

View File

@@ -26,8 +26,7 @@
package ninja.javafx.smartcsv.preferences; package ninja.javafx.smartcsv.preferences;
import com.typesafe.config.Config; import com.google.gson.GsonBuilder;
import com.typesafe.config.ConfigFactory;
import ninja.javafx.smartcsv.FileReader; import ninja.javafx.smartcsv.FileReader;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.supercsv.prefs.CsvPreference; import org.supercsv.prefs.CsvPreference;
@@ -35,6 +34,8 @@ import org.supercsv.quote.AlwaysQuoteMode;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import static ninja.javafx.smartcsv.preferences.QuoteModeHelper.getQuoteMode; import static ninja.javafx.smartcsv.preferences.QuoteModeHelper.getQuoteMode;
@@ -44,7 +45,7 @@ import static ninja.javafx.smartcsv.preferences.QuoteModeHelper.getQuoteMode;
@Service @Service
public class PreferencesFileReader implements FileReader { public class PreferencesFileReader implements FileReader {
private Config config; private Map config;
private CsvPreference csvPreference; private CsvPreference csvPreference;
public PreferencesFileReader() { public PreferencesFileReader() {
@@ -55,15 +56,15 @@ public class PreferencesFileReader implements FileReader {
@Override @Override
public void read(File filename) throws IOException { public void read(File filename) throws IOException {
config = ConfigFactory.parseFile(filename); config = new GsonBuilder().create().fromJson(new java.io.FileReader(filename), HashMap.class);
if (config != null) { if (config != null) {
char quoteChar = config.getString("quoteChar").charAt(0); char quoteChar = config.get("quoteChar").toString().charAt(0);
char delimiterChar = config.getString("delimiterChar").charAt(0); char delimiterChar = config.get("delimiterChar").toString().charAt(0);
String endOfLineSymbols = config.getString("endOfLineSymbols"); String endOfLineSymbols = config.get("endOfLineSymbols").toString();
boolean surroundingSpacesNeedQuotes = config.getBoolean("surroundingSpacesNeedQuotes"); boolean surroundingSpacesNeedQuotes = (Boolean)config.get("surroundingSpacesNeedQuotes");
boolean ignoreEmptyLines = config.getBoolean("ignoreEmptyLines"); boolean ignoreEmptyLines = (Boolean)config.get("ignoreEmptyLines");
String quoteMode = config.getString("quoteMode"); String quoteMode = config.get("quoteMode").toString();
csvPreference = new CsvPreference.Builder(quoteChar, delimiterChar, endOfLineSymbols) csvPreference = new CsvPreference.Builder(quoteChar, delimiterChar, endOfLineSymbols)
.useQuoteMode(getQuoteMode(quoteMode)) .useQuoteMode(getQuoteMode(quoteMode))

View File

@@ -26,9 +26,8 @@
package ninja.javafx.smartcsv.preferences; package ninja.javafx.smartcsv.preferences;
import com.typesafe.config.Config; import com.google.gson.Gson;
import com.typesafe.config.ConfigFactory; import com.google.gson.GsonBuilder;
import com.typesafe.config.ConfigRenderOptions;
import ninja.javafx.smartcsv.FileWriter; import ninja.javafx.smartcsv.FileWriter;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.supercsv.prefs.CsvPreference; import org.supercsv.prefs.CsvPreference;
@@ -60,8 +59,8 @@ public class PreferencesFileWriter implements FileWriter {
preferences.put("ignoreEmptyLines", csvPreference.isIgnoreEmptyLines()); preferences.put("ignoreEmptyLines", csvPreference.isIgnoreEmptyLines());
preferences.put("quoteMode", QuoteModeHelper.getQuoteModeName(csvPreference.getQuoteMode())); preferences.put("quoteMode", QuoteModeHelper.getQuoteModeName(csvPreference.getQuoteMode()));
Config config = ConfigFactory.parseMap(preferences); Gson gson = new GsonBuilder().setPrettyPrinting().create();
Files.write(file.toPath(), config.root().render(ConfigRenderOptions.concise()).getBytes()); Files.write(file.toPath(), gson.toJson(preferences).getBytes());
} }
} }

View File

@@ -0,0 +1,42 @@
/*
The MIT License (MIT)
-----------------------------------------------------------------------------
Copyright (c) 2015 javafx.ninja <info@javafx.ninja>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
package ninja.javafx.smartcsv.validation;
import com.google.gson.annotations.SerializedName;
/**
* header configuration for the validation
*/
public class HeaderConfiguration {
@SerializedName("list")
private String[] names ;
public String[] getNames() {
return names;
}
}

View File

@@ -0,0 +1,121 @@
/*
The MIT License (MIT)
-----------------------------------------------------------------------------
Copyright (c) 2015 javafx.ninja <info@javafx.ninja>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
package ninja.javafx.smartcsv.validation;
import com.google.gson.annotations.SerializedName;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static java.lang.Boolean.FALSE;
/**
* validation configuration
*/
public class ValidationConfiguration {
@SerializedName("headers")
private HeaderConfiguration headerConfiguration = new HeaderConfiguration();
@SerializedName("columns")
private Map<String, Map<String, Object>> columnConfigurations = new HashMap<>();
public String[] headerNames() {
if (noHeader()) return null;
return headerConfiguration.getNames();
}
public Boolean integerRuleFor(String column) {
if (noRulesFor(column)) return FALSE;
return defaultValue((Boolean)columnConfigurations.get(column).get("integer"), FALSE);
}
public Boolean doubleRuleFor(String column) {
if (noRulesFor(column)) return FALSE;
return defaultValue((Boolean)columnConfigurations.get(column).get("double"), FALSE);
}
public Boolean notEmptyRuleFor(String column) {
if (noRulesFor(column)) return FALSE;
return defaultValue((Boolean)columnConfigurations.get(column).get("not empty"), FALSE);
}
public Integer minLengthRuleFor(String column) {
if (noRulesFor(column)) return null;
return doubleToInteger((Double)columnConfigurations.get(column).get("minlength"));
}
public Integer maxLengthRuleFor(String column) {
if (noRulesFor(column)) return null;
return doubleToInteger((Double)columnConfigurations.get(column).get("maxlength"));
}
public String dateRuleFor(String column) {
if (noRulesFor(column)) return null;
return (String)columnConfigurations.get(column).get("date");
}
public Boolean alphanumericRuleFor(String column) {
if (noRulesFor(column)) return FALSE;
return defaultValue((Boolean)columnConfigurations.get(column).get("alphanumeric"), FALSE);
}
public String regexpRuleFor(String column) {
if (noRulesFor(column)) return null;
return (String)columnConfigurations.get(column).get("regexp");
}
public List<String> valueOfRuleFor(String column) {
if (noRulesFor(column)) return null;
return (List<String>)columnConfigurations.get(column).get("value of");
}
public String groovyRuleFor(String column) {
if (noRulesFor(column)) return null;
return (String)columnConfigurations.get(column).get("groovy");
}
private boolean noHeader() {
return headerConfiguration == null;
}
private boolean noRulesFor(String column) {
return columnConfigurations == null || columnConfigurations.get(column) == null;
}
private <T> T defaultValue(T value, T defaultValue) {
if (value == null) return defaultValue;
return value;
}
private Integer doubleToInteger(Double value) {
if (value == null) return null;
return (int)Math.round(value);
}
}

View File

@@ -26,8 +26,7 @@
package ninja.javafx.smartcsv.validation; package ninja.javafx.smartcsv.validation;
import com.typesafe.config.Config; import com.google.gson.GsonBuilder;
import com.typesafe.config.ConfigFactory;
import ninja.javafx.smartcsv.FileReader; import ninja.javafx.smartcsv.FileReader;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@@ -40,11 +39,11 @@ import java.io.IOException;
@Service @Service
public class ValidationFileReader implements FileReader { public class ValidationFileReader implements FileReader {
private Config config; private ValidationConfiguration config;
@Override @Override
public void read(File file) throws IOException { public void read(File file) throws IOException {
config = ConfigFactory.parseFile(file); config = new GsonBuilder().create().fromJson(new java.io.FileReader(file), ValidationConfiguration.class);
} }
public Validator getValidator() { public Validator getValidator() {

View File

@@ -26,7 +26,6 @@
package ninja.javafx.smartcsv.validation; package ninja.javafx.smartcsv.validation;
import com.typesafe.config.Config;
import groovy.lang.Binding; import groovy.lang.Binding;
import groovy.lang.GroovyShell; import groovy.lang.GroovyShell;
import groovy.lang.Script; import groovy.lang.Script;
@@ -49,7 +48,7 @@ public class Validator {
// member variables // member variables
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
private Config validationConfig; private ValidationConfiguration validationConfig;
private GroovyShell shell = new GroovyShell(); private GroovyShell shell = new GroovyShell();
private Map<String, Script> scriptCache = new HashMap<>(); private Map<String, Script> scriptCache = new HashMap<>();
@@ -62,7 +61,7 @@ public class Validator {
* JSON configuration for this validator * JSON configuration for this validator
* @param validationConfig * @param validationConfig
*/ */
public Validator(Config validationConfig) { public Validator(ValidationConfiguration validationConfig) {
this.validationConfig = validationConfig; this.validationConfig = validationConfig;
} }
@@ -80,31 +79,25 @@ public class Validator {
public ValidationError isValid(String column, String value, Integer lineNumber) { public ValidationError isValid(String column, String value, Integer lineNumber) {
ValidationError result = null; ValidationError result = null;
if (validationConfig != null) { if (validationConfig != null) {
Config columnSectionConfig = getColumnSectionConfig();
if (columnSectionConfig != null) {
Config columnConfig = getColumnConfig(columnSectionConfig, column);
if (columnConfig != null) {
ValidationError error = ValidationError.withLineNumber(lineNumber); ValidationError error = ValidationError.withLineNumber(lineNumber);
checkBlankOrNull(columnConfig, value, error); checkBlankOrNull(column, value, error);
if (value != null && !value.isEmpty()) { if (value != null && !value.isEmpty()) {
checkRegularExpression(columnConfig, value, error); checkRegularExpression(column, value, error);
checkAlphaNumeric(columnConfig, value, error); checkAlphaNumeric(column, value, error);
checkDate(columnConfig, value, error); checkDate(column, value, error);
checkMaxLength(columnConfig, value, error); checkMaxLength(column, value, error);
checkMinLength(columnConfig, value, error); checkMinLength(column, value, error);
checkInteger(columnConfig, value, error); checkInteger(column, value, error);
checkGroovy(column, columnConfig, value, error); checkGroovy(column, value, error);
checkValueOf(columnConfig, value, error); checkValueOf(column, value, error);
checkDouble(columnConfig, value, error); checkDouble(column, value, error);
} }
if (!error.isEmpty()) { if (!error.isEmpty()) {
result = error; result = error;
} }
} }
}
}
return result; return result;
} }
@@ -113,8 +106,8 @@ public class Validator {
// private methods // private methods
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
private void checkGroovy(String column, Config columnConfig, String value, ValidationError error) { private void checkGroovy(String column, String value, ValidationError error) {
String groovyScript = getString(columnConfig, "groovy"); String groovyScript = validationConfig.groovyRuleFor(column);
if (groovyScript != null) { if (groovyScript != null) {
Script script = scriptCache.get(column); Script script = scriptCache.get(column);
@@ -149,43 +142,42 @@ public class Validator {
return groovyResult.equals(true) || groovyResult.toString().trim().toLowerCase().equals("true"); return groovyResult.equals(true) || groovyResult.toString().trim().toLowerCase().equals("true");
} }
private void checkValueOf(Config columnConfig, String value, ValidationError error) { private void checkValueOf(String column, String value, ValidationError error) {
List<String> stringList = getStringList(columnConfig, "value of"); List<String> values = validationConfig.valueOfRuleFor(column);
if (stringList != null) { if (values != null) {
if (!stringList.contains(value)) { if (!values.contains(value)) {
String commaSeparated = stringList.stream().collect(joining(", ")); String commaSeparated = values.stream().collect(joining(", "));
error.add("validation.message.value.of", value, commaSeparated); error.add("validation.message.value.of", value, commaSeparated);
} }
} }
} }
private void checkBlankOrNull(Config columnConfig, String value, ValidationError error) { private void checkBlankOrNull(String column, String value, ValidationError error) {
if (getBoolean(columnConfig, "not empty")) { if (validationConfig.notEmptyRuleFor(column)) {
if (isBlankOrNull(value)) { if (isBlankOrNull(value)) {
error.add("validation.message.not.empty"); error.add("validation.message.not.empty");
} }
} }
} }
private void checkInteger(Config columnConfig, String value, ValidationError error) { private void checkInteger(String column, String value, ValidationError error) {
if (getBoolean(columnConfig, "integer")) { if (validationConfig.integerRuleFor(column)) {
if (!isInt(value)) { if (!isInt(value)) {
error.add("validation.message.integer"); error.add("validation.message.integer");
} }
} }
} }
private void checkDouble(Config columnConfig, String value, ValidationError error) { private void checkDouble(String column, String value, ValidationError error) {
if (getBoolean(columnConfig, "double")) { if (validationConfig.doubleRuleFor(column)) {
if (!isDouble(value)) { if (!isDouble(value)) {
error.add("validation.message.double"); error.add("validation.message.double");
} }
} }
} }
private void checkMinLength(String column, String value, ValidationError error) {
private void checkMinLength(Config columnConfig, String value, ValidationError error) { Integer minLength = validationConfig.minLengthRuleFor(column);
Integer minLength = getInteger(columnConfig, "minlength");
if (minLength != null) { if (minLength != null) {
if (!minLength(value, minLength)) { if (!minLength(value, minLength)) {
error.add("validation.message.min.length", minLength.toString()); error.add("validation.message.min.length", minLength.toString());
@@ -193,8 +185,8 @@ public class Validator {
} }
} }
private void checkMaxLength(Config columnConfig, String value, ValidationError error) { private void checkMaxLength(String column, String value, ValidationError error) {
Integer maxLength = getInteger(columnConfig, "maxlength"); Integer maxLength = validationConfig.maxLengthRuleFor(column);
if (maxLength != null) { if (maxLength != null) {
if (!maxLength(value, maxLength)) { if (!maxLength(value, maxLength)) {
error.add("validation.message.max.length", maxLength.toString()); error.add("validation.message.max.length", maxLength.toString());
@@ -202,8 +194,8 @@ public class Validator {
} }
} }
private void checkDate(Config columnConfig, String value, ValidationError error) { private void checkDate(String column, String value, ValidationError error) {
String dateformat = getString(columnConfig, "date"); String dateformat = validationConfig.dateRuleFor(column);
if (dateformat != null && !dateformat.trim().isEmpty()) { if (dateformat != null && !dateformat.trim().isEmpty()) {
if (!isDate(value, dateformat, true)) { if (!isDate(value, dateformat, true)) {
error.add("validation.message.date.format", dateformat); error.add("validation.message.date.format", dateformat);
@@ -211,16 +203,16 @@ public class Validator {
} }
} }
private void checkAlphaNumeric(Config columnConfig, String value, ValidationError error) { private void checkAlphaNumeric(String column, String value, ValidationError error) {
if (getBoolean(columnConfig, "alphanumeric")) { if (validationConfig.alphanumericRuleFor(column)) {
if (!matchRegexp(value, "[0-9a-zA-Z]*")) { if (!matchRegexp(value, "[0-9a-zA-Z]*")) {
error.add("validation.message.alphanumeric"); error.add("validation.message.alphanumeric");
} }
} }
} }
private void checkRegularExpression(Config columnConfig, String value, ValidationError error) { private void checkRegularExpression(String column, String value, ValidationError error) {
String regexp = getString(columnConfig, "regexp"); String regexp = validationConfig.regexpRuleFor(column);
if (regexp != null && !regexp.trim().isEmpty()) { if (regexp != null && !regexp.trim().isEmpty()) {
if (!matchRegexp(value, regexp)) { if (!matchRegexp(value, regexp)) {
error.add("validation.message.regexp", regexp); error.add("validation.message.regexp", regexp);
@@ -228,53 +220,25 @@ public class Validator {
} }
} }
private Config getColumnSectionConfig() {
return validationConfig.hasPath("columns") ? validationConfig.getConfig("columns") : null;
}
private Config getColumnConfig(Config columnSectionConfig, String column) {
return columnSectionConfig.hasPath(column) ? columnSectionConfig.getConfig(column) : null;
}
private String getString(Config columnConfig, String path) {
return columnConfig.hasPath(path) ? columnConfig.getString(path) : null;
}
private Integer getInteger(Config columnConfig, String path) {
return columnConfig.hasPath(path) ? columnConfig.getInt(path) : null;
}
private boolean getBoolean(Config columnConfig, String path) {
return columnConfig.hasPath(path) && columnConfig.getBoolean(path);
}
private List<String> getStringList(Config columnConfig, String path) {
return columnConfig.hasPath(path) ? columnConfig.getStringList(path) : null;
}
public ValidationError isHeaderValid(String[] headerNames) { public ValidationError isHeaderValid(String[] headerNames) {
ValidationError result = null; ValidationError result = null;
if (validationConfig != null) { if (validationConfig != null) {
if (validationConfig.hasPath("headers")) { String[] headerNamesConfig = validationConfig.headerNames();
Config headerSectionConfig = validationConfig.getConfig("headers"); if (headerNamesConfig != null) {
List<String> headerConfig = getStringList(headerSectionConfig, "list"); if (headerNames.length != headerNamesConfig.length) {
if (headerConfig != null) {
if (headerNames.length != headerConfig.size()) {
result = ValidationError.withoutLineNumber().add("validation.message.header.length", result = ValidationError.withoutLineNumber().add("validation.message.header.length",
Integer.toString(headerNames.length), Integer.toString(headerNames.length),
Integer.toString(headerConfig.size())); Integer.toString(headerNamesConfig.length));
return result; return result;
} }
ValidationError error = ValidationError.withoutLineNumber(); ValidationError error = ValidationError.withoutLineNumber();
for(int i=0; i<headerConfig.size(); i++) { for(int i=0; i<headerNamesConfig.length; i++) {
String header = headerConfig.get(i); if (!headerNamesConfig[i].equals(headerNames[i])) {
if (!header.equals(headerNames[i])) {
error.add("validation.message.header.match", error.add("validation.message.header.match",
Integer.toString(i), Integer.toString(i),
header, headerNamesConfig[i],
headerNames[i]); headerNames[i]);
} }
} }
@@ -283,7 +247,6 @@ public class Validator {
} }
} }
} }
}
return result; return result;
} }
} }

View File

@@ -46,8 +46,8 @@
<Hyperlink onAction="#openLinkInBrowser" text="https://spring.io/" GridPane.columnIndex="1" GridPane.rowIndex="3" /> <Hyperlink onAction="#openLinkInBrowser" text="https://spring.io/" GridPane.columnIndex="1" GridPane.rowIndex="3" />
<Label text="supercsv" GridPane.rowIndex="4" /> <Label text="supercsv" GridPane.rowIndex="4" />
<Hyperlink onAction="#openLinkInBrowser" text="http://super-csv.github.io/super-csv/" GridPane.columnIndex="1" GridPane.rowIndex="4" /> <Hyperlink onAction="#openLinkInBrowser" text="http://super-csv.github.io/super-csv/" GridPane.columnIndex="1" GridPane.rowIndex="4" />
<Label text="config" GridPane.rowIndex="5" /> <Label text="Gson" GridPane.rowIndex="5" />
<Hyperlink onAction="#openLinkInBrowser" text="https://github.com/typesafehub/config" GridPane.columnIndex="1" GridPane.rowIndex="5" /> <Hyperlink onAction="#openLinkInBrowser" text="https://github.com/google/gson/" GridPane.columnIndex="1" GridPane.rowIndex="5" />
<Label text="commons-validator" GridPane.rowIndex="6" /> <Label text="commons-validator" GridPane.rowIndex="6" />
<Hyperlink onAction="#openLinkInBrowser" text="https://commons.apache.org/proper/commons-validator/" GridPane.columnIndex="1" GridPane.rowIndex="6" /> <Hyperlink onAction="#openLinkInBrowser" text="https://commons.apache.org/proper/commons-validator/" GridPane.columnIndex="1" GridPane.rowIndex="6" />
<Label text="fontawesomefx" GridPane.rowIndex="7" /> <Label text="fontawesomefx" GridPane.rowIndex="7" />

View File

@@ -1,62 +0,0 @@
package ninja.javafx.smartcsv.validation;
import com.typesafe.config.Config;
import java.util.List;
import static java.util.Arrays.asList;
import static org.mockito.Mockito.*;
public class ConfigMock {
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// constants
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
private static final String HEADER_SECTION_KEY = "headers";
private static final String COLUMN_SECTION_KEY = "columns";
private static final String LIST_KEY = "list";
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// mocks
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
public static Config headerSectionConfig(String[] headerNames) {
Config headerSectionConfig = mock(Config.class);
Config listConfig = mock(Config.class);
when(headerSectionConfig.hasPath(HEADER_SECTION_KEY)).thenReturn(true);
when(headerSectionConfig.getConfig(HEADER_SECTION_KEY)).thenReturn(listConfig);
when(listConfig.hasPath(LIST_KEY)).thenReturn(true);
when(listConfig.getStringList(LIST_KEY)).thenReturn(asList(headerNames));
return headerSectionConfig;
}
public static Config columnSectionConfig(String column, String validation, Object value) {
Config columnSectionConfig = mock(Config.class);
Config columnConfig = mock(Config.class);
Config validatorConfig = mock(Config.class);
when(columnSectionConfig.hasPath(COLUMN_SECTION_KEY)).thenReturn(true);
when(columnSectionConfig.getConfig(COLUMN_SECTION_KEY)).thenReturn(columnConfig);
when(columnConfig.hasPath(column)).thenReturn(true);
when(columnConfig.getConfig(column)).thenReturn(validatorConfig);
when(validatorConfig.hasPath(validation)).thenReturn(true);
if (value instanceof Boolean) {
when(validatorConfig.getBoolean(validation)).thenReturn((Boolean) value);
} else if (value instanceof String) {
when(validatorConfig.getString(validation)).thenReturn((String) value);
} else if (value instanceof Integer) {
when(validatorConfig.getInt(validation)).thenReturn((Integer) value);
} else if (value instanceof List) {
when(validatorConfig.getStringList(validation)).thenReturn((List<String>) value);
}
return columnSectionConfig;
}
}

View File

@@ -26,20 +26,19 @@
package ninja.javafx.smartcsv.validation; package ninja.javafx.smartcsv.validation;
import com.typesafe.config.Config; import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.junit.runners.Parameterized; import org.junit.runners.Parameterized;
import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.Collections;
import java.util.List; import java.util.List;
import static java.util.Arrays.asList; import static java.util.Arrays.asList;
import static java.util.Collections.singletonList; import static java.util.Collections.singletonList;
import static ninja.javafx.smartcsv.validation.ConfigMock.headerSectionConfig; import static java.util.stream.Collectors.joining;
import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat; import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
@@ -52,7 +51,7 @@ public class HeaderValidationTest {
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// parameters // parameters
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
private Config config; private ValidationConfiguration config;
private Boolean expectedResult; private Boolean expectedResult;
private List<ValidationMessage> expectedErrors; private List<ValidationMessage> expectedErrors;
private String[] headerNames; private String[] headerNames;
@@ -66,11 +65,12 @@ public class HeaderValidationTest {
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// parameterized constructor // parameterized constructor
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
public HeaderValidationTest(String[] configHeaderNames, public HeaderValidationTest(String configHeaderNames,
String[] headerNames, String[] headerNames,
Boolean expectedResult, Boolean expectedResult,
List<ValidationMessage> expectedErrors) { List<ValidationMessage> expectedErrors) {
this.config = headerSectionConfig(configHeaderNames); Gson gson = new GsonBuilder().create();
this.config = gson.fromJson(configHeaderNames, ValidationConfiguration.class);
this.headerNames = headerNames; this.headerNames = headerNames;
this.expectedResult = expectedResult; this.expectedResult = expectedResult;
this.expectedErrors = expectedErrors; this.expectedErrors = expectedErrors;
@@ -106,11 +106,16 @@ public class HeaderValidationTest {
@Parameterized.Parameters @Parameterized.Parameters
public static Collection validationConfigurations() { public static Collection validationConfigurations() {
return asList(new Object[][] { return asList(new Object[][] {
{ new String[] {}, new String[] {}, true, null }, { json(), new String[] {}, true, null },
{ new String[] {"a"}, new String[] {"a"}, true, null }, { json("a"), new String[] {"a"}, true, null },
{ new String[] {"a"}, new String[] {"b"}, false, singletonList(new ValidationMessage("validation.message.header.match", "0", "a", "b"))}, { json("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("validation.message.header.length", "2", "1"))}, { json("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("validation.message.header.match", "0", "a", "b"), new ValidationMessage("validation.message.header.match", "1", "b", "a")) } { json("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")) }
}); });
} }
public static String json(String... headerNames) {
return "{\"headers\":{\"list\":[" + asList(headerNames).stream().collect(joining(", ")) + "]}}";
}
} }

View File

@@ -1,15 +1,17 @@
package ninja.javafx.smartcsv.validation; package ninja.javafx.smartcsv.validation;
import com.typesafe.config.Config; import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.junit.runners.Parameterized; import org.junit.runners.Parameterized;
import java.util.Collection; import java.util.Collection;
import java.util.List;
import static java.util.Arrays.asList; import static java.util.Arrays.asList;
import static ninja.javafx.smartcsv.validation.ConfigMock.columnSectionConfig; import static java.util.stream.Collectors.joining;
import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat; import static org.junit.Assert.assertThat;
@@ -23,7 +25,7 @@ public class ValidatorTest {
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// parameters // parameters
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
private Config config; private ValidationConfiguration config;
private String column; private String column;
private String value; private String value;
private Boolean expectedResult; private Boolean expectedResult;
@@ -39,14 +41,14 @@ public class ValidatorTest {
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// parameterized constructor // parameterized constructor
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
public ValidatorTest(String configcolumn, public ValidatorTest(String config,
String configValidation,
Object configValue,
String column, String column,
String value, String value,
Boolean expectedResult, Boolean expectedResult,
ValidationMessage expectedError) { ValidationMessage expectedError) {
this.config = columnSectionConfig(configcolumn, configValidation, configValue); System.out.println(config);
Gson gson = new GsonBuilder().create();
this.config = gson.fromJson(config, ValidationConfiguration.class);
this.column = column; this.column = column;
this.value = value; this.value = value;
this.expectedResult = expectedResult; this.expectedResult = expectedResult;
@@ -84,30 +86,42 @@ public class ValidatorTest {
@Parameterized.Parameters @Parameterized.Parameters
public static Collection validationConfigurations() { public static Collection validationConfigurations() {
return asList(new Object[][] { return asList(new Object[][] {
{ "column", "not empty", true, "column", "value", true, null }, { json("column", "not empty", true), "column", "value", true, null },
{ "column", "not empty", true, "column", "", false, new ValidationMessage("validation.message.not.empty") }, { json("column", "not empty", true), "column", "", false, new ValidationMessage("validation.message.not.empty") },
{ "column", "not empty", true, "column", null, false, new ValidationMessage("validation.message.not.empty") }, { json("column", "not empty", true), "column", null, false, new ValidationMessage("validation.message.not.empty") },
{ "column", "integer", true, "column", "999", true, null }, { json("column", "integer", true), "column", "999", true, null },
{ "column", "integer", true, "column", "a", false, new ValidationMessage("validation.message.integer") }, { json("column", "integer", true), "column", "a", false, new ValidationMessage("validation.message.integer") },
{ "column", "double", true, "column", "999", true, null }, { json("column", "double", true), "column", "999", true, null },
{ "column", "double", true, "column", "999.000", true, null }, { json("column", "double", true), "column", "999.000", true, null },
{ "column", "double", true, "column", "a", false, new ValidationMessage("validation.message.double") }, { json("column", "double", true), "column", "a", false, new ValidationMessage("validation.message.double") },
{ "column", "minlength", 2, "column", "12", true, null }, { json("column", "minlength", 2), "column", "12", true, null },
{ "column", "minlength", 2, "column", "1", false, new ValidationMessage("validation.message.min.length", "2") }, { json("column", "minlength", 2), "column", "1", false, new ValidationMessage("validation.message.min.length", "2") },
{ "column", "maxlength", 2, "column", "12", true, null }, { json("column", "maxlength", 2), "column", "12", true, null },
{ "column", "maxlength", 2, "column", "123", false, new ValidationMessage("validation.message.max.length", "2") }, { json("column", "maxlength", 2), "column", "123", false, new ValidationMessage("validation.message.max.length", "2") },
{ "column", "date", "yyyyMMdd", "column", "20151127", true, null }, { json("column", "date", "yyyyMMdd"), "column", "20151127", true, null },
{ "column", "date", "yyyyMMdd", "column", "27.11.2015", false, new ValidationMessage("validation.message.date.format", "yyyyMMdd") }, { json("column", "date", "yyyyMMdd"), "column", "27.11.2015", false, new ValidationMessage("validation.message.date.format", "yyyyMMdd") },
{ "column", "alphanumeric", true, "column", "abcABC123", true, null }, { json("column", "alphanumeric", true), "column", "abcABC123", true, null },
{ "column", "alphanumeric", true, "column", "-abcABC123", false, new ValidationMessage("validation.message.alphanumeric") }, { json("column", "alphanumeric", true), "column", "-abcABC123", false, new ValidationMessage("validation.message.alphanumeric") },
{ "column", "regexp", "[a-z]*", "column", "abc", true, null }, { json("column", "regexp", "[a-z]*"), "column", "abc", true, null },
{ "column", "regexp", "[a-z]*", "column", "abcA", false, new ValidationMessage("validation.message.regexp", "[a-z]*") }, { json("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 }, { json("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") }, { json("column", "groovy", "value.contains('a')? 'true' : 'no a inside'"), "column", "bcdefg", false, new ValidationMessage("no a inside") },
{ "column", "value of", asList("a","b","c","d","e"), "column", "c", true, null }, { json("column", "value of", asList("a","b","c","d","e")), "column", "c", true, null },
{ "column", "value of", asList("a","b","c","d","e"), "column", "f", false, new ValidationMessage("validation.message.value.of", "f", "a, b, c, d, e") }, { json("column", "value of", asList("a","b","c","d","e")), "column", "f", false, new ValidationMessage("validation.message.value.of", "f", "a, b, c, d, e") },
}); });
} }
public static String json(String column, String rule, Object value) {
String json = "{\"columns\":{\"" + column + "\":{\"" + rule + "\":";
if (value instanceof String) {
json += "\""+ value + "\"";
} else if (value instanceof List) {
List<String> list = (List<String>)value;
json += "[" + list.stream().collect(joining(", ")) + "]";
} else {
json += value;
}
json += "}}}";
return json;
}
} }