25 Commits
0.6 ... 0.8

Author SHA1 Message Date
Andreas Billmann
a37a84bd09 Merge remote-tracking branch 'remotes/origin/json_table_schema' 2016-09-22 20:48:57 +02:00
Andreas Billmann
5100c668ab version 0.8 based on JSON Table Schema 2016-09-22 20:46:30 +02:00
Andreas Billmann
90bda028ec finding enum based on external value should use external value as compare value 2016-09-18 15:26:59 +02:00
Andreas Billmann
5e31f834ac fixed the imports of the new validation classes 2016-09-18 15:18:48 +02:00
Andreas Billmann
d689423c61 added 2016 to the license text 2016-09-18 14:58:38 +02:00
Andreas Billmann
9e8d71ca1d implemented string format validations 2016-09-18 14:58:37 +02:00
Andreas Billmann
70855e614a the editor can handle the support subset of JSON Table Schema 2016-09-18 14:58:37 +02:00
4354afdf1d handle defaults 2016-09-18 14:58:36 +02:00
4002219dfe reorganize validation package 2016-09-18 14:58:35 +02:00
7723906935 write values back to config 2016-09-18 14:58:34 +02:00
5694273c51 read constraints into an object instead of some map structure and change form init of validation editor 2016-09-18 14:58:33 +02:00
04a54da798 editor should support new config ... first steps 2016-09-18 14:58:32 +02:00
6f635f5e75 ignore log file 2016-09-18 14:58:31 +02:00
742f129ea9 change editor to the new config
The editor should handle the new configuration
2016-09-18 14:58:31 +02:00
0c391e292e first quick implementation of to support json table schema 2016-09-18 14:58:30 +02:00
cd0ca0ed11 set preferences on csv file reader and writer after load and changing through dialog 2016-09-14 19:23:36 +02:00
e799f0ac45 min and max value spinner are dependent 2016-08-11 13:25:15 +02:00
3664a4e8a7 the most senseless combination of rules are not possible any more 2016-08-11 13:11:23 +02:00
e87eec2162 no need for 2 checkboxes when it is a boolean rule 2016-08-11 12:55:09 +02:00
3adfd566bc error export implemented and message on error side bar includes column name 2016-08-10 23:45:47 +02:00
e6742a4e30 error export implemented and message on error side bar includes column name 2016-08-10 23:41:47 +02:00
7472c66823 fixed uniqueness validation and renamed the abstract class when empty values are valid 2016-08-09 21:17:29 +02:00
c7873ef0ba unique validation has to work on the model to have the correct snapshot of the data 2016-08-09 20:59:29 +02:00
b79a20201e removed the special treatment of NotEmptyValidation 2016-08-09 20:59:29 +02:00
Andreas Billmann
3ebf78805c Update README.md 2016-08-08 17:23:02 +02:00
72 changed files with 1491 additions and 598 deletions

1
.gitignore vendored
View File

@@ -74,3 +74,4 @@ crashlytics.properties
crashlytics-build.properties crashlytics-build.properties
smartcsv.log

View File

@@ -1,6 +1,6 @@
# SmartCSV.fx # SmartCSV.fx
##Description ##Description
A simple JavaFX application to load, save and edit a CSV file and provide a JSON configuration for columns to check the values in the columns. A simple JavaFX application to load, save and edit a CSV file and provide a [JSON Table Schema](http://specs.frictionlessdata.io/json-table-schema/) for columns to check the values in the columns.
##Motivation ##Motivation
At work I have the need to fix wrong CSV files from customers. It is hard to find the errors and fix them in a texteditor, At work I have the need to fix wrong CSV files from customers. It is hard to find the errors and fix them in a texteditor,
@@ -14,7 +14,7 @@ even in a "normal" CSV editor. So I decided to write this simple JavaFX applicat
[Wiki & Documentation](https://github.com/frosch95/SmartCSV.fx/wiki) [Wiki & Documentation](https://github.com/frosch95/SmartCSV.fx/wiki)
binary distribution of the [latest release (0.5)](https://drive.google.com/file/d/0BwY9gBUvn5qmejllOTRwbEJYdDA/view?usp=sharing) binary distribution of the [latest release (0.8)](https://github.com/frosch95/SmartCSV.fx/releases/download/0.8/SmartCSV.fx-0.8-SNAPSHOT.zip)
##Talks ##Talks
[Introduction](http://javafx.ninja/talks/introduction/) [Introduction](http://javafx.ninja/talks/introduction/)
@@ -23,7 +23,7 @@ binary distribution of the [latest release (0.5)](https://drive.google.com/file/
###The MIT License (MIT) ###The MIT License (MIT)
Copyright (c) 2015 Andreas Billmann <andreas.billmann@javafx.ninja> Copyright (c) 2015-2016 Andreas Billmann <andreas.billmann@javafx.ninja>

View File

@@ -1,5 +1,5 @@
group 'ninja.javafx' group 'ninja.javafx'
version '0.6-SNAPSHOT' version '0.8-SNAPSHOT'
apply plugin: 'java' apply plugin: 'java'
apply plugin: 'groovy' apply plugin: 'groovy'

View File

@@ -1,7 +1,7 @@
The MIT License (MIT) The MIT License (MIT)
------------------------------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------------------------------------
Copyright (c) 2015 Andreas Billmann <andreas.billmann@javafx.ninja> Copyright (c) 2015-2016 Andreas Billmann <andreas.billmann@javafx.ninja>

View File

@@ -2,7 +2,7 @@
The MIT License (MIT) The MIT License (MIT)
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
Copyright (c) 2015 javafx.ninja <info@javafx.ninja> Copyright (c) 2015-2016 javafx.ninja <info@javafx.ninja>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@@ -2,7 +2,7 @@
The MIT License (MIT) The MIT License (MIT)
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
Copyright (c) 2015 javafx.ninja <info@javafx.ninja> Copyright (c) 2015-2016 javafx.ninja <info@javafx.ninja>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@@ -2,7 +2,7 @@
The MIT License (MIT) The MIT License (MIT)
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
Copyright (c) 2015 javafx.ninja <info@javafx.ninja> Copyright (c) 2015-2016 javafx.ninja <info@javafx.ninja>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@@ -2,7 +2,7 @@
The MIT License (MIT) The MIT License (MIT)
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
Copyright (c) 2015 javafx.ninja <info@javafx.ninja> Copyright (c) 2015-2016 javafx.ninja <info@javafx.ninja>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@@ -2,7 +2,7 @@
The MIT License (MIT) The MIT License (MIT)
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
Copyright (c) 2015 javafx.ninja <info@javafx.ninja> Copyright (c) 2015-2016 javafx.ninja <info@javafx.ninja>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@@ -0,0 +1,71 @@
package ninja.javafx.smartcsv.export;
import javafx.concurrent.Service;
import javafx.concurrent.Task;
import ninja.javafx.smartcsv.fx.table.model.CSVModel;
import ninja.javafx.smartcsv.validation.ValidationError;
import java.io.File;
import java.io.StringWriter;
import java.nio.file.Files;
import java.util.ResourceBundle;
import static java.text.MessageFormat.format;
import static ninja.javafx.smartcsv.fx.util.I18nValidationUtil.getI18nValidatioMessage;
/**
* this class exports the error messages into a log file
*/
@org.springframework.stereotype.Service
public class ErrorExport extends Service {
private CSVModel model;
private File file;
private ResourceBundle resourceBundle;
private String csvFilename;
public void setCsvFilename(String csvFilename) {
this.csvFilename = csvFilename;
}
public void setResourceBundle(ResourceBundle resourceBundle) {
this.resourceBundle = resourceBundle;
}
public void setModel(CSVModel model) {
this.model = model;
}
public void setFile(File file) {
this.file = file;
}
@Override
protected Task createTask() {
return new Task() {
@Override
protected Void call() throws Exception {
try {
StringWriter log = new StringWriter();
log.append(
format(resourceBundle.getString("log.header.message"),
csvFilename,
Integer.toString(model.getValidationError().size()))).append("\n\n");
model.getValidationError().forEach(error ->
log.append(
format(resourceBundle.getString("log.message"),
error.getLineNumber().toString(),
error.getColumn(),
getI18nValidatioMessage(resourceBundle, error))).append("\n")
);
Files.write(file.toPath(), log.toString().getBytes());
} catch (Throwable ex) {
ex.printStackTrace();
}
return null;
}
};
}
}

View File

@@ -2,7 +2,7 @@
The MIT License (MIT) The MIT License (MIT)
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
Copyright (c) 2015 javafx.ninja <info@javafx.ninja> Copyright (c) 2015-2016 javafx.ninja <info@javafx.ninja>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@@ -2,7 +2,7 @@
The MIT License (MIT) The MIT License (MIT)
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
Copyright (c) 2015 javafx.ninja <info@javafx.ninja> Copyright (c) 2015-2016 javafx.ninja <info@javafx.ninja>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@@ -2,7 +2,7 @@
The MIT License (MIT) The MIT License (MIT)
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
Copyright (c) 2015 javafx.ninja <info@javafx.ninja> Copyright (c) 2015-2016 javafx.ninja <info@javafx.ninja>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
@@ -26,6 +26,7 @@
package ninja.javafx.smartcsv.fx; package ninja.javafx.smartcsv.fx;
import javafx.beans.binding.Bindings;
import javafx.collections.ListChangeListener; import javafx.collections.ListChangeListener;
import javafx.collections.WeakListChangeListener; import javafx.collections.WeakListChangeListener;
import javafx.concurrent.WorkerStateEvent; import javafx.concurrent.WorkerStateEvent;
@@ -39,6 +40,7 @@ import javafx.scene.layout.BorderPane;
import javafx.stage.FileChooser; import javafx.stage.FileChooser;
import ninja.javafx.smartcsv.csv.CSVFileReader; import ninja.javafx.smartcsv.csv.CSVFileReader;
import ninja.javafx.smartcsv.csv.CSVFileWriter; import ninja.javafx.smartcsv.csv.CSVFileWriter;
import ninja.javafx.smartcsv.export.ErrorExport;
import ninja.javafx.smartcsv.files.FileStorage; import ninja.javafx.smartcsv.files.FileStorage;
import ninja.javafx.smartcsv.fx.about.AboutController; import ninja.javafx.smartcsv.fx.about.AboutController;
import ninja.javafx.smartcsv.fx.list.ErrorSideBar; import ninja.javafx.smartcsv.fx.list.ErrorSideBar;
@@ -54,7 +56,7 @@ import ninja.javafx.smartcsv.fx.util.SaveFileService;
import ninja.javafx.smartcsv.fx.validation.ValidationEditorController; import ninja.javafx.smartcsv.fx.validation.ValidationEditorController;
import ninja.javafx.smartcsv.preferences.PreferencesFileReader; import ninja.javafx.smartcsv.preferences.PreferencesFileReader;
import ninja.javafx.smartcsv.preferences.PreferencesFileWriter; import ninja.javafx.smartcsv.preferences.PreferencesFileWriter;
import ninja.javafx.smartcsv.validation.ValidationConfiguration; import ninja.javafx.smartcsv.validation.configuration.ValidationConfiguration;
import ninja.javafx.smartcsv.validation.ValidationError; import ninja.javafx.smartcsv.validation.ValidationError;
import ninja.javafx.smartcsv.validation.ValidationFileReader; import ninja.javafx.smartcsv.validation.ValidationFileReader;
import ninja.javafx.smartcsv.validation.ValidationFileWriter; import ninja.javafx.smartcsv.validation.ValidationFileWriter;
@@ -95,6 +97,9 @@ public class SmartCSVController extends FXMLController {
public static final String CSV_FILTER_EXTENSION = "*.csv"; public static final String CSV_FILTER_EXTENSION = "*.csv";
public static final String JSON_FILTER_TEXT = "JSON files (*.json)"; public static final String JSON_FILTER_TEXT = "JSON files (*.json)";
public static final String JSON_FILTER_EXTENSION = "*.json"; public static final String JSON_FILTER_EXTENSION = "*.json";
public static final String EXPORT_LOG_FILTER_TEXT = "Error log files (*.log)";
public static final String EXPORT_LOG_FILTER_EXTENSION = "*.log";
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// injections // injections
@@ -115,6 +120,9 @@ public class SmartCSVController extends FXMLController {
@Autowired @Autowired
private SaveFileService saveFileService; private SaveFileService saveFileService;
@Autowired
private ErrorExport errorExport;
@FXML @FXML
private BorderPane applicationPane; private BorderPane applicationPane;
@@ -157,6 +165,9 @@ public class SmartCSVController extends FXMLController {
@FXML @FXML
private MenuItem gotoLineMenuItem; private MenuItem gotoLineMenuItem;
@FXML
private MenuItem exportMenuItem;
@FXML @FXML
private Button saveButton; private Button saveButton;
@@ -181,6 +192,9 @@ public class SmartCSVController extends FXMLController {
@FXML @FXML
private Button addRowButton; private Button addRowButton;
@FXML
private Button exportButton;
@FXML @FXML
private Label currentLineNumber; private Label currentLineNumber;
@@ -193,8 +207,10 @@ public class SmartCSVController extends FXMLController {
private TableView<CSVRow> tableView; private TableView<CSVRow> tableView;
private ErrorSideBar errorSideBar; private ErrorSideBar errorSideBar;
private ResourceBundle resourceBundle; private ResourceBundle resourceBundle;
private CSVFileReader csvFileReader = new CSVFileReader();
private CSVFileWriter csvFileWriter = new CSVFileWriter();
private FileStorage<CSVModel> currentCsvFile = new FileStorage<>(new CSVFileReader(), new CSVFileWriter()); private FileStorage<CSVModel> currentCsvFile = new FileStorage<>(csvFileReader, csvFileWriter);
private FileStorage<ValidationConfiguration> currentConfigFile = new FileStorage<>(new ValidationFileReader(), new ValidationFileWriter()); private FileStorage<ValidationConfiguration> currentConfigFile = new FileStorage<>(new ValidationFileReader(), new ValidationFileWriter());
private FileStorage<CsvPreference> csvPreferenceFile = new FileStorage<>(new PreferencesFileReader(), new PreferencesFileWriter()); private FileStorage<CsvPreference> csvPreferenceFile = new FileStorage<>(new PreferencesFileReader(), new PreferencesFileWriter());
@@ -370,6 +386,26 @@ public class SmartCSVController extends FXMLController {
} }
} }
@FXML
public void export(ActionEvent actionEvent) {
final FileChooser fileChooser = new FileChooser();
//Set extension filter
final FileChooser.ExtensionFilter extFilter = new FileChooser.ExtensionFilter(EXPORT_LOG_FILTER_TEXT, EXPORT_LOG_FILTER_EXTENSION);
fileChooser.getExtensionFilters().add(extFilter);
fileChooser.setTitle("Save");
//Show open file dialog
File file = fileChooser.showSaveDialog(applicationPane.getScene().getWindow());
if (file != null) {
errorExport.setCsvFilename(currentCsvFile.getFile().getName());
errorExport.setModel(currentCsvFile.getContent());
errorExport.setFile(file);
errorExport.setResourceBundle(resourceBundle);
errorExport.restart();
}
}
public boolean canExit() { public boolean canExit() {
boolean canExit = true; boolean canExit = true;
if (currentCsvFile.getContent() != null && currentCsvFile.isFileChanged()) { if (currentCsvFile.getContent() != null && currentCsvFile.isFileChanged()) {
@@ -389,6 +425,7 @@ public class SmartCSVController extends FXMLController {
public void showValidationEditor(String column) { public void showValidationEditor(String column) {
validationEditorController.setSelectedColumn(column); validationEditorController.setSelectedColumn(column);
validationEditorController.updateForm();
Alert alert = new Alert(Alert.AlertType.CONFIRMATION); Alert alert = new Alert(Alert.AlertType.CONFIRMATION);
alert.setGraphic(null); alert.setGraphic(null);
@@ -486,6 +523,9 @@ public class SmartCSVController extends FXMLController {
private void setCsvPreference(CsvPreference csvPreference) { private void setCsvPreference(CsvPreference csvPreference) {
preferencesController.setCsvPreference(csvPreference); preferencesController.setCsvPreference(csvPreference);
csvFileReader.setCsvPreference(csvPreference);
csvFileWriter.setCsvPreference(csvPreference);
} }
private void loadFile(String filterText, private void loadFile(String filterText,
@@ -552,6 +592,8 @@ public class SmartCSVController extends FXMLController {
* Creates new table view and add the new content * Creates new table view and add the new content
*/ */
private void resetContent() { private void resetContent() {
resetExportButtons();
if (currentCsvFile.getContent() != null) { if (currentCsvFile.getContent() != null) {
currentCsvFile.getContent().getValidationError().addListener(weakErrorListListener); currentCsvFile.getContent().getValidationError().addListener(weakErrorListListener);
currentCsvFile.getContent().setValidationConfiguration(currentConfigFile.getContent()); currentCsvFile.getContent().setValidationConfiguration(currentConfigFile.getContent());
@@ -575,9 +617,22 @@ public class SmartCSVController extends FXMLController {
setRightAnchor(tableView, 0.0); setRightAnchor(tableView, 0.0);
tableWrapper.getChildren().setAll(tableView); tableWrapper.getChildren().setAll(tableView);
errorSideBar.setModel(currentCsvFile.getContent()); errorSideBar.setModel(currentCsvFile.getContent());
binExportButtons();
} }
} }
private void binExportButtons() {
exportButton.disableProperty().bind(Bindings.isEmpty(currentCsvFile.getContent().getValidationError()));
exportMenuItem.disableProperty().bind(Bindings.isEmpty(currentCsvFile.getContent().getValidationError()));
}
private void resetExportButtons() {
exportButton.disableProperty().unbind();
exportMenuItem.disableProperty().unbind();
exportButton.disableProperty().setValue(true);
exportMenuItem.disableProperty().setValue(true);
}
/** /**
* Adds a column with the given name to the tableview * Adds a column with the given name to the tableview
* @param header name of the column header * @param header name of the column header

View File

@@ -2,7 +2,7 @@
The MIT License (MIT) The MIT License (MIT)
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
Copyright (c) 2015 javafx.ninja <info@javafx.ninja> Copyright (c) 2015-2016 javafx.ninja <info@javafx.ninja>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@@ -2,7 +2,7 @@
The MIT License (MIT) The MIT License (MIT)
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
Copyright (c) 2015 javafx.ninja <info@javafx.ninja> Copyright (c) 2015-2016 javafx.ninja <info@javafx.ninja>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
@@ -48,7 +48,7 @@ import java.util.ResourceBundle;
import static javafx.geometry.Pos.CENTER; import static javafx.geometry.Pos.CENTER;
import static ninja.javafx.smartcsv.fx.util.ColorConstants.ERROR_COLOR; import static ninja.javafx.smartcsv.fx.util.ColorConstants.ERROR_COLOR;
import static ninja.javafx.smartcsv.fx.util.ColorConstants.OK_COLOR; import static ninja.javafx.smartcsv.fx.util.ColorConstants.OK_COLOR;
import static ninja.javafx.smartcsv.fx.util.I18nValidationUtil.getI18nValidatioMessage; import static ninja.javafx.smartcsv.fx.util.I18nValidationUtil.getI18nValidatioMessageWithColumn;
/** /**
* clickable side bar with error markers * clickable side bar with error markers
@@ -137,9 +137,7 @@ public class ErrorSideBar extends Region {
int rows = model.get().getRows().size(); int rows = model.get().getRows().size();
double space = (double)heightWithoutStatusBlock() / rows; double space = (double)heightWithoutStatusBlock() / rows;
for (ValidationError error : errorList) { errorList.forEach(error -> errorMarkerList.add(generateErrorMarker(space, error)));
errorMarkerList.add(generateErrorMarker(space, error));
}
} }
} }
getChildren().setAll(errorMarkerList); getChildren().setAll(errorMarkerList);
@@ -158,7 +156,7 @@ public class ErrorSideBar extends Region {
errorMarker.setStyle("-fx-background-color: " + ERROR_COLOR); errorMarker.setStyle("-fx-background-color: " + ERROR_COLOR);
errorMarker.setOnMouseClicked(event -> selectedValidationError.setValue(error)); errorMarker.setOnMouseClicked(event -> selectedValidationError.setValue(error));
errorMarker.setOnMouseEntered(event -> { errorMarker.setOnMouseEntered(event -> {
popOver.setContentNode(popupContent(getI18nValidatioMessage(resourceBundle, error))); popOver.setContentNode(popupContent(getI18nValidatioMessageWithColumn(resourceBundle, error)));
popOver.show(errorMarker, -16); popOver.show(errorMarker, -16);
}); });
return errorMarker; return errorMarker;

View File

@@ -2,7 +2,7 @@
The MIT License (MIT) The MIT License (MIT)
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
Copyright (c) 2015 javafx.ninja <info@javafx.ninja> Copyright (c) 2015-2016 javafx.ninja <info@javafx.ninja>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@@ -2,7 +2,7 @@
The MIT License (MIT) The MIT License (MIT)
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
Copyright (c) 2015 javafx.ninja <info@javafx.ninja> Copyright (c) 2015-2016 javafx.ninja <info@javafx.ninja>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@@ -2,7 +2,7 @@
The MIT License (MIT) The MIT License (MIT)
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
Copyright (c) 2015 javafx.ninja <info@javafx.ninja> Copyright (c) 2015-2016 javafx.ninja <info@javafx.ninja>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@@ -2,7 +2,7 @@
The MIT License (MIT) The MIT License (MIT)
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
Copyright (c) 2015 javafx.ninja <info@javafx.ninja> Copyright (c) 2015-2016 javafx.ninja <info@javafx.ninja>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@@ -2,7 +2,7 @@
The MIT License (MIT) The MIT License (MIT)
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
Copyright (c) 2015 javafx.ninja <info@javafx.ninja> Copyright (c) 2015-2016 javafx.ninja <info@javafx.ninja>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
@@ -29,7 +29,7 @@ package ninja.javafx.smartcsv.fx.table.model;
import javafx.collections.FXCollections; import javafx.collections.FXCollections;
import javafx.collections.ObservableList; import javafx.collections.ObservableList;
import ninja.javafx.smartcsv.validation.RevalidationService; import ninja.javafx.smartcsv.validation.RevalidationService;
import ninja.javafx.smartcsv.validation.ValidationConfiguration; import ninja.javafx.smartcsv.validation.configuration.ValidationConfiguration;
import ninja.javafx.smartcsv.validation.ValidationError; import ninja.javafx.smartcsv.validation.ValidationError;
import ninja.javafx.smartcsv.validation.Validator; import ninja.javafx.smartcsv.validation.Validator;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
@@ -39,7 +39,7 @@ import org.apache.logging.log4j.Logger;
* The CSVModel is the client representation for the csv filepath. * The CSVModel is the client representation for the csv filepath.
* It holds the data in rows, stores the header and manages the validator. * It holds the data in rows, stores the header and manages the validator.
*/ */
public final class CSVModel { public final class CSVModel implements ColumnValueProvider {
private static final Logger logger = LogManager.getLogger(CSVModel.class); private static final Logger logger = LogManager.getLogger(CSVModel.class);
@@ -55,7 +55,7 @@ public final class CSVModel {
* @param validationConfiguration the validator configuration for this data * @param validationConfiguration the validator configuration for this data
*/ */
public void setValidationConfiguration(ValidationConfiguration validationConfiguration) { public void setValidationConfiguration(ValidationConfiguration validationConfiguration) {
this.validator = new Validator(validationConfiguration); this.validator = new Validator(validationConfiguration, this);
revalidate(); revalidate();
} }
@@ -145,11 +145,19 @@ public final class CSVModel {
public ValidationConfiguration createValidationConfiguration() { public ValidationConfiguration createValidationConfiguration() {
ValidationConfiguration newValidationConfiguration = new ValidationConfiguration(); ValidationConfiguration newValidationConfiguration = new ValidationConfiguration();
newValidationConfiguration.setHeaderNames(this.header); newValidationConfiguration.setHeaderNames(this.header);
this.validator = new Validator(newValidationConfiguration); this.validator = new Validator(newValidationConfiguration, this);
this.revalidate(); this.revalidate();
return newValidationConfiguration; return newValidationConfiguration;
} }
@Override
public String getValue(int row, String column) {
return rows.get(row).getColumns().get(column).getValue().getValue();
}
@Override
public int getNumberOfRows() {
return rows.size();
}
} }

View File

@@ -2,7 +2,7 @@
The MIT License (MIT) The MIT License (MIT)
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
Copyright (c) 2015 javafx.ninja <info@javafx.ninja> Copyright (c) 2015-2016 javafx.ninja <info@javafx.ninja>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@@ -2,7 +2,7 @@
The MIT License (MIT) The MIT License (MIT)
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
Copyright (c) 2015 javafx.ninja <info@javafx.ninja> Copyright (c) 2015-2016 javafx.ninja <info@javafx.ninja>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@@ -0,0 +1,11 @@
package ninja.javafx.smartcsv.fx.table.model;
/**
* interface for easier access to values in a column
*/
public interface ColumnValueProvider {
String getValue(int row, String column);
int getNumberOfRows();
}

View File

@@ -2,7 +2,7 @@
The MIT License (MIT) The MIT License (MIT)
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
Copyright (c) 2015 javafx.ninja <info@javafx.ninja> Copyright (c) 2015-2016 javafx.ninja <info@javafx.ninja>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@@ -2,7 +2,7 @@
The MIT License (MIT) The MIT License (MIT)
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
Copyright (c) 2015 javafx.ninja <info@javafx.ninja> Copyright (c) 2015-2016 javafx.ninja <info@javafx.ninja>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
@@ -43,9 +43,8 @@ public class I18nValidationUtil {
public static String getI18nValidatioMessage(ResourceBundle resourceBundle, List<ValidationError> errors) { public static String getI18nValidatioMessage(ResourceBundle resourceBundle, List<ValidationError> errors) {
StringWriter message = new StringWriter(); StringWriter message = new StringWriter();
for (ValidationError validationError: errors) { errors.forEach(error -> message.append(getI18nValidatioMessage(resourceBundle, error)).append("\n"));
message.append(getI18nValidatioMessage(resourceBundle, validationError)).append("\n");
}
if (message.toString().length() != 0) { if (message.toString().length() != 0) {
return cutOffLastLineBreak(message.toString()); return cutOffLastLineBreak(message.toString());
@@ -54,11 +53,20 @@ public class I18nValidationUtil {
return ""; return "";
} }
public static String getI18nValidatioMessageWithColumn(ResourceBundle resourceBundle, ValidationError error) {
return getI18nValidatioMessage(resourceBundle, error, resourceBundle.getString("column") + " " + error.getColumn() + " : ");
}
public static String getI18nValidatioMessage(ResourceBundle resourceBundle, ValidationError error) { public static String getI18nValidatioMessage(ResourceBundle resourceBundle, ValidationError error) {
return getI18nValidatioMessage(resourceBundle, error, "");
}
private static String getI18nValidatioMessage(ResourceBundle resourceBundle, ValidationError error, String prefix) {
List<ValidationMessage> validationMessages = error.getMessages(); List<ValidationMessage> validationMessages = error.getMessages();
StringWriter message = new StringWriter(); StringWriter message = new StringWriter();
for (ValidationMessage validationMessage: validationMessages) { validationMessages.forEach(validationMessage -> {
message.append(prefix);
if (resourceBundle.containsKey(validationMessage.getKey())) { if (resourceBundle.containsKey(validationMessage.getKey())) {
String resourceText = resourceBundle.getString(validationMessage.getKey()); String resourceText = resourceBundle.getString(validationMessage.getKey());
if (validationMessage.getParameters().length > 0) { if (validationMessage.getParameters().length > 0) {
@@ -69,7 +77,7 @@ public class I18nValidationUtil {
} else { } else {
message.append(validationMessage.getKey()).append("\n"); message.append(validationMessage.getKey()).append("\n");
} }
} });
if (!validationMessages.isEmpty()) { if (!validationMessages.isEmpty()) {
return cutOffLastLineBreak(message.toString()); return cutOffLastLineBreak(message.toString());

View File

@@ -2,7 +2,7 @@
The MIT License (MIT) The MIT License (MIT)
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
Copyright (c) 2015 javafx.ninja <info@javafx.ninja> Copyright (c) 2015-2016 javafx.ninja <info@javafx.ninja>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@@ -2,7 +2,7 @@
The MIT License (MIT) The MIT License (MIT)
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
Copyright (c) 2015 javafx.ninja <info@javafx.ninja> Copyright (c) 2015-2016 javafx.ninja <info@javafx.ninja>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@@ -0,0 +1,61 @@
/*
The MIT License (MIT)
-----------------------------------------------------------------------------
Copyright (c) 2015-2016 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.fx.validation;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.util.Callback;
import ninja.javafx.smartcsv.validation.configuration.StringFormat;
import java.util.ResourceBundle;
/**
* cell factory for string formats
*/
public class StringFormatEditorCellFactory implements Callback<ListView<StringFormat>, ListCell<StringFormat>> {
private ResourceBundle resourceBundle;
public StringFormatEditorCellFactory(ResourceBundle resourceBundle) {
this.resourceBundle = resourceBundle;
}
@Override
public ListCell<StringFormat> call(ListView<StringFormat> param) {
return new ListCell<StringFormat>(){
@Override
protected void updateItem(StringFormat item, boolean empty) {
super.updateItem(item, empty);
if (item == null || empty) {
setGraphic(null);
} else {
setText(resourceBundle.getString("format.type."+item));
}
}
} ;
}
}

View File

@@ -0,0 +1,54 @@
/*
The MIT License (MIT)
-----------------------------------------------------------------------------
Copyright (c) 2015-2016 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.fx.validation;
import javafx.util.StringConverter;
import ninja.javafx.smartcsv.validation.configuration.StringFormat;
import java.util.ResourceBundle;
/**
* converter for string formats
*/
public class StringFormatStringConverter extends StringConverter<StringFormat> {
private ResourceBundle resourceBundle;
public StringFormatStringConverter(ResourceBundle resourceBundle) {
this.resourceBundle = resourceBundle;
}
@Override
public String toString(StringFormat item) {
return resourceBundle.getString("format.type."+item);
}
@Override
public StringFormat fromString(String string) {
return StringFormat.fromExternalValue(string);
}
}

View File

@@ -2,7 +2,7 @@
The MIT License (MIT) The MIT License (MIT)
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
Copyright (c) 2015 javafx.ninja <info@javafx.ninja> Copyright (c) 2015-2016 javafx.ninja <info@javafx.ninja>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
@@ -30,8 +30,9 @@ import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty; import javafx.beans.property.StringProperty;
import javafx.fxml.FXML; import javafx.fxml.FXML;
import javafx.scene.control.*; import javafx.scene.control.*;
import javafx.scene.control.SpinnerValueFactory.IntegerSpinnerValueFactory;
import ninja.javafx.smartcsv.fx.FXMLController; import ninja.javafx.smartcsv.fx.FXMLController;
import ninja.javafx.smartcsv.validation.ValidationConfiguration; import ninja.javafx.smartcsv.validation.configuration.*;
import org.fxmisc.richtext.CodeArea; import org.fxmisc.richtext.CodeArea;
import org.fxmisc.richtext.LineNumberFactory; import org.fxmisc.richtext.LineNumberFactory;
import org.fxmisc.richtext.StyleSpans; import org.fxmisc.richtext.StyleSpans;
@@ -47,8 +48,11 @@ import java.util.ResourceBundle;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import static java.lang.Boolean.FALSE;
import static java.util.Arrays.asList; import static java.util.Arrays.asList;
import static java.util.stream.Collectors.joining; import static java.util.stream.Collectors.joining;
import static javafx.beans.binding.Bindings.when;
import static ninja.javafx.smartcsv.validation.configuration.Type.STRING;
/** /**
* controller for editing column validations * controller for editing column validations
@@ -75,7 +79,7 @@ public class ValidationEditorController extends FXMLController {
"transient", "true", "try", "void", "volatile", "while" "transient", "true", "try", "void", "volatile", "while"
}; };
private static final String KEYWORD_PATTERN = "\\b(" + String.join("|", KEYWORDS) + ")\\b"; private static final String KEYWORD_PATTERN = "\\b(" + String.join("|", (CharSequence[]) KEYWORDS) + ")\\b";
private static final String PAREN_PATTERN = "\\(|\\)"; private static final String PAREN_PATTERN = "\\(|\\)";
private static final String BRACE_PATTERN = "\\{|\\}"; private static final String BRACE_PATTERN = "\\{|\\}";
private static final String BRACKET_PATTERN = "\\[|\\]"; private static final String BRACKET_PATTERN = "\\[|\\]";
@@ -96,19 +100,13 @@ public class ValidationEditorController extends FXMLController {
); );
@FXML @FXML
private CheckBox notEmptyRuleCheckBox; private ComboBox<Type> typeComboBox;
@FXML @FXML
private CheckBox integerRuleCheckBox; private ComboBox<StringFormat> formatComboBox;
@FXML @FXML
private CheckBox doublerRuleCheckBox; private TextField formatTextField;
@FXML
private CheckBox alphanumericRuleCheckBox;
@FXML
private CheckBox uniqueRuleCheckBox;
@FXML @FXML
private Spinner<Integer> minLengthSpinner; private Spinner<Integer> minLengthSpinner;
@@ -116,9 +114,6 @@ public class ValidationEditorController extends FXMLController {
@FXML @FXML
private Spinner<Integer> maxLengthSpinner; private Spinner<Integer> maxLengthSpinner;
@FXML
private TextField dateformatRuleTextField;
@FXML @FXML
private TextField regexpRuleTextField; private TextField regexpRuleTextField;
@@ -131,24 +126,12 @@ public class ValidationEditorController extends FXMLController {
@FXML @FXML
private CheckBox enableNotEmptyRule; private CheckBox enableNotEmptyRule;
@FXML
private CheckBox enableIntegerRule;
@FXML
private CheckBox enableDoubleRule;
@FXML
private CheckBox enableAlphanumericRule;
@FXML @FXML
private CheckBox enableMinLengthRule; private CheckBox enableMinLengthRule;
@FXML @FXML
private CheckBox enableMaxLengthRule; private CheckBox enableMaxLengthRule;
@FXML
private CheckBox enableDateRule;
@FXML @FXML
private CheckBox enableRegexpRule; private CheckBox enableRegexpRule;
@@ -170,25 +153,13 @@ public class ValidationEditorController extends FXMLController {
@Override @Override
public void initialize(URL location, ResourceBundle resources) { public void initialize(URL location, ResourceBundle resources) {
initTypeAndFormatInput(resources);
minLengthSpinner.setValueFactory(new SpinnerValueFactory.IntegerSpinnerValueFactory(0, Integer.MAX_VALUE, 0)); initMinMaxSpinner();
maxLengthSpinner.setValueFactory(new SpinnerValueFactory.IntegerSpinnerValueFactory(0, Integer.MAX_VALUE, 0));
initCheckBox(notEmptyRuleCheckBox, enableNotEmptyRule);
initCheckBox(integerRuleCheckBox, enableIntegerRule);
initCheckBox(doublerRuleCheckBox, enableDoubleRule);
initCheckBox(alphanumericRuleCheckBox, enableAlphanumericRule);
initCheckBox(uniqueRuleCheckBox, enableUniqueRule);
initSpinner(minLengthSpinner, enableMinLengthRule); initSpinner(minLengthSpinner, enableMinLengthRule);
initSpinner(maxLengthSpinner, enableMaxLengthRule); initSpinner(maxLengthSpinner, enableMaxLengthRule);
initTextInputControl(dateformatRuleTextField, enableDateRule);
initTextInputControl(regexpRuleTextField, enableRegexpRule); initTextInputControl(regexpRuleTextField, enableRegexpRule);
initTextInputControl(valueOfRuleTextField, enableValueOfRule); initTextInputControl(valueOfRuleTextField, enableValueOfRule);
initCodeAreaControl(groovyRuleTextArea, enableGroovyRule); initCodeAreaControl(groovyRuleTextArea, enableGroovyRule);
selectedColumn.addListener(observable -> {
updateForm();
});
} }
public String getSelectedColumn() { public String getSelectedColumn() {
@@ -207,152 +178,235 @@ public class ValidationEditorController extends FXMLController {
this.validationConfiguration = validationConfiguration; this.validationConfiguration = validationConfiguration;
} }
private void initTypeAndFormatInput(ResourceBundle resources) {
typeComboBox.getItems().addAll(STRING,
Type.INTEGER,
Type.NUMBER,
Type.DATE,
Type.DATETIME,
Type.TIME);
formatComboBox.setCellFactory(new StringFormatEditorCellFactory(resources));
formatComboBox.setConverter(new StringFormatStringConverter(resources));
formatComboBox.getItems().addAll(
StringFormat.DEFAULT,
StringFormat.EMAIL,
StringFormat.URI,
StringFormat.BINARY,
StringFormat.UUID
);
typeComboBox.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> changeFormat());
}
private void updateFormatTextField() {
switch (typeComboBox.getValue()) {
case DATE:
case DATETIME:
case TIME:
formatTextField.setVisible(true);
formatTextField.setText(getCurrentFieldConfig().getFormat());
break;
default:
formatTextField.setVisible(false);
formatTextField.setText(null);
break;
}
}
private void updateFormatComboBox() {
switch (typeComboBox.getValue()) {
case STRING:
formatComboBox.setVisible(true);
formatComboBox.getSelectionModel().select(StringFormat.fromExternalValue(getCurrentFieldConfig().getFormat()));
break;
default:
formatComboBox.setVisible(false);
break;
}
}
private void initMinMaxSpinner() {
IntegerSpinnerValueFactory minValueFactory = new IntegerSpinnerValueFactory(0, Integer.MAX_VALUE, 0);
minLengthSpinner.setValueFactory(minValueFactory);
IntegerSpinnerValueFactory maxValueFactory = new IntegerSpinnerValueFactory(0, Integer.MAX_VALUE, 0);
maxLengthSpinner.setValueFactory(maxValueFactory);
minValueFactory.maxProperty().bind(
when(enableMaxLengthRule.selectedProperty()).
then(maxLengthSpinner.valueProperty()).
otherwise(Integer.MAX_VALUE));
maxValueFactory.minProperty().bind(
when(enableMinLengthRule.selectedProperty()).
then(minLengthSpinner.valueProperty()).
otherwise(0));
}
private void changeFormat() {
switch (typeComboBox.getValue()) {
case STRING:
updateFormatComboBox();
break;
case DATE:
case DATETIME:
case TIME:
updateFormatTextField();
break;
case INTEGER:
case NUMBER:
default:
// format: no options
formatComboBox.setVisible(false);
formatTextField.setVisible(false);
break;
}
}
public void updateConfiguration() { public void updateConfiguration() {
if (enableIntegerRule.isSelected()) { Field config = getCurrentFieldConfig();
validationConfiguration.setIntegerRuleFor(selectedColumn.getValue(), integerRuleCheckBox.isSelected()); config.setType(typeComboBox.getValue());
} else {
validationConfiguration.setIntegerRuleFor(selectedColumn.getValue(), null);
}
if (enableNotEmptyRule.isSelected()) { switch (typeComboBox.getValue()) {
validationConfiguration.setNotEmptyRuleFor(selectedColumn.getValue(), notEmptyRuleCheckBox.isSelected()); case STRING:
config.setFormat(formatComboBox.getValue().getExternalValue());
break;
case DATE:
case DATETIME:
case TIME:
if (formatTextField.getText().trim().isEmpty()) {
config.setFormat(null);
} else { } else {
validationConfiguration.setNotEmptyRuleFor(selectedColumn.getValue(), null); // TODO: validate input
config.setFormat(formatTextField.getText());
} }
break;
if (enableUniqueRule.isSelected()) { case INTEGER:
validationConfiguration.setUniqueRuleFor(selectedColumn.getValue(), uniqueRuleCheckBox.isSelected()); case NUMBER:
} else { default:
validationConfiguration.setUniqueRuleFor(selectedColumn.getValue(), null); // format: no options
} config.setFormat(null);
break;
if (enableDoubleRule.isSelected()) {
validationConfiguration.setDoubleRuleFor(selectedColumn.getValue(), doublerRuleCheckBox.isSelected());
} else {
validationConfiguration.setDoubleRuleFor(selectedColumn.getValue(), null);
}
if (enableAlphanumericRule.isSelected()) {
validationConfiguration.setAlphanumericRuleFor(selectedColumn.getValue(), alphanumericRuleCheckBox.isSelected());
} else {
validationConfiguration.setAlphanumericRuleFor(selectedColumn.getValue(), null);
}
if (enableDateRule.isSelected()) {
validationConfiguration.setDateRuleFor(selectedColumn.getValue(), dateformatRuleTextField.getText());
} else {
validationConfiguration.setDateRuleFor(selectedColumn.getValue(), null);
} }
if (enableGroovyRule.isSelected()) { if (enableGroovyRule.isSelected()) {
validationConfiguration.setGroovyRuleFor(selectedColumn.getValue(), groovyRuleTextArea.getText()); config.setGroovy(groovyRuleTextArea.getText());
} else { } else {
validationConfiguration.setGroovyRuleFor(selectedColumn.getValue(), null); config.setGroovy(null);
}
Constraints constraints = config.getConstraints();
if (constraints == null) {
constraints = new Constraints();
}
if (enableNotEmptyRule.isSelected()) {
constraints.setRequired(enableNotEmptyRule.isSelected());
} else {
constraints.setRequired(null);
}
if (enableUniqueRule.isSelected()) {
constraints.setUnique(enableUniqueRule.isSelected());
} else {
constraints.setUnique(null);
} }
if (enableMinLengthRule.isSelected()) { if (enableMinLengthRule.isSelected()) {
validationConfiguration.setMinLengthRuleFor(selectedColumn.getValue(), minLengthSpinner.getValue()); constraints.setMinLength(minLengthSpinner.getValue());
} else { } else {
validationConfiguration.setMinLengthRuleFor(selectedColumn.getValue(), null); constraints.setMinLength(null);
} }
if (enableMaxLengthRule.isSelected()) { if (enableMaxLengthRule.isSelected()) {
validationConfiguration.setMaxLengthRuleFor(selectedColumn.getValue(), maxLengthSpinner.getValue()); constraints.setMaxLength(maxLengthSpinner.getValue());
} else { } else {
validationConfiguration.setMaxLengthRuleFor(selectedColumn.getValue(), null); constraints.setMaxLength(null);
} }
if (enableRegexpRule.isSelected()) { if (enableRegexpRule.isSelected()) {
validationConfiguration.setRegexpRuleFor(selectedColumn.getValue(), regexpRuleTextField.getText()); constraints.setPattern(regexpRuleTextField.getText());
} else { } else {
validationConfiguration.setRegexpRuleFor(selectedColumn.getValue(), null); constraints.setPattern(null);
} }
if (enableValueOfRule.isSelected()) { if (enableValueOfRule.isSelected()) {
validationConfiguration.setValueOfRuleFor(selectedColumn.getValue(), asList(valueOfRuleTextField.getText().split(", "))); constraints.setEnumeration(asList(valueOfRuleTextField.getText().split(", ")));
} else { } else {
validationConfiguration.setValueOfRuleFor(selectedColumn.getValue(), null); constraints.setEnumeration(null);
} }
} }
private void updateForm() { private Field getCurrentFieldConfig() {
return validationConfiguration.getFieldConfiguration(getSelectedColumn());
}
updateCheckBox( private void addDependencyListener(CheckBox rule, CheckBox... dependentRules) {
notEmptyRuleCheckBox, rule.selectedProperty().addListener((observable, oldValue, newValue) -> {
validationConfiguration.getNotEmptyRuleFor(getSelectedColumn()), if (newValue) {
enableNotEmptyRule for (CheckBox dependentRule: dependentRules) {
dependentRule.selectedProperty().setValue(false);
}
}
});
}
public void updateForm() {
Field config = getCurrentFieldConfig();
if (config.getType() != null) {
typeComboBox.setValue(config.getType());
} else {
typeComboBox.setValue(STRING);
}
updateFormatComboBox();
updateFormatTextField();
updateCodeAreaControl(
groovyRuleTextArea,
config.getGroovy(),
enableGroovyRule
); );
updateCheckBox( Constraints constraints = config.getConstraints();
integerRuleCheckBox, updateCheckBox(constraints != null ? constraints.getRequired() : FALSE, enableNotEmptyRule);
validationConfiguration.getIntegerRuleFor(getSelectedColumn()), updateCheckBox(constraints != null ? constraints.getUnique() : FALSE, enableUniqueRule);
enableIntegerRule
);
updateCheckBox(
doublerRuleCheckBox,
validationConfiguration.getDoubleRuleFor(getSelectedColumn()),
enableDoubleRule
);
updateCheckBox(
alphanumericRuleCheckBox,
validationConfiguration.getAlphanumericRuleFor(getSelectedColumn()),
enableAlphanumericRule
);
updateCheckBox(
uniqueRuleCheckBox,
validationConfiguration.getUniqueRuleFor(getSelectedColumn()),
enableUniqueRule
);
updateSpinner( updateSpinner(
minLengthSpinner, minLengthSpinner,
validationConfiguration.getMinLengthRuleFor(getSelectedColumn()), constraints != null ? constraints.getMinLength() : null,
enableMinLengthRule enableMinLengthRule
); );
updateSpinner( updateSpinner(
maxLengthSpinner, maxLengthSpinner,
validationConfiguration.getMaxLengthRuleFor(getSelectedColumn()), constraints != null ? constraints.getMaxLength() : null,
enableMaxLengthRule enableMaxLengthRule
); );
updateTextInputControl(
dateformatRuleTextField,
validationConfiguration.getDateRuleFor(getSelectedColumn()),
enableDateRule
);
updateTextInputControl( updateTextInputControl(
regexpRuleTextField, regexpRuleTextField,
validationConfiguration.getRegexpRuleFor(getSelectedColumn()), constraints != null ? constraints.getPattern() : null,
enableRegexpRule enableRegexpRule
); );
updateTextInputControl( updateTextInputControl(
valueOfRuleTextField, valueOfRuleTextField,
validationConfiguration.getValueOfRuleFor(getSelectedColumn()), constraints != null ? constraints.getEnumeration() : null,
enableValueOfRule enableValueOfRule
); );
updateCodeAreaControl(
groovyRuleTextArea,
validationConfiguration.getGroovyRuleFor(getSelectedColumn()),
enableGroovyRule
);
} }
private void updateCheckBox(CheckBox rule, Boolean value, CheckBox ruleEnabled) { private void updateCheckBox(Boolean value, CheckBox ruleEnabled) {
if (value == null) { if (value == null) {
ruleEnabled.setSelected(false); ruleEnabled.setSelected(false);
} else { } else {
rule.setSelected(value); ruleEnabled.setSelected(value);
ruleEnabled.setSelected(true);
} }
} }
@@ -392,15 +446,6 @@ public class ValidationEditorController extends FXMLController {
} }
} }
private void initCheckBox(CheckBox rule, CheckBox ruleEnabled) {
rule.disableProperty().bind(ruleEnabled.selectedProperty().not());
ruleEnabled.selectedProperty().addListener((observable, oldValue, newValue) -> {
if (!newValue) {
rule.setSelected(false);
}
});
}
private void initSpinner(Spinner rule, CheckBox ruleEnabled) { private void initSpinner(Spinner rule, CheckBox ruleEnabled) {
rule.disableProperty().bind(ruleEnabled.selectedProperty().not()); rule.disableProperty().bind(ruleEnabled.selectedProperty().not());
ruleEnabled.selectedProperty().addListener((observable, oldValue, newValue) -> { ruleEnabled.selectedProperty().addListener((observable, oldValue, newValue) -> {

View File

@@ -2,7 +2,7 @@
The MIT License (MIT) The MIT License (MIT)
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
Copyright (c) 2015 javafx.ninja <info@javafx.ninja> Copyright (c) 2015-2016 javafx.ninja <info@javafx.ninja>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@@ -2,7 +2,7 @@
The MIT License (MIT) The MIT License (MIT)
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
Copyright (c) 2015 javafx.ninja <info@javafx.ninja> Copyright (c) 2015-2016 javafx.ninja <info@javafx.ninja>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@@ -2,7 +2,7 @@
The MIT License (MIT) The MIT License (MIT)
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
Copyright (c) 2015 javafx.ninja <info@javafx.ninja> Copyright (c) 2015-2016 javafx.ninja <info@javafx.ninja>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@@ -2,7 +2,7 @@
The MIT License (MIT) The MIT License (MIT)
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
Copyright (c) 2015 javafx.ninja <info@javafx.ninja> Copyright (c) 2015-2016 javafx.ninja <info@javafx.ninja>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@@ -1,176 +0,0 @@
/*
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;
/**
* 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 void setHeaderNames(String[] headerNames) {
headerConfiguration.setNames(headerNames);
}
public Boolean getUniqueRuleFor(String column) {
return (Boolean)getValue(column, "unique");
}
public Boolean getIntegerRuleFor(String column) {
return (Boolean)getValue(column, "integer");
}
public Boolean getDoubleRuleFor(String column) {
return (Boolean)getValue(column, "double");
}
public Boolean getNotEmptyRuleFor(String column) {
return (Boolean)getValue(column, "not empty");
}
public Integer getMinLengthRuleFor(String column) {
return doubleToInteger((Double)getValue(column, "minlength"));
}
public Integer getMaxLengthRuleFor(String column) {
Double value = (Double)getValue(column, "maxlength");
return value != null ? doubleToInteger(value) : null;
}
public String getDateRuleFor(String column) {
return (String)getValue(column, "date");
}
public Boolean getAlphanumericRuleFor(String column) {
return (Boolean)getValue(column, "alphanumeric");
}
public String getRegexpRuleFor(String column) {
return (String)getValue(column, "regexp");
}
public List<String> getValueOfRuleFor(String column) {
return (List<String>)getValue(column, "value of");
}
public String getGroovyRuleFor(String column) {
return (String)getValue(column, "groovy");
}
public void setIntegerRuleFor(String column, Boolean value) {
setValue(column, value, "integer");
}
public void setDoubleRuleFor(String column, Boolean value) {
setValue(column, value, "double");
}
public void setNotEmptyRuleFor(String column, Boolean value) {
setValue(column, value, "not empty");
}
public void setUniqueRuleFor(String column, Boolean value) {
setValue(column, value, "unique");
}
public void setMinLengthRuleFor(String column, Integer value) {
setValue(column, value == null ? null : value.doubleValue(), "minlength");
}
public void setMaxLengthRuleFor(String column, Integer value) {
setValue(column, value == null ? null : value.doubleValue(), "maxlength");
}
public void setDateRuleFor(String column, String value) {
setValue(column, value, "date");
}
public void setAlphanumericRuleFor(String column, Boolean value) {
setValue(column, value, "alphanumeric");
}
public void setRegexpRuleFor(String column, String value) {
setValue(column, value, "regexp");
}
public void setValueOfRuleFor(String column, List<String> value) {
setValue(column, value, "value of");
}
public void setGroovyRuleFor(String column, String value) {
setValue(column, value, "groovy");
}
private void setValue(String column, Object value, String key) {
if (!columnConfigurations.containsKey(column)) {
columnConfigurations.put(column, new HashMap<>());
}
if (value == null && columnConfigurations.get(column).containsKey(key)) {
columnConfigurations.get(column).remove(key);
} else {
columnConfigurations.get(column).put(key, value);
}
}
private Object getValue(String column, String key) {
if (columnConfigurations != null) {
Map rulesForColumn = columnConfigurations.get(column);
if (rulesForColumn != null) {
return columnConfigurations.get(column).get(key);
}
}
return null;
}
private boolean noHeader() {
return headerConfiguration == null;
}
private Integer doubleToInteger(Double value) {
if (value == null) return null;
return (int)Math.round(value);
}
}

View File

@@ -2,7 +2,7 @@
The MIT License (MIT) The MIT License (MIT)
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
Copyright (c) 2015 javafx.ninja <info@javafx.ninja> Copyright (c) 2015-2016 javafx.ninja <info@javafx.ninja>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
@@ -38,6 +38,7 @@ public class ValidationError {
private List<ValidationMessage> messages = new ArrayList<>(); private List<ValidationMessage> messages = new ArrayList<>();
private Integer lineNumber; private Integer lineNumber;
private String column = "";
private ValidationError(Integer lineNumber) { private ValidationError(Integer lineNumber) {
this.lineNumber = lineNumber; this.lineNumber = lineNumber;
@@ -51,10 +52,19 @@ public class ValidationError {
return new ValidationError(-1); return new ValidationError(-1);
} }
public ValidationError column(String column) {
this.column = column;
return this;
}
public Integer getLineNumber() { public Integer getLineNumber() {
return lineNumber; return lineNumber;
} }
public String getColumn() {
return column;
}
public List<ValidationMessage> getMessages() { public List<ValidationMessage> getMessages() {
return messages; return messages;
} }

View File

@@ -2,7 +2,7 @@
The MIT License (MIT) The MIT License (MIT)
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
Copyright (c) 2015 javafx.ninja <info@javafx.ninja> Copyright (c) 2015-2016 javafx.ninja <info@javafx.ninja>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
@@ -28,10 +28,14 @@ package ninja.javafx.smartcsv.validation;
import com.google.gson.GsonBuilder; import com.google.gson.GsonBuilder;
import ninja.javafx.smartcsv.FileReader; import ninja.javafx.smartcsv.FileReader;
import ninja.javafx.smartcsv.validation.configuration.Field;
import ninja.javafx.smartcsv.validation.configuration.ValidationConfiguration;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import static ninja.javafx.smartcsv.validation.configuration.Type.*;
/** /**
* This class loads the constraints as json config * This class loads the constraints as json config
*/ */
@@ -42,6 +46,30 @@ public class ValidationFileReader implements FileReader<ValidationConfiguration>
@Override @Override
public void read(File file) throws IOException { public void read(File file) throws IOException {
config = new GsonBuilder().create().fromJson(new java.io.FileReader(file), ValidationConfiguration.class); config = new GsonBuilder().create().fromJson(new java.io.FileReader(file), ValidationConfiguration.class);
setDefaults();
}
private void setDefaults() {
for (Field field : config.getFields()) {
if (field.getType() == null) {
field.setType(STRING);
}
if (field.getType() == DATE) {
if (field.getFormat() == null) {
field.setFormat("yyyy-MM-dd");
}
}
if (field.getType() == DATETIME) {
if (field.getFormat() == null) {
field.setFormat("yyyy-MM-ddThh:mm:ssZ");
}
}
if (field.getType() == TIME) {
if (field.getFormat() == null) {
field.setFormat("hh:mm:ss");
}
}
}
} }
public ValidationConfiguration getContent() { public ValidationConfiguration getContent() {

View File

@@ -2,7 +2,7 @@
The MIT License (MIT) The MIT License (MIT)
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
Copyright (c) 2015 javafx.ninja <info@javafx.ninja> Copyright (c) 2015-2016 javafx.ninja <info@javafx.ninja>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
@@ -29,6 +29,7 @@ package ninja.javafx.smartcsv.validation;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.GsonBuilder; import com.google.gson.GsonBuilder;
import ninja.javafx.smartcsv.FileWriter; import ninja.javafx.smartcsv.FileWriter;
import ninja.javafx.smartcsv.validation.configuration.ValidationConfiguration;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;

View File

@@ -0,0 +1,43 @@
package ninja.javafx.smartcsv.validation;
/**
* @author abi
*/
public class ValidationFormatHelper {
public static String dateFormat(String format, String defaultFormat) {
if (format != null && !format.trim().isEmpty()) {
format = format.trim();
if (format.startsWith("fmt:")) {
format = format.substring(4);
format = format.replace("%Y", "yyyy");
format = format.replace("%y", "yy");
format = format.replace("%m", "MM");
format = format.replace("%d", "dd");
format = format.replace("%a", "E");
format = format.replace("%A", "EEEE");
format = format.replace("%w", "F");
format = format.replace("%b", "MMM");
format = format.replace("%B", "MMMMM");
format = format.replace("%H", "HH");
format = format.replace("%I", "hh");
format = format.replace("%p", "a");
format = format.replace("%M", "mm");
format = format.replace("%S", "ss");
format = format.replace("%z", "Z");
format = format.replace("%Z", "z");
format = format.replace("%j", "DDD");
format = format.replace("%U", "ww");
return format;
}
}
return defaultFormat;
}
public static Integer doubleToInteger(Double value) {
if (value == null) return null;
return (int)Math.round(value);
}
}

View File

@@ -2,7 +2,7 @@
The MIT License (MIT) The MIT License (MIT)
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
Copyright (c) 2015 javafx.ninja <info@javafx.ninja> Copyright (c) 2015-2016 javafx.ninja <info@javafx.ninja>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@@ -2,7 +2,7 @@
The MIT License (MIT) The MIT License (MIT)
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
Copyright (c) 2015 javafx.ninja <info@javafx.ninja> Copyright (c) 2015-2016 javafx.ninja <info@javafx.ninja>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
@@ -26,10 +26,20 @@
package ninja.javafx.smartcsv.validation; package ninja.javafx.smartcsv.validation;
import ninja.javafx.smartcsv.fx.table.model.ColumnValueProvider;
import ninja.javafx.smartcsv.validation.checker.*;
import ninja.javafx.smartcsv.validation.configuration.Constraints;
import ninja.javafx.smartcsv.validation.configuration.Field;
import ninja.javafx.smartcsv.validation.configuration.ValidationConfiguration;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import static ninja.javafx.smartcsv.validation.ValidationFormatHelper.dateFormat;
import static ninja.javafx.smartcsv.validation.configuration.StringFormat.*;
import static ninja.javafx.smartcsv.validation.configuration.Type.*;
/** /**
* This class checks all the validations defined in the * This class checks all the validations defined in the
* Config against a given value * Config against a given value
@@ -41,6 +51,7 @@ public class Validator {
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
private ValidationConfiguration validationConfig; private ValidationConfiguration validationConfig;
private ColumnValueProvider columnValueProvider;
private Map<String, Map<Validation.Type, Validation>> columnValidationMap = new HashMap<>(); private Map<String, Map<Validation.Type, Validation>> columnValidationMap = new HashMap<>();
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -52,8 +63,9 @@ public class Validator {
* *
* @param validationConfig * @param validationConfig
*/ */
public Validator(ValidationConfiguration validationConfig) { public Validator(ValidationConfiguration validationConfig, ColumnValueProvider columnValueProvider) {
this.validationConfig = validationConfig; this.validationConfig = validationConfig;
this.columnValueProvider = columnValueProvider;
initColumnValidations(); initColumnValidations();
} }
@@ -82,17 +94,12 @@ public class Validator {
public ValidationError isValid(Integer row, String column, String value) { public ValidationError isValid(Integer row, String column, String value) {
ValidationError result = null; ValidationError result = null;
if (hasConfig()) { if (hasConfig()) {
ValidationError error = ValidationError.withLineNumber(row); ValidationError error = ValidationError.withLineNumber(row).column(column);
Map<Validation.Type, Validation> validationMap = columnValidationMap.get(column); Map<Validation.Type, Validation> validationMap = columnValidationMap.get(column);
if (validationMap != null) { if (validationMap != null) {
for (Validation validation: validationMap.values()) { for (Validation validation: validationMap.values()) {
if (validation.canBeChecked(value)) {
if (validation.getType() == Validation.Type.NOT_EMPTY) {
validation.check(row, value, error); validation.check(row, value, error);
} else {
if (value != null && !value.isEmpty()) {
validation.check(row, value, error);
}
} }
} }
} }
@@ -135,68 +142,113 @@ public class Validator {
private void initColumnValidations() { private void initColumnValidations() {
if (hasConfig()) { if (hasConfig()) {
String[] columns = validationConfig.headerNames(); for (Field column : validationConfig.getFields()) {
for (String column : columns) {
initializeColumnWithRules(column); initializeColumnWithRules(column);
} }
} }
} }
private void initializeColumnWithRules(String column) { private void initializeColumnWithRules(String columnName) {
Boolean alphaNumeric = validationConfig.getAlphanumericRuleFor(column); if (hasConfig()) {
if (alphaNumeric != null && alphaNumeric) { for (Field column : validationConfig.getFields()) {
add(column, new AlphaNumericValidation()); if (column.getName().equals(columnName)) {
initializeColumnWithRules(column);
break;
}
}
} }
Boolean doubleRule = validationConfig.getDoubleRuleFor(column);
if (doubleRule != null && doubleRule) {
add(column, new DoubleValidation());
} }
Boolean integerRule = validationConfig.getIntegerRuleFor(column); private void initializeColumnWithRules(Field column) {
if (integerRule != null && integerRule) {
add(column, new IntegerValidation()); if (column.getType() != null) {
if (column.getType() == NUMBER) {
add(column.getName(), new DoubleValidation());
} }
Boolean notEmptyRule = validationConfig.getNotEmptyRuleFor(column); if (column.getType() == INTEGER) {
if (notEmptyRule != null && notEmptyRule) { add(column.getName(), new IntegerValidation());
add(column, new NotEmptyValidation());
} }
Boolean uniqueRule = validationConfig.getUniqueRuleFor(column); if (column.getType() == DATE) {
if (uniqueRule != null && uniqueRule) { String format = dateFormat(column.getFormat(), "YYYY-MM-DD");
add(column, new UniqueValidation()); add(column.getName(), new DateValidation(format));
} }
String dateRule = validationConfig.getDateRuleFor(column); if (column.getType() == DATETIME) {
if (dateRule != null && !dateRule.trim().isEmpty()) { String format = dateFormat(column.getFormat(), "YYYY-MM-DDThh:mm:ssZ");
add(column, new DateValidation(dateRule)); add(column.getName(), new DateValidation(format));
} }
Integer minLength = validationConfig.getMinLengthRuleFor(column); if (column.getType() == TIME) {
if (minLength != null) { String format = dateFormat(column.getFormat(), "hh:mm:ss");
add(column, new MinLengthValidation(minLength)); add(column.getName(), new DateValidation(format));
} }
Integer maxLength = validationConfig.getMaxLengthRuleFor(column); if (column.getType() == STRING && column.getFormat().equalsIgnoreCase(EMAIL.getExternalValue())) {
if (maxLength != null) { add(column.getName(), new EmailValidation());
add(column, new MaxLengthValidation(maxLength));
} }
String regexp = validationConfig.getRegexpRuleFor(column); if (column.getType() == STRING && column.getFormat().equalsIgnoreCase(URI.getExternalValue())) {
if (regexp != null && !regexp.trim().isEmpty()) { add(column.getName(), new UriValidation());
add(column, new RegExpValidation(regexp));
} }
String groovy = validationConfig.getGroovyRuleFor(column); if (column.getType() == STRING && column.getFormat().equalsIgnoreCase(UUID.getExternalValue())) {
add(column.getName(), new UuidValidation());
}
if (column.getType() == STRING && column.getFormat().equalsIgnoreCase(BINARY.getExternalValue())) {
add(column.getName(), new BinaryValidation());
}
if (column.getType() == STRING && column.getFormat() == null) {
columnValidationMap.get(column).remove(Validation.Type.STRING);
}
}
String groovy = column.getGroovy();
if (groovy != null && !groovy.trim().isEmpty()) { if (groovy != null && !groovy.trim().isEmpty()) {
add(column, new GroovyValidation(groovy)); add(column.getName(), new GroovyValidation(groovy));
} }
List<String> valueOfRule = validationConfig.getValueOfRuleFor(column);
Constraints constraints = column.getConstraints();
if (constraints != null) {
Boolean notEmptyRule = constraints.getRequired();
if (notEmptyRule != null && notEmptyRule) {
add(column.getName(), new NotEmptyValidation());
}
Boolean uniqueRule = constraints.getUnique();
if (uniqueRule != null && uniqueRule) {
add(column.getName(), new UniqueValidation(columnValueProvider, column.getName()));
}
Integer minLength = constraints.getMinLength();
if (minLength != null) {
add(column.getName(), new MinLengthValidation(minLength));
}
Integer maxLength = constraints.getMaxLength();
if (maxLength != null) {
add(column.getName(), new MaxLengthValidation(maxLength));
}
String regexp = constraints.getPattern();
if (regexp != null && !regexp.trim().isEmpty()) {
add(column.getName(), new RegExpValidation(regexp));
}
List<String> valueOfRule = constraints.getEnumeration();
if (valueOfRule != null && !valueOfRule.isEmpty()) { if (valueOfRule != null && !valueOfRule.isEmpty()) {
add(column, new ValueOfValidation(valueOfRule)); add(column.getName(), new ValueOfValidation(valueOfRule));
} }
} }
}
public ValidationError isHeaderValid(String[] headerNames) { public ValidationError isHeaderValid(String[] headerNames) {
@@ -228,4 +280,6 @@ public class Validator {
} }
return result; return result;
} }
} }

View File

@@ -2,7 +2,7 @@
The MIT License (MIT) The MIT License (MIT)
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
Copyright (c) 2015 javafx.ninja <info@javafx.ninja> Copyright (c) 2015-2016 javafx.ninja <info@javafx.ninja>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
@@ -23,32 +23,28 @@
THE SOFTWARE. THE SOFTWARE.
*/ */
package ninja.javafx.smartcsv.validation; package ninja.javafx.smartcsv.validation.checker;
import java.util.HashMap; import ninja.javafx.smartcsv.validation.ValidationError;
import java.util.Base64;
/** /**
* Checks if the value is unique in the column * checks if the value is a base64 encoded string representing binary data
*/ */
public class UniqueValidation implements Validation { public class BinaryValidation extends EmptyValueIsValid {
private HashMap<String, Integer> columnValueMap = new HashMap<>();
@Override @Override
public void check(int row, String value, ValidationError error) { public void check(int row, String value, ValidationError error) {
Integer valueInLineNumber = columnValueMap.get(value); try {
if (valueInLineNumber != null) { Base64.getDecoder().decode(value);
if (!valueInLineNumber.equals(row)) { } catch (IllegalArgumentException e) {
valueInLineNumber += 1; // show not 0 based line numbers to user error.add("validation.message.binary");
error.add("validation.message.uniqueness", value, valueInLineNumber.toString());
}
} else {
columnValueMap.put(value, row);
} }
} }
@Override @Override
public Type getType() { public Type getType() {
return Type.UNIQUE; return Type.STRING;
} }
} }

View File

@@ -2,7 +2,7 @@
The MIT License (MIT) The MIT License (MIT)
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
Copyright (c) 2015 javafx.ninja <info@javafx.ninja> Copyright (c) 2015-2016 javafx.ninja <info@javafx.ninja>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
@@ -23,14 +23,16 @@
THE SOFTWARE. THE SOFTWARE.
*/ */
package ninja.javafx.smartcsv.validation; package ninja.javafx.smartcsv.validation.checker;
import ninja.javafx.smartcsv.validation.ValidationError;
import static org.apache.commons.validator.GenericValidator.isDate; import static org.apache.commons.validator.GenericValidator.isDate;
/** /**
* Checks if the date has the right format * Checks if the date has the right format
*/ */
public class DateValidation implements Validation { public class DateValidation extends EmptyValueIsValid {
private String dateformat; private String dateformat;

View File

@@ -2,7 +2,7 @@
The MIT License (MIT) The MIT License (MIT)
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
Copyright (c) 2015 javafx.ninja <info@javafx.ninja> Copyright (c) 2015-2016 javafx.ninja <info@javafx.ninja>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
@@ -23,14 +23,16 @@
THE SOFTWARE. THE SOFTWARE.
*/ */
package ninja.javafx.smartcsv.validation; package ninja.javafx.smartcsv.validation.checker;
import ninja.javafx.smartcsv.validation.ValidationError;
import static org.apache.commons.validator.GenericValidator.isDouble; import static org.apache.commons.validator.GenericValidator.isDouble;
/** /**
* Checks if the value is a double * Checks if the value is a double
*/ */
public class DoubleValidation implements Validation { public class DoubleValidation extends EmptyValueIsValid {
@Override @Override
public void check(int row, String value, ValidationError error) { public void check(int row, String value, ValidationError error) {

View File

@@ -2,7 +2,7 @@
The MIT License (MIT) The MIT License (MIT)
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
Copyright (c) 2015 javafx.ninja <info@javafx.ninja> Copyright (c) 2015-2016 javafx.ninja <info@javafx.ninja>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
@@ -23,24 +23,25 @@
THE SOFTWARE. THE SOFTWARE.
*/ */
package ninja.javafx.smartcsv.validation.checker;
package ninja.javafx.smartcsv.validation; import ninja.javafx.smartcsv.validation.ValidationError;
import org.apache.commons.validator.routines.EmailValidator;
import com.google.gson.annotations.SerializedName;
/** /**
* header configuration for the validation * checks if the value is a valid email address
*/ */
public class HeaderConfiguration { public class EmailValidation extends EmptyValueIsValid {
@SerializedName("list") @Override
private String[] names ; public void check(int row, String value, ValidationError error) {
if (!EmailValidator.getInstance().isValid(value)) {
public String[] getNames() { error.add("validation.message.email");
return names; }
} }
public void setNames(String[] names) { @Override
this.names = names; public Type getType() {
return Type.STRING;
} }
} }

View File

@@ -0,0 +1,12 @@
package ninja.javafx.smartcsv.validation.checker;
/**
* validations based on this are not validated when the value is null or empty
*/
public abstract class EmptyValueIsValid implements Validation {
@Override
public boolean canBeChecked(String value) {
return value != null && !value.isEmpty();
}
}

View File

@@ -2,7 +2,7 @@
The MIT License (MIT) The MIT License (MIT)
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
Copyright (c) 2015 javafx.ninja <info@javafx.ninja> Copyright (c) 2015-2016 javafx.ninja <info@javafx.ninja>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
@@ -23,17 +23,18 @@
THE SOFTWARE. THE SOFTWARE.
*/ */
package ninja.javafx.smartcsv.validation; package ninja.javafx.smartcsv.validation.checker;
import groovy.lang.Binding; import groovy.lang.Binding;
import groovy.lang.GroovyShell; import groovy.lang.GroovyShell;
import groovy.lang.Script; import groovy.lang.Script;
import ninja.javafx.smartcsv.validation.ValidationError;
import org.codehaus.groovy.control.CompilationFailedException; import org.codehaus.groovy.control.CompilationFailedException;
/** /**
* Executes the given groovy as check * Executes the given groovy as check
*/ */
public class GroovyValidation implements Validation { public class GroovyValidation extends EmptyValueIsValid {
private String groovyScript; private String groovyScript;
private GroovyShell shell = new GroovyShell(); private GroovyShell shell = new GroovyShell();

View File

@@ -2,7 +2,7 @@
The MIT License (MIT) The MIT License (MIT)
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
Copyright (c) 2015 javafx.ninja <info@javafx.ninja> Copyright (c) 2015-2016 javafx.ninja <info@javafx.ninja>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
@@ -23,14 +23,16 @@
THE SOFTWARE. THE SOFTWARE.
*/ */
package ninja.javafx.smartcsv.validation; package ninja.javafx.smartcsv.validation.checker;
import ninja.javafx.smartcsv.validation.ValidationError;
import static org.apache.commons.validator.GenericValidator.isInt; import static org.apache.commons.validator.GenericValidator.isInt;
/** /**
* Checks if the value is an integer * Checks if the value is an integer
*/ */
public class IntegerValidation implements Validation { public class IntegerValidation extends EmptyValueIsValid {
@Override @Override
public void check(int row, String value, ValidationError error) { public void check(int row, String value, ValidationError error) {

View File

@@ -2,7 +2,7 @@
The MIT License (MIT) The MIT License (MIT)
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
Copyright (c) 2015 javafx.ninja <info@javafx.ninja> Copyright (c) 2015-2016 javafx.ninja <info@javafx.ninja>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
@@ -23,14 +23,16 @@
THE SOFTWARE. THE SOFTWARE.
*/ */
package ninja.javafx.smartcsv.validation; package ninja.javafx.smartcsv.validation.checker;
import ninja.javafx.smartcsv.validation.ValidationError;
import static org.apache.commons.validator.GenericValidator.maxLength; import static org.apache.commons.validator.GenericValidator.maxLength;
/** /**
* Checks if the value is shorter or exactly as long as the given max length * Checks if the value is shorter or exactly as long as the given max length
*/ */
public class MaxLengthValidation implements Validation { public class MaxLengthValidation extends EmptyValueIsValid {
private int maxLength; private int maxLength;

View File

@@ -2,7 +2,7 @@
The MIT License (MIT) The MIT License (MIT)
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
Copyright (c) 2015 javafx.ninja <info@javafx.ninja> Copyright (c) 2015-2016 javafx.ninja <info@javafx.ninja>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
@@ -23,14 +23,16 @@
THE SOFTWARE. THE SOFTWARE.
*/ */
package ninja.javafx.smartcsv.validation; package ninja.javafx.smartcsv.validation.checker;
import ninja.javafx.smartcsv.validation.ValidationError;
import static org.apache.commons.validator.GenericValidator.minLength; import static org.apache.commons.validator.GenericValidator.minLength;
/** /**
* Checks if the value is at minimum long as the given min length * Checks if the value is at minimum long as the given min length
*/ */
public class MinLengthValidation implements Validation { public class MinLengthValidation extends EmptyValueIsValid {
private int minLength; private int minLength;

View File

@@ -2,7 +2,7 @@
The MIT License (MIT) The MIT License (MIT)
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
Copyright (c) 2015 javafx.ninja <info@javafx.ninja> Copyright (c) 2015-2016 javafx.ninja <info@javafx.ninja>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
@@ -23,7 +23,9 @@
THE SOFTWARE. THE SOFTWARE.
*/ */
package ninja.javafx.smartcsv.validation; package ninja.javafx.smartcsv.validation.checker;
import ninja.javafx.smartcsv.validation.ValidationError;
import static org.apache.commons.validator.GenericValidator.isBlankOrNull; import static org.apache.commons.validator.GenericValidator.isBlankOrNull;
@@ -43,4 +45,9 @@ public class NotEmptyValidation implements Validation {
public Type getType() { public Type getType() {
return Type.NOT_EMPTY; return Type.NOT_EMPTY;
} }
@Override
public boolean canBeChecked(String value) {
return true;
}
} }

View File

@@ -2,7 +2,7 @@
The MIT License (MIT) The MIT License (MIT)
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
Copyright (c) 2015 javafx.ninja <info@javafx.ninja> Copyright (c) 2015-2016 javafx.ninja <info@javafx.ninja>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
@@ -23,14 +23,16 @@
THE SOFTWARE. THE SOFTWARE.
*/ */
package ninja.javafx.smartcsv.validation; package ninja.javafx.smartcsv.validation.checker;
import ninja.javafx.smartcsv.validation.ValidationError;
import static org.apache.commons.validator.GenericValidator.matchRegexp; import static org.apache.commons.validator.GenericValidator.matchRegexp;
/** /**
* Checks the value against the given reg exp * Checks the value against the given reg exp
*/ */
public class RegExpValidation implements Validation { public class RegExpValidation extends EmptyValueIsValid {
private String regexp; private String regexp;

View File

@@ -0,0 +1,79 @@
/*
The MIT License (MIT)
-----------------------------------------------------------------------------
Copyright (c) 2015-2016 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.checker;
import ninja.javafx.smartcsv.fx.table.model.ColumnValueProvider;
import ninja.javafx.smartcsv.validation.ValidationError;
import java.util.ArrayList;
import java.util.List;
import static java.util.Collections.sort;
import static java.util.stream.Collectors.joining;
/**
* Checks if the value is unique in the column
*/
public class UniqueValidation extends EmptyValueIsValid {
private ColumnValueProvider columnValueProvider;
private String column;
public UniqueValidation(ColumnValueProvider columnValueProvider, String column) {
this.columnValueProvider = columnValueProvider;
this.column = column;
}
@Override
public void check(int row, String value, ValidationError error) {
List<Integer> lineNumbers = new ArrayList<>();
int numberOfRows = columnValueProvider.getNumberOfRows();
for (int currentRowOfIteration = 0; currentRowOfIteration < numberOfRows; currentRowOfIteration++) {
String storedValue = columnValueProvider.getValue(currentRowOfIteration, column);
if (value.equals(storedValue) && currentRowOfIteration != row) {
lineNumbers.add(currentRowOfIteration + 1); // show not 0 based line numbers to user
}
}
if (!lineNumbers.isEmpty()) {
if (lineNumbers.size() > 1) {
sort(lineNumbers);
error.add("validation.message.uniqueness.multiple", value, lineNumbers.stream().map(Object::toString).collect(joining(", ")));
} else {
error.add("validation.message.uniqueness.single", value, lineNumbers.get(0).toString());
}
}
}
@Override
public Type getType() {
return Type.UNIQUE;
}
}

View File

@@ -0,0 +1,51 @@
/*
The MIT License (MIT)
-----------------------------------------------------------------------------
Copyright (c) 2015-2016 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.checker;
import ninja.javafx.smartcsv.validation.ValidationError;
import java.net.URI;
import java.net.URISyntaxException;
/**
* checks if the value is a valid uri address
*/
public class UriValidation extends EmptyValueIsValid {
@Override
public void check(int row, String value, ValidationError error) {
try {
new URI(value);
} catch (URISyntaxException e) {
error.add("validation.message.uri");
}
}
@Override
public Type getType() {
return Type.STRING;
}
}

View File

@@ -2,7 +2,7 @@
The MIT License (MIT) The MIT License (MIT)
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
Copyright (c) 2015 javafx.ninja <info@javafx.ninja> Copyright (c) 2015-2016 javafx.ninja <info@javafx.ninja>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
@@ -23,23 +23,28 @@
THE SOFTWARE. THE SOFTWARE.
*/ */
package ninja.javafx.smartcsv.validation; package ninja.javafx.smartcsv.validation.checker;
import static org.apache.commons.validator.GenericValidator.matchRegexp; import ninja.javafx.smartcsv.validation.ValidationError;
import java.util.UUID;
/** /**
* Checks if the value is alpha numeric * checks if the value is a valid uuid
*/ */
public class AlphaNumericValidation implements Validation { public class UuidValidation extends EmptyValueIsValid {
@Override @Override
public void check(int row, String value, ValidationError error) { public void check(int row, String value, ValidationError error) {
if (!matchRegexp(value, "[0-9a-zA-Z]*")) { try {
error.add("validation.message.alphanumeric"); UUID.fromString(value);
} catch (IllegalArgumentException e) {
error.add("validation.message.uuid");
} }
} }
@Override @Override
public Type getType() { public Type getType() {
return Type.ALPHANUMERIC; return Type.STRING;
} }
} }

View File

@@ -2,7 +2,7 @@
The MIT License (MIT) The MIT License (MIT)
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
Copyright (c) 2015 javafx.ninja <info@javafx.ninja> Copyright (c) 2015-2016 javafx.ninja <info@javafx.ninja>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
@@ -23,14 +23,17 @@
THE SOFTWARE. THE SOFTWARE.
*/ */
package ninja.javafx.smartcsv.validation; package ninja.javafx.smartcsv.validation.checker;
import ninja.javafx.smartcsv.validation.ValidationError;
/** /**
* Interface for all validations * Interface for all validations
*/ */
public interface Validation { public interface Validation {
enum Type { NOT_EMPTY, UNIQUE, DOUBLE, INTEGER, MIN_LENGTH, MAX_LENGTH, DATE, ALPHANUMERIC, REGEXP, VALUE_OF, GROOVY } enum Type { NOT_EMPTY, UNIQUE, DOUBLE, INTEGER, MIN_LENGTH, MAX_LENGTH, DATE, REGEXP, VALUE_OF, STRING, GROOVY }
void check(int row, String value, ValidationError error); void check(int row, String value, ValidationError error);
Type getType(); Type getType();
boolean canBeChecked(String value);
} }

View File

@@ -2,7 +2,7 @@
The MIT License (MIT) The MIT License (MIT)
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
Copyright (c) 2015 javafx.ninja <info@javafx.ninja> Copyright (c) 2015-2016 javafx.ninja <info@javafx.ninja>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
@@ -23,7 +23,9 @@
THE SOFTWARE. THE SOFTWARE.
*/ */
package ninja.javafx.smartcsv.validation; package ninja.javafx.smartcsv.validation.checker;
import ninja.javafx.smartcsv.validation.ValidationError;
import java.util.List; import java.util.List;
@@ -32,7 +34,7 @@ import static java.util.stream.Collectors.joining;
/** /**
* Checks if the value is part of a list of values * Checks if the value is part of a list of values
*/ */
public class ValueOfValidation implements Validation { public class ValueOfValidation extends EmptyValueIsValid {
private List<String> values; private List<String> values;

View File

@@ -0,0 +1,96 @@
/*
The MIT License (MIT)
-----------------------------------------------------------------------------
Copyright (c) 2015-2016 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.configuration;
import com.google.gson.annotations.SerializedName;
import java.util.List;
/**
* contraints defined in JSON Table Schema
* @see <a href="http://specs.frictionlessdata.io/json-table-schema/">JSON Table Schema</a>
*/
public class Constraints {
private Boolean required;
private Boolean unique;
private Integer minLength;
private Integer maxLength;
private String pattern;
@SerializedName("enum")
private List<String> enumeration;
public Boolean getRequired() {
return required;
}
public void setRequired(Boolean required) {
this.required = required;
}
public Boolean getUnique() {
return unique;
}
public void setUnique(Boolean unique) {
this.unique = unique;
}
public Integer getMinLength() {
return minLength;
}
public void setMinLength(Integer minLength) {
this.minLength = minLength;
}
public Integer getMaxLength() {
return maxLength;
}
public void setMaxLength(Integer maxLength) {
this.maxLength = maxLength;
}
public String getPattern() {
return pattern;
}
public void setPattern(String pattern) {
this.pattern = pattern;
}
public List<String> getEnumeration() {
return enumeration;
}
public void setEnumeration(List<String> enumeration) {
this.enumeration = enumeration;
}
}

View File

@@ -0,0 +1,109 @@
/*
The MIT License (MIT)
-----------------------------------------------------------------------------
Copyright (c) 2015-2016 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.configuration;
/**
* this class represents a field in the configuration
* @see <a href="http://specs.frictionlessdata.io/json-table-schema/">JSON Table Schema</a>
*/
public class Field {
private String name;
private String title;
private Type type;
private String description;
private String format;
private Object missingValue;
private Constraints constraints;
private String groovy;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public Type getType() {
return type;
}
public void setType(Type type) {
this.type = type;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getFormat() {
return format;
}
public void setFormat(String format) {
this.format = format;
}
public Object getMissingValue() {
return missingValue;
}
public void setMissingValue(Object missingValue) {
this.missingValue = missingValue;
}
public Constraints getConstraints() {
return constraints;
}
public void setConstraints(Constraints constraints) {
this.constraints = constraints;
}
public String getGroovy() {
return groovy;
}
public void setGroovy(String groovy) {
this.groovy = groovy;
}
}

View File

@@ -0,0 +1,60 @@
/*
The MIT License (MIT)
-----------------------------------------------------------------------------
Copyright (c) 2015-2016 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.configuration;
/**
* Enumeration for format values for type string in JSON Table Schema
* @see <a href="http://specs.frictionlessdata.io/json-table-schema/">JSON Table Schema</a>
*/
public enum StringFormat {
DEFAULT(null),
EMAIL("email"),
URI("uri"),
BINARY("binary"),
UUID("uuid");
private String externalValue;
StringFormat(String externalValue) {
this.externalValue = externalValue;
}
public String getExternalValue() {
return externalValue;
}
public static StringFormat fromExternalValue(String externalValue) {
if (externalValue != null) {
for (StringFormat value : StringFormat.values()) {
if (externalValue.equals(value.getExternalValue())) {
return value;
}
}
}
return DEFAULT;
}
}

View File

@@ -0,0 +1,48 @@
/*
The MIT License (MIT)
-----------------------------------------------------------------------------
Copyright (c) 2015-2016 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.configuration;
import com.google.gson.annotations.SerializedName;
/**
* Types of JSON Table Schema
* @see <a href="http://specs.frictionlessdata.io/json-table-schema/">JSON Table Schema</a>
*/
public enum Type {
@SerializedName("string")STRING,
@SerializedName("integer")INTEGER,
@SerializedName("number")NUMBER,
@SerializedName("date")DATE,
@SerializedName("datetime")DATETIME,
@SerializedName("time")TIME
// TODO: currently not supported
// @SerializedName("object") OBJECT,
// @SerializedName("array") ARRAY,
// @SerializedName("duration") DURATION,
// @SerializedName("geopoint") GEOPOINT,
// @SerializedName("geojson") GEOJSON
}

View File

@@ -0,0 +1,81 @@
/*
The MIT License (MIT)
-----------------------------------------------------------------------------
Copyright (c) 2015-2016 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.configuration;
import com.google.gson.annotations.SerializedName;
import java.util.ArrayList;
import java.util.List;
/**
* Configuration based on JSON Table Schema
* @see <a href="http://specs.frictionlessdata.io/json-table-schema/">JSON Table Schema</a>
*/
public class ValidationConfiguration {
@SerializedName("fields")
private Field[] fields;
public Field[] getFields() {
return fields;
}
public void setFields(Field[] fields) {
this.fields = fields;
}
public Field getFieldConfiguration(String column) {
for (Field field : fields) {
if (field.getName().equals(column)) {
return field;
}
}
return null;
}
public String[] headerNames() {
if (fields != null) {
List<String> headerNames = new ArrayList<>();
for (Field field : fields) {
headerNames.add(field.getName());
}
return headerNames.toArray(new String[headerNames.size()]);
}
return null;
}
public void setHeaderNames(String[] header) {
fields = new Field[header.length];
int i = 0;
for (String headerName: header) {
fields[i] = new Field();
fields[i].setName(headerName);
i++;
}
}
}

View File

@@ -91,7 +91,7 @@
<Font size="18.0" /> <Font size="18.0" />
</font> </font>
</Label> </Label>
<TextArea editable="false" prefHeight="200.0" prefWidth="200.0" text="Copyright (c) 2015 Andreas Billmann &lt;andreas.billmann@javafx.ninja&gt;&#10;&#10;Permission is hereby granted, free of charge, to any person obtaining a copy&#10;of this software and associated documentation files (the &quot;Software&quot;), to deal&#10;in the Software without restriction, including without limitation the rights&#10;to use, copy, modify, merge, publish, distribute, sublicense, and/or sell&#10;copies of the Software, and to permit persons to whom the Software is&#10;furnished to do so, subject to the following conditions:&#10;&#10;The above copyright notice and this permission notice shall be included in&#10;all copies or substantial portions of the Software.&#10;&#10;&#10;&#10;THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR&#10;IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,&#10;FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE&#10;AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER&#10;LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,&#10;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN&#10;THE SOFTWARE." wrapText="true" /> <TextArea editable="false" prefHeight="200.0" prefWidth="200.0" text="Copyright (c) 2015-2016 Andreas Billmann &lt;andreas.billmann@javafx.ninja&gt;&#10;&#10;Permission is hereby granted, free of charge, to any person obtaining a copy&#10;of this software and associated documentation files (the &quot;Software&quot;), to deal&#10;in the Software without restriction, including without limitation the rights&#10;to use, copy, modify, merge, publish, distribute, sublicense, and/or sell&#10;copies of the Software, and to permit persons to whom the Software is&#10;furnished to do so, subject to the following conditions:&#10;&#10;The above copyright notice and this permission notice shall be included in&#10;all copies or substantial portions of the Software.&#10;&#10;&#10;&#10;THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR&#10;IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,&#10;FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE&#10;AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER&#10;LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,&#10;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN&#10;THE SOFTWARE." wrapText="true" />
</children> </children>
<opaqueInsets> <opaqueInsets>
<Insets /> <Insets />

View File

@@ -1,5 +1,5 @@
application.name = SmartCSV.fx application.name = SmartCSV.fx
application.version = 0.6 application.version = 0.8
# fxml views # fxml views
fxml.smartcvs.view = /ninja/javafx/smartcsv/fx/smartcsv.fxml fxml.smartcvs.view = /ninja/javafx/smartcsv/fx/smartcsv.fxml

View File

@@ -1,16 +1,16 @@
.list-view { .table-view .list-view {
-fx-background-color: -fx-background; -fx-background-color: -fx-background;
-fx-padding: 1; -fx-padding: 1;
} }
.list-cell { .table-view .list-cell {
-fx-padding: 1.0em 1.0em 1.0em 1.0em; -fx-padding: 1.0em 1.0em 1.0em 1.0em;
} }
.list-cell:odd { .table-view .list-cell:odd {
-fx-background: -fx-control-inner-background-alt; -fx-background: -fx-control-inner-background-alt;
} }
.list-cell:even { .table-view .list-cell:even {
-fx-background: -fx-control-inner-background; -fx-background: -fx-control-inner-background;
} }
@@ -82,9 +82,14 @@
.goto-icon { .goto-icon {
-glyph-name: "SUBDIRECTORY_ARROW_RIGHT"; -glyph-name: "SUBDIRECTORY_ARROW_RIGHT";
-glyph-size: 16px; -glyph-size: 16px;
} }
.export-icon {
-glyph-name: "BUG";
-glyph-size: 16px;
}
/* toolbar customization based on http://fxexperience.com/2012/02/customized-segmented-toolbar-buttons/ */ /* toolbar customization based on http://fxexperience.com/2012/02/customized-segmented-toolbar-buttons/ */
#background { #background {
@@ -149,6 +154,11 @@
-fx-fill: white; -fx-fill: white;
} }
.tool-bar .export-icon {
-glyph-size: 16px;
-fx-fill: white;
}
.segmented-button-bar .button { .segmented-button-bar .button {
-fx-background-color: -fx-background-color:
-darkest-black, -darkest-black,

View File

@@ -78,6 +78,11 @@
<MaterialDesignIconView styleClass="preferences-icon" /> <MaterialDesignIconView styleClass="preferences-icon" />
</graphic> </graphic>
</MenuItem> </MenuItem>
<MenuItem fx:id="exportMenuItem" disable="true" mnemonicParsing="false" onAction="#export" text="%menu.export">
<graphic>
<MaterialDesignIconView styleClass="export-icon" />
</graphic>
</MenuItem>
<SeparatorMenuItem mnemonicParsing="false" /> <SeparatorMenuItem mnemonicParsing="false" />
<MenuItem mnemonicParsing="false" onAction="#close" text="%menu.close"> <MenuItem mnemonicParsing="false" onAction="#close" text="%menu.close">
<graphic> <graphic>
@@ -229,6 +234,14 @@
<MaterialDesignIconView styleClass="preferences-icon" /> <MaterialDesignIconView styleClass="preferences-icon" />
</graphic> </graphic>
</Button> </Button>
<Button fx:id="exportButton" disable="true" mnemonicParsing="false" onAction="#export">
<tooltip>
<Tooltip text="%menu.export" />
</tooltip>
<graphic>
<MaterialDesignIconView styleClass="export-icon" />
</graphic>
</Button>
<Button mnemonicParsing="false" onAction="#close" styleClass="last"> <Button mnemonicParsing="false" onAction="#close" styleClass="last">
<tooltip> <tooltip>
<Tooltip text="%menu.close" /> <Tooltip text="%menu.close" />

View File

@@ -14,6 +14,7 @@ menu.preferences = Preferences
menu.delete.row = Delete row menu.delete.row = Delete row
menu.add.row = Add row menu.add.row = Add row
menu.goto.line = Goto line menu.goto.line = Goto line
menu.export = Export error log
title.validation.errors = Validation Errors: title.validation.errors = Validation Errors:
@@ -45,6 +46,7 @@ preferences.quoteMode = Quote mode:
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.double = should be a double validation.message.double = should be a double
validation.message.email = should be an email address
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.exception = groovy script '{0}' throws exception: {1}
validation.message.groovy.return.null = groovy script '{0}' returns null validation.message.groovy.return.null = groovy script '{0}' returns null
@@ -52,29 +54,46 @@ validation.message.min.length = has not min length of {0}
validation.message.max.length = has not max 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.date.format = is not a date of format {0}
validation.message.regexp = does not match {0} validation.message.regexp = does not match {0}
validation.message.uniqueness = value {0} is not unique (found in line {1}) validation.message.uniqueness.multiple = value {0} is not unique (found in rows {1})
validation.message.uniqueness.single = value {0} is not unique (found in row {1})
validation.message.uri = should be an uri
validation.message.uuid = should be an uuid
validation.message.binary = should be a base64 encoded string representing binary data
validation.message.header.length = number of headers is not correct! there are {0} but there should be {1} 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 "{2}" validation.message.header.match = header number {0} does not match "{1}" should be "{2}"
validation.message.value.of = Value {0} is not part of this list {1} validation.message.value.of = Value {0} is not part of this list {1}
validation.rule.label.not_empty = not empty: validation.rule.label.not_empty = not empty
validation.rule.label.integer = integer: validation.rule.label.integer = integer
validation.rule.label.double = double: validation.rule.label.double = double
validation.rule.label.minlength = minimum length: validation.rule.label.minlength = minimum length:
validation.rule.label.maxlength = maximum length: validation.rule.label.maxlength = maximum length:
validation.rule.label.dateformat = date format: validation.rule.label.dateformat = date format:
validation.rule.label.alphanumeric = alphanumeric: validation.rule.label.alphanumeric = alphanumeric
validation.rule.label.regexp = regular expression: validation.rule.label.regexp = regular expression:
validation.rule.label.value_of = value in list: validation.rule.label.value_of = value in list:
validation.rule.label.groovy = groovy: validation.rule.label.groovy = groovy:
validation.rules.active = active validation.rules.active = active
validation.rules.name = rule validation.rules.name = rule
validation.rules.value = value validation.rules.value = value
validation.rule.label.unique = Unique in column: validation.rule.label.unique = Unique in column
validation.rule.format = Format:
validation.rule.type = Type:
dialog.validation.rules.title = Validation rules dialog.validation.rules.title = Validation rules
dialog.validation.rules.header = Validation rules of column "{0}" dialog.validation.rules.header = Validation rules of column "{0}"
context.menu.edit.column.rules = Edit rules context.menu.edit.column.rules = Edit rules
lineNumber = Selected line: lineNumber = Selected line:
log.header.message = {0} has {1} errors
log.message = row {0} column {1} : {2}
column = column
format.type.DEFAULT = default
format.type.EMAIL = email
format.type.URI = uri
format.type.BINARY = binary
format.type.UUID = uuid

View File

@@ -23,6 +23,7 @@ menu.preferences = Einstellungen
menu.delete.row = Zeile l\u00f6schen menu.delete.row = Zeile l\u00f6schen
menu.add.row = Zeile hinzuf\u00fcgen menu.add.row = Zeile hinzuf\u00fcgen
menu.goto.line = Springe zur Zeile menu.goto.line = Springe zur Zeile
menu.export = Export Fehlerdatei
title.validation.errors = Fehler in der Datei: title.validation.errors = Fehler in der Datei:
@@ -54,6 +55,7 @@ preferences.quoteMode = Einfassungsmodus:
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.double = Muss eine Gleitkommazahl sein validation.message.double = Muss eine Gleitkommazahl sein
validation.message.email = Muss eine Email-Adresse 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.exception = groovy script '{0}' wirft folgenden Fehler: {1}
validation.message.groovy.return.null = groovy script '{0}' meldet "null" validation.message.groovy.return.null = groovy script '{0}' meldet "null"
@@ -61,15 +63,19 @@ 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.max.length = Hat nicht die maximale L\u00e4nge von {0}
validation.message.date.format = Das Datumsformat entspricht nicht {0} validation.message.date.format = Das Datumsformat entspricht nicht {0}
validation.message.regexp = entspricht nicht dem regul\u00e4ren Ausdruck {0} validation.message.regexp = entspricht nicht dem regul\u00e4ren Ausdruck {0}
validation.message.uniqueness = Wert {0} ist nicht einmalig (gefunden in Zeile {1}) validation.message.uniqueness.multiple = Wert {0} ist nicht einmalig (gefunden in den Zeilen {1})
validation.message.uniqueness.single = Wert {0} ist nicht einmalig (gefunden in Zeile {1})
validation.message.uri = Muss eine URI sein
validation.message.uuid = Muss eine UUID sein
validation.message.binary = Muss ein base64 encoded Text sein, der bin\u00e4re Daten enth\u00e4lt
validation.message.header.length = Anzahl der \u00dcberschriften ist nicht korrekt! Es sind {0} aber es sollten {1} sein 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 validation.message.header.match = \u00dcberschrift in Spalte {0} stimmt nicht. "{1}" sollte "{3}" sein
validation.message.value.of = Der Wert {0} ist nicht in der Liste {1} enthalten validation.message.value.of = Der Wert {0} ist nicht in der Liste {1} enthalten
validation.rule.label.not_empty = Nicht leer: validation.rule.label.not_empty = Nicht leer
validation.rule.label.integer = Zahl: validation.rule.label.integer = Zahl
validation.rule.label.double = Gleitkommazahl: validation.rule.label.double = Gleitkommazahl
validation.rule.label.minlength = Minimale L\u00e4nge: validation.rule.label.minlength = Minimale L\u00e4nge:
validation.rule.label.maxlength = Maximale L\u00e4nge: validation.rule.label.maxlength = Maximale L\u00e4nge:
validation.rule.label.dateformat = Datumsformat: validation.rule.label.dateformat = Datumsformat:
@@ -80,7 +86,9 @@ validation.rule.label.groovy = groovy:
validation.rules.active = Aktiv validation.rules.active = Aktiv
validation.rules.name = Regel validation.rules.name = Regel
validation.rules.value = Wert validation.rules.value = Wert
validation.rule.label.unique = Einmalig in Spalte: validation.rule.label.unique = Einmalig in Spalte
validation.rule.format = Format:
validation.rule.type = Typ:
dialog.validation.rules.title = Pr\u00fcfregeln dialog.validation.rules.title = Pr\u00fcfregeln
dialog.validation.rules.header = Pr\u00fcfregeln f\u00fcr die Spalte "{0}" dialog.validation.rules.header = Pr\u00fcfregeln f\u00fcr die Spalte "{0}"
@@ -88,3 +96,14 @@ dialog.validation.rules.header = Pr\u00fcfregeln f\u00fcr die Spalte "{0}"
context.menu.edit.column.rules = Pr\u00fcfregeln bearbeiten context.menu.edit.column.rules = Pr\u00fcfregeln bearbeiten
lineNumber = Ausgew\u00e4hlte Zeile: lineNumber = Ausgew\u00e4hlte Zeile:
log.header.message = {0} hat {1} Fehler
log.message = Zeile {0} Spalte {1} : {2}
column = Spalte
format.type.DEFAULT = Standard
format.type.EMAIL = Email
format.type.URI = URI
format.type.BINARY = Bin\u00e4r
format.type.UUID = UUID

View File

@@ -1,68 +1,63 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import org.fxmisc.richtext.CodeArea?>
<?import java.net.URL?> <?import java.net.URL?>
<GridPane hgap="10.0" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefWidth="600.0" vgap="10.0" xmlns="http://javafx.com/javafx/8.0.101" xmlns:fx="http://javafx.com/fxml/1"> <?import javafx.geometry.Insets?>
<?import javafx.scene.control.CheckBox?>
<?import javafx.scene.control.ComboBox?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.Separator?>
<?import javafx.scene.control.Spinner?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.RowConstraints?>
<?import org.fxmisc.richtext.CodeArea?>
<GridPane hgap="20.0" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefWidth="800.0" vgap="6.0" xmlns="http://javafx.com/javafx/8.0.76-ea" xmlns:fx="http://javafx.com/fxml/1">
<columnConstraints> <columnConstraints>
<ColumnConstraints halignment="CENTER" hgrow="NEVER" maxWidth="50.0" prefWidth="50.0" /> <ColumnConstraints halignment="LEFT" hgrow="NEVER" />
<ColumnConstraints hgrow="NEVER" /> <ColumnConstraints halignment="LEFT" hgrow="ALWAYS" />
<ColumnConstraints hgrow="ALWAYS" /> <ColumnConstraints halignment="LEFT" hgrow="NEVER" />
<ColumnConstraints halignment="LEFT" hgrow="ALWAYS" />
</columnConstraints> </columnConstraints>
<rowConstraints> <rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" /> <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" /> <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" /> <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" valignment="CENTER" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" valignment="CENTER" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" valignment="CENTER" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" /> <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" /> <RowConstraints minHeight="10.0" valignment="TOP" vgrow="ALWAYS" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" /> <RowConstraints />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints> </rowConstraints>
<children> <children>
<Label text="%validation.rule.label.not_empty" GridPane.columnIndex="1" GridPane.rowIndex="1" /> <Label text="%validation.rule.type" GridPane.columnSpan="2" GridPane.halignment="LEFT" GridPane.hgrow="ALWAYS" />
<Label text="%validation.rule.label.integer" GridPane.columnIndex="1" GridPane.rowIndex="2" /> <Label text="%validation.rule.format" GridPane.columnSpan="2" GridPane.halignment="LEFT" GridPane.hgrow="ALWAYS" GridPane.rowIndex="1" />
<Label text="%validation.rule.label.double" GridPane.columnIndex="1" GridPane.rowIndex="3" /> <ComboBox fx:id="typeComboBox" maxWidth="1.7976931348623157E308" GridPane.columnIndex="1" GridPane.columnSpan="3" GridPane.halignment="LEFT" GridPane.hgrow="ALWAYS" />
<Label text="%validation.rule.label.minlength" GridPane.columnIndex="1" GridPane.rowIndex="6" /> <ComboBox fx:id="formatComboBox" prefWidth="150.0" GridPane.columnIndex="1" GridPane.columnSpan="3" GridPane.rowIndex="1" visible="false" />
<Label text="%validation.rule.label.maxlength" GridPane.columnIndex="1" GridPane.rowIndex="7" /> <TextField fx:id="formatTextField" GridPane.columnIndex="1" GridPane.columnSpan="3" GridPane.rowIndex="1" visible="false" />
<Label text="%validation.rule.label.dateformat" GridPane.columnIndex="1" GridPane.rowIndex="8" /> <CheckBox fx:id="enableNotEmptyRule" mnemonicParsing="false" text="%validation.rule.label.not_empty" GridPane.rowIndex="3" />
<Label text="%validation.rule.label.alphanumeric" GridPane.columnIndex="1" GridPane.rowIndex="4" /> <CheckBox fx:id="enableUniqueRule" mnemonicParsing="false" text="%validation.rule.label.unique" GridPane.columnIndex="2" GridPane.rowIndex="3" />
<Label text="%validation.rule.label.regexp" GridPane.columnIndex="1" GridPane.rowIndex="9" /> <CheckBox fx:id="enableMinLengthRule" mnemonicParsing="false" text="%validation.rule.label.minlength" GridPane.rowIndex="4" />
<Label text="%validation.rule.label.value_of" GridPane.columnIndex="1" GridPane.rowIndex="10" /> <Spinner fx:id="minLengthSpinner" GridPane.columnIndex="1" GridPane.rowIndex="4" />
<Label text="%validation.rule.label.groovy" GridPane.columnIndex="1" GridPane.rowIndex="11" /> <CheckBox fx:id="enableMaxLengthRule" mnemonicParsing="false" text="%validation.rule.label.maxlength" GridPane.columnIndex="2" GridPane.rowIndex="4" />
<Label text="%validation.rule.label.unique" GridPane.columnIndex="1" GridPane.rowIndex="5" /> <Spinner fx:id="maxLengthSpinner" GridPane.columnIndex="3" GridPane.rowIndex="4" />
<CheckBox fx:id="enableNotEmptyRule" mnemonicParsing="false" GridPane.rowIndex="1" /> <CheckBox fx:id="enableRegexpRule" mnemonicParsing="false" text="%validation.rule.label.regexp" GridPane.rowIndex="5" />
<CheckBox fx:id="notEmptyRuleCheckBox" mnemonicParsing="false" GridPane.columnIndex="2" GridPane.rowIndex="1" /> <TextField fx:id="regexpRuleTextField" GridPane.columnIndex="1" GridPane.columnSpan="3" GridPane.rowIndex="5" />
<CheckBox fx:id="enableIntegerRule" mnemonicParsing="false" GridPane.rowIndex="2" /> <CheckBox fx:id="enableValueOfRule" mnemonicParsing="false" text="%validation.rule.label.value_of" GridPane.rowIndex="6" />
<CheckBox fx:id="integerRuleCheckBox" mnemonicParsing="false" GridPane.columnIndex="2" GridPane.rowIndex="2" /> <TextField fx:id="valueOfRuleTextField" GridPane.columnIndex="1" GridPane.columnSpan="3" GridPane.rowIndex="6" />
<CheckBox fx:id="enableDoubleRule" mnemonicParsing="false" GridPane.rowIndex="3" /> <CheckBox fx:id="enableGroovyRule" mnemonicParsing="false" text="%validation.rule.label.groovy" GridPane.rowIndex="7">
<CheckBox fx:id="doublerRuleCheckBox" mnemonicParsing="false" GridPane.columnIndex="2" GridPane.rowIndex="3" /> <GridPane.margin>
<CheckBox fx:id="enableAlphanumericRule" mnemonicParsing="false" GridPane.rowIndex="4" /> <Insets top="8.0" />
<CheckBox fx:id="alphanumericRuleCheckBox" mnemonicParsing="false" GridPane.columnIndex="2" GridPane.rowIndex="4" /> </GridPane.margin>
<CheckBox fx:id="enableUniqueRule" mnemonicParsing="false" GridPane.rowIndex="5" /> </CheckBox>
<CheckBox fx:id="uniqueRuleCheckBox" mnemonicParsing="false" GridPane.columnIndex="2" GridPane.rowIndex="5" /> <CodeArea fx:id="groovyRuleTextArea" minHeight="-Infinity" minWidth="-Infinity" prefHeight="200.0" GridPane.columnIndex="1" GridPane.columnSpan="3" GridPane.rowIndex="7">
<CheckBox fx:id="enableMinLengthRule" mnemonicParsing="false" GridPane.rowIndex="6" /> <GridPane.margin>
<Spinner fx:id="minLengthSpinner" GridPane.columnIndex="2" GridPane.rowIndex="6" /> <Insets top="8.0" />
<CheckBox fx:id="enableMaxLengthRule" mnemonicParsing="false" GridPane.rowIndex="7" /> </GridPane.margin>
<Spinner fx:id="maxLengthSpinner" GridPane.columnIndex="2" GridPane.rowIndex="7" /> </CodeArea>
<CheckBox fx:id="enableDateRule" mnemonicParsing="false" GridPane.rowIndex="8" /> <Separator prefWidth="200.0" GridPane.columnSpan="4" GridPane.rowIndex="2" />
<TextField fx:id="dateformatRuleTextField" GridPane.columnIndex="2" GridPane.rowIndex="8" />
<CheckBox fx:id="enableRegexpRule" mnemonicParsing="false" GridPane.rowIndex="9" />
<TextField fx:id="regexpRuleTextField" GridPane.columnIndex="2" GridPane.rowIndex="9" />
<CheckBox fx:id="enableValueOfRule" mnemonicParsing="false" GridPane.rowIndex="10" />
<TextField fx:id="valueOfRuleTextField" GridPane.columnIndex="2" GridPane.rowIndex="10" />
<CheckBox fx:id="enableGroovyRule" mnemonicParsing="false" GridPane.rowIndex="11" />
<CodeArea fx:id="groovyRuleTextArea" prefHeight="300.0" prefWidth="200.0" GridPane.columnIndex="2" GridPane.rowIndex="11" GridPane.rowSpan="2" />
<Label style="-fx-font-weight: bold;" text="%validation.rules.active" />
<Label style="-fx-font-weight: bold;" text="%validation.rules.name" GridPane.columnIndex="1" />
<Label style="-fx-font-weight: bold;" text="%validation.rules.value" GridPane.columnIndex="2" />
</children> </children>
<padding> <padding>

View File

@@ -2,7 +2,7 @@
The MIT License (MIT) The MIT License (MIT)
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
Copyright (c) 2015 javafx.ninja <info@javafx.ninja> Copyright (c) 2015-2016 javafx.ninja <info@javafx.ninja>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@@ -2,7 +2,7 @@
The MIT License (MIT) The MIT License (MIT)
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
Copyright (c) 2015 javafx.ninja <info@javafx.ninja> Copyright (c) 2015-2016 javafx.ninja <info@javafx.ninja>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
@@ -28,6 +28,7 @@ package ninja.javafx.smartcsv.validation;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.GsonBuilder; import com.google.gson.GsonBuilder;
import ninja.javafx.smartcsv.validation.configuration.ValidationConfiguration;
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;

View File

@@ -2,6 +2,7 @@ package ninja.javafx.smartcsv.validation;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.GsonBuilder; import com.google.gson.GsonBuilder;
import ninja.javafx.smartcsv.validation.configuration.ValidationConfiguration;
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;