reorganize validation package

This commit is contained in:
2016-09-12 04:48:22 +02:00
committed by Andreas Billmann
parent 7723906935
commit 4002219dfe
27 changed files with 274 additions and 167 deletions

View File

@@ -51,13 +51,13 @@ public class ErrorExport extends Service {
format(resourceBundle.getString("log.header.message"),
csvFilename,
Integer.toString(model.getValidationError().size()))).append("\n\n");
for (ValidationError error:model.getValidationError()) {
model.getValidationError().forEach(error ->
log.append(
format(resourceBundle.getString("log.message"),
error.getLineNumber().toString(),
error.getColumn(),
getI18nValidatioMessage(resourceBundle, error))).append("\n");
}
getI18nValidatioMessage(resourceBundle, error))).append("\n")
);
Files.write(file.toPath(), log.toString().getBytes());
} catch (Throwable ex) {

View File

@@ -56,7 +56,7 @@ import ninja.javafx.smartcsv.fx.util.SaveFileService;
import ninja.javafx.smartcsv.fx.validation.ValidationEditorController;
import ninja.javafx.smartcsv.preferences.PreferencesFileReader;
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.ValidationFileReader;
import ninja.javafx.smartcsv.validation.ValidationFileWriter;
@@ -425,6 +425,7 @@ public class SmartCSVController extends FXMLController {
public void showValidationEditor(String column) {
validationEditorController.setSelectedColumn(column);
validationEditorController.updateForm();
Alert alert = new Alert(Alert.AlertType.CONFIRMATION);
alert.setGraphic(null);

View File

@@ -137,9 +137,7 @@ public class ErrorSideBar extends Region {
int rows = model.get().getRows().size();
double space = (double)heightWithoutStatusBlock() / rows;
for (ValidationError error : errorList) {
errorMarkerList.add(generateErrorMarker(space, error));
}
errorList.forEach(error -> errorMarkerList.add(generateErrorMarker(space, error)));
}
}
getChildren().setAll(errorMarkerList);

View File

@@ -29,7 +29,7 @@ package ninja.javafx.smartcsv.fx.table.model;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
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.Validator;
import org.apache.logging.log4j.LogManager;

View File

@@ -43,9 +43,8 @@ public class I18nValidationUtil {
public static String getI18nValidatioMessage(ResourceBundle resourceBundle, List<ValidationError> errors) {
StringWriter message = new StringWriter();
for (ValidationError validationError: errors) {
message.append(getI18nValidatioMessage(resourceBundle, validationError)).append("\n");
}
errors.forEach(error -> message.append(getI18nValidatioMessage(resourceBundle, error)).append("\n"));
if (message.toString().length() != 0) {
return cutOffLastLineBreak(message.toString());
@@ -66,7 +65,7 @@ public class I18nValidationUtil {
List<ValidationMessage> validationMessages = error.getMessages();
StringWriter message = new StringWriter();
for (ValidationMessage validationMessage: validationMessages) {
validationMessages.forEach(validationMessage -> {
message.append(prefix);
if (resourceBundle.containsKey(validationMessage.getKey())) {
String resourceText = resourceBundle.getString(validationMessage.getKey());
@@ -78,7 +77,7 @@ public class I18nValidationUtil {
} else {
message.append(validationMessage.getKey()).append("\n");
}
}
});
if (!validationMessages.isEmpty()) {
return cutOffLastLineBreak(message.toString());

View File

@@ -32,9 +32,9 @@ import javafx.fxml.FXML;
import javafx.scene.control.*;
import javafx.scene.control.SpinnerValueFactory.IntegerSpinnerValueFactory;
import ninja.javafx.smartcsv.fx.FXMLController;
import ninja.javafx.smartcsv.validation.ConstraintsConfiguration;
import ninja.javafx.smartcsv.validation.FieldConfiguration;
import ninja.javafx.smartcsv.validation.ValidationConfiguration;
import ninja.javafx.smartcsv.validation.configuration.ConstraintsConfiguration;
import ninja.javafx.smartcsv.validation.configuration.FieldConfiguration;
import ninja.javafx.smartcsv.validation.configuration.ValidationConfiguration;
import org.fxmisc.richtext.CodeArea;
import org.fxmisc.richtext.LineNumberFactory;
import org.fxmisc.richtext.StyleSpans;
@@ -50,9 +50,12 @@ import java.util.ResourceBundle;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static java.lang.Boolean.FALSE;
import static java.util.Arrays.asList;
import static java.util.stream.Collectors.joining;
import static javafx.beans.binding.Bindings.when;
import static javafx.collections.FXCollections.observableList;
import static ninja.javafx.smartcsv.validation.configuration.FieldConfiguration.*;
/**
* controller for editing column validations
@@ -102,6 +105,12 @@ public class ValidationEditorController extends FXMLController {
@FXML
private ComboBox<FieldConfiguration.Type> typeComboBox;
@FXML
private ComboBox<String> formatComboBox;
@FXML
private TextField formatTextField;
@FXML
private Spinner<Integer> minLengthSpinner;
@@ -147,27 +156,112 @@ public class ValidationEditorController extends FXMLController {
@Override
public void initialize(URL location, ResourceBundle resources) {
typeComboBox.getItems().addAll(FieldConfiguration.Type.STRING,
FieldConfiguration.Type.INTEGER,
FieldConfiguration.Type.NUMBER,
FieldConfiguration.Type.DATE,
FieldConfiguration.Type.DATETIME,
FieldConfiguration.Type.TIME);
typeComboBox.setValue(FieldConfiguration.Type.STRING);
initTypeAndFormatInput();
initMinMaxSpinner();
initSpinner(minLengthSpinner, enableMinLengthRule);
initSpinner(maxLengthSpinner, enableMaxLengthRule);
initTextInputControl(regexpRuleTextField, enableRegexpRule);
initTextInputControl(valueOfRuleTextField, enableValueOfRule);
initCodeAreaControl(groovyRuleTextArea, enableGroovyRule);
}
public String getSelectedColumn() {
return selectedColumn.get();
}
selectedColumn.addListener(observable -> {
updateForm();
});
public StringProperty selectedColumnProperty() {
return selectedColumn;
}
public void setSelectedColumn(String selectedColumn) {
this.selectedColumn.set(selectedColumn);
}
public void setValidationConfiguration(ValidationConfiguration validationConfiguration) {
this.validationConfiguration = validationConfiguration;
}
private void initTypeAndFormatInput() {
typeComboBox.getItems().addAll(Type.STRING,
Type.INTEGER,
Type.NUMBER,
Type.DATE,
Type.DATETIME,
Type.TIME);
formatComboBox.setDisable(true);
formatTextField.setDisable(true);
typeComboBox.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> clearFormatComboBox());
formatComboBox.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> clearFormatTextField());
}
private void updateFormatTextField() {
FieldConfiguration config = getCurrentFieldConfig();
switch (config.getType()) {
case DATE:
case DATETIME:
case TIME:
if (config.getFormat().startsWith("fmt:")) {
formatTextField.setText(config.getFormat().substring(4));
} else {
formatTextField.setText(config.getFormat());
}
break;
default:
formatTextField.setText(null);
break;
}
}
private void clearFormatTextField() {
FieldConfiguration config = getCurrentFieldConfig();
formatTextField.setText(null);
switch (config.getType()) {
case DATE:
case DATETIME:
case TIME:
formatTextField.setDisable(false);
break;
default:
formatTextField.setDisable(true);
break;
}
}
private void clearFormatComboBox() {
formatTextField.setText(null);
formatTextField.setDisable(true);
changeFormat();
if (!formatComboBox.isDisable()) {
formatComboBox.getSelectionModel().selectFirst();
} else {
formatComboBox.getSelectionModel().clearSelection();
}
}
private void updateFormInput() {
FieldConfiguration config = getCurrentFieldConfig();
if (!formatComboBox.isDisable()) {
if (config.getFormat() == null) {
formatComboBox.getSelectionModel().selectFirst();
} else {
switch (config.getType()) {
case STRING:
case NUMBER:
formatComboBox.getSelectionModel().select(config.getFormat());
break;
case DATE:
case DATETIME:
case TIME:
if (config.getFormat().startsWith("fmt:")) {
formatComboBox.getSelectionModel().select(DateFormat.FMT_PATTERN.toString());
} else {
formatComboBox.getSelectionModel().select(DateFormat.ANY.toString());
}
break;
}
}
}
}
private void initMinMaxSpinner() {
@@ -188,94 +282,44 @@ public class ValidationEditorController extends FXMLController {
}
public String getSelectedColumn() {
return selectedColumn.get();
}
public StringProperty selectedColumnProperty() {
return selectedColumn;
}
public void setSelectedColumn(String selectedColumn) {
this.selectedColumn.set(selectedColumn);
}
public void setValidationConfiguration(ValidationConfiguration validationConfiguration) {
this.validationConfiguration = validationConfiguration;
}
private void changeFormatInput() {
private void changeFormat() {
formatComboBox.getItems().clear();
formatComboBox.getSelectionModel().clearSelection();
switch (typeComboBox.getValue()) {
case STRING:
/*
default: any valid string.
email: A valid email address.
uri: A valid URI.
binary: A base64 encoded string representing binary data.
uuid: A string that is a uuid
*/
updateFormatComboBox(getStringFormats());
break;
case NUMBER:
/*
decimalChar: A string whose value is used to represent a decimal point within the number. The default value is ".".
groupChar: A string whose value is used to group digits within the number. The default value is null. A common value is "," e.g. "100,000".
currency
*/
break;
updateFormatComboBox(getNumberFormats());
break;
case DATE:
/*
default: An ISO8601 format string.
This MUST be in ISO8601 format YYYY-MM-DD
any: Any parsable representation of the type. The implementing library can attempt to parse the datetime via a range of strategies.
An example is dateutil.parser.parse from the python-dateutils library.
fmt:PATTERN: date/time values in this field conform to PATTERN where [PATTERN] follows the syntax of standard Python / C strptime.
*/
break;
case DATETIME:
/*
default: An ISO8601 format string.
datetime: a date-time. This MUST be in ISO 8601 format of YYYY-MM-DDThhssZ in UTC time
any: Any parsable representation of the type. The implementing library can attempt to parse the datetime via a range of strategies.
An example is dateutil.parser.parse from the python-dateutils library.
fmt:PATTERN: date/time values in this field conform to PATTERN where [PATTERN] follows the syntax of standard Python / C strptime.
*/
break;
case TIME:
/*
default: An ISO8601 format string.
time: a time without a date
any: Any parsable representation of the type. The implementing library can attempt to parse the datetime via a range of strategies.
An example is dateutil.parser.parse from the python-dateutils library.
fmt:PATTERN: date/time values in this field conform to PATTERN where [PATTERN] follows the syntax of standard Python / C strptime.
*/
updateFormatComboBox(getDateFormats());
break;
// case GEOPOINT:
// /*
// default: A string of the pattern "lon, lat", where lon is the longitude and lat is the latitude.
// array: An array of exactly two items, where each item is either a number, or a string parsable as a number, and the first item is lon and the second item is lat.
// object: A JSON object with exactly two keys, lat and lon
// */
// break;
// case GEOJSON:
// /*
// default: A geojson object as per the GeoJSON spec.
// topojson: A topojson object as per the TopoJSON spec
// */
// case DURATION:
// case OBJECT:
// case ARRAY:
case INTEGER:
default:
// format: no options
formatComboBox.setDisable(true);
formatTextField.setDisable(true);
formatTextField.setText(null);
break;
}
updateFormInput();
}
private void updateFormatComboBox(List<String> values) {
formatComboBox.getItems().setAll(observableList(values));
formatComboBox.setEditable(false);
formatComboBox.setDisable(false);
formatTextField.setDisable(true);
formatTextField.setText(null);
}
public void updateConfiguration() {
FieldConfiguration config = validationConfiguration.getFieldConfiguration(getSelectedColumn());
FieldConfiguration config = getCurrentFieldConfig();
config.setType(typeComboBox.getValue());
if (enableGroovyRule.isSelected()) {
@@ -289,9 +333,6 @@ public class ValidationEditorController extends FXMLController {
constraints = new ConstraintsConfiguration();
}
if (enableNotEmptyRule.isSelected()) {
constraints.setRequired(enableNotEmptyRule.isSelected());
} else {
@@ -330,6 +371,10 @@ public class ValidationEditorController extends FXMLController {
}
private FieldConfiguration getCurrentFieldConfig() {
return validationConfiguration.getFieldConfiguration(getSelectedColumn());
}
private void addDependencyListener(CheckBox rule, CheckBox... dependentRules) {
rule.selectedProperty().addListener((observable, oldValue, newValue) -> {
if (newValue) {
@@ -340,9 +385,9 @@ public class ValidationEditorController extends FXMLController {
});
}
private void updateForm() {
public void updateForm() {
FieldConfiguration config = validationConfiguration.getFieldConfiguration(getSelectedColumn());
FieldConfiguration config = getCurrentFieldConfig();
if (config.getType() != null) {
typeComboBox.setValue(config.getType());
@@ -350,6 +395,9 @@ public class ValidationEditorController extends FXMLController {
typeComboBox.setValue(FieldConfiguration.Type.STRING);
}
updateFormInput();
updateFormatTextField();
updateCodeAreaControl(
groovyRuleTextArea,
config.getGroovy(),
@@ -357,8 +405,8 @@ public class ValidationEditorController extends FXMLController {
);
ConstraintsConfiguration constraints = config.getConstraints();
updateCheckBox(constraints != null ? constraints.getRequired() : false, enableNotEmptyRule);
updateCheckBox(constraints != null ? constraints.getUnique() : false, enableUniqueRule);
updateCheckBox(constraints != null ? constraints.getRequired() : FALSE, enableNotEmptyRule);
updateCheckBox(constraints != null ? constraints.getUnique() : FALSE, enableUniqueRule);
updateSpinner(
minLengthSpinner,

View File

@@ -28,6 +28,7 @@ package ninja.javafx.smartcsv.validation;
import com.google.gson.GsonBuilder;
import ninja.javafx.smartcsv.FileReader;
import ninja.javafx.smartcsv.validation.configuration.ValidationConfiguration;
import java.io.File;
import java.io.IOException;
@@ -42,7 +43,6 @@ public class ValidationFileReader implements FileReader<ValidationConfiguration>
@Override
public void read(File file) throws IOException {
config = new GsonBuilder().create().fromJson(new java.io.FileReader(file), ValidationConfiguration.class);
System.out.println("brechpunkt");
}
public ValidationConfiguration getContent() {

View File

@@ -29,6 +29,7 @@ package ninja.javafx.smartcsv.validation;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import ninja.javafx.smartcsv.FileWriter;
import ninja.javafx.smartcsv.validation.configuration.ValidationConfiguration;
import java.io.File;
import java.io.IOException;

View File

@@ -27,13 +27,16 @@
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.ConstraintsConfiguration;
import ninja.javafx.smartcsv.validation.configuration.FieldConfiguration;
import ninja.javafx.smartcsv.validation.configuration.ValidationConfiguration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static ninja.javafx.smartcsv.validation.ValidationFormatHelper.dateFormat;
import static ninja.javafx.smartcsv.validation.ValidationFormatHelper.doubleToInteger;
/**
* This class checks all the validations defined in the

View File

@@ -23,7 +23,9 @@
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;

View File

@@ -23,7 +23,9 @@
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;

View File

@@ -1,4 +1,4 @@
package ninja.javafx.smartcsv.validation;
package ninja.javafx.smartcsv.validation.checker;
/**
* validations based on this are not validated when the value is null or empty

View File

@@ -23,11 +23,12 @@
THE SOFTWARE.
*/
package ninja.javafx.smartcsv.validation;
package ninja.javafx.smartcsv.validation.checker;
import groovy.lang.Binding;
import groovy.lang.GroovyShell;
import groovy.lang.Script;
import ninja.javafx.smartcsv.validation.ValidationError;
import org.codehaus.groovy.control.CompilationFailedException;
/**

View File

@@ -23,7 +23,9 @@
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;

View File

@@ -23,7 +23,9 @@
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;

View File

@@ -23,7 +23,9 @@
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;

View File

@@ -23,7 +23,9 @@
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;

View File

@@ -23,7 +23,9 @@
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;

View File

@@ -23,9 +23,10 @@
THE SOFTWARE.
*/
package ninja.javafx.smartcsv.validation;
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;

View File

@@ -23,7 +23,9 @@
THE SOFTWARE.
*/
package ninja.javafx.smartcsv.validation;
package ninja.javafx.smartcsv.validation.checker;
import ninja.javafx.smartcsv.validation.ValidationError;
/**
* Interface for all validations

View File

@@ -23,7 +23,9 @@
THE SOFTWARE.
*/
package ninja.javafx.smartcsv.validation;
package ninja.javafx.smartcsv.validation.checker;
import ninja.javafx.smartcsv.validation.ValidationError;
import java.util.List;

View File

@@ -1,4 +1,4 @@
package ninja.javafx.smartcsv.validation;
package ninja.javafx.smartcsv.validation.configuration;
import com.google.gson.annotations.SerializedName;

View File

@@ -1,7 +1,11 @@
package ninja.javafx.smartcsv.validation;
package ninja.javafx.smartcsv.validation.configuration;
import com.google.gson.annotations.SerializedName;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* @author abi
*/
@@ -22,6 +26,45 @@ public class FieldConfiguration {
// @SerializedName("geojson") GEOJSON
}
public enum StringFormat {
@SerializedName("default") DEFAULT,
@SerializedName("email") EMAIL,
@SerializedName("uri") URI,
@SerializedName("binary") BINARY,
@SerializedName("uuid") UUID
}
public static List<String> getStringFormats() {
return Stream.of(StringFormat.values())
.map(StringFormat::name)
.collect(Collectors.toList());
}
public enum NumberFormat {
@SerializedName("decimalChar") DECIMAL_CHAR,
@SerializedName("groupChar") GROUP_CHAR,
@SerializedName("currency") CURRENCY
}
public static List<String> getNumberFormats() {
return Stream.of(NumberFormat.values())
.map(NumberFormat::name)
.collect(Collectors.toList());
}
public enum DateFormat {
@SerializedName("default") DEFAULT,
@SerializedName("any") ANY,
@SerializedName("fmtPattern") FMT_PATTERN
}
public static List<String> getDateFormats() {
return Stream.of(DateFormat.values())
.map(DateFormat::name)
.collect(Collectors.toList());
}
private String name;
private String title;
private Type type;

View File

@@ -24,7 +24,7 @@
*/
package ninja.javafx.smartcsv.validation;
package ninja.javafx.smartcsv.validation.configuration;
import com.google.gson.annotations.SerializedName;

View File

@@ -13,65 +13,57 @@
<?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.101" xmlns:fx="http://javafx.com/fxml/1">
<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 halignment="LEFT" hgrow="NEVER"/>
<ColumnConstraints halignment="LEFT" hgrow="ALWAYS"/>
<ColumnConstraints halignment="LEFT" hgrow="NEVER"/>
<ColumnConstraints halignment="LEFT" hgrow="ALWAYS"/>
<ColumnConstraints halignment="LEFT" hgrow="NEVER" />
<ColumnConstraints halignment="LEFT" hgrow="ALWAYS" />
<ColumnConstraints halignment="LEFT" hgrow="NEVER" />
<ColumnConstraints halignment="LEFT" hgrow="ALWAYS" />
</columnConstraints>
<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" 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" valignment="TOP" vgrow="ALWAYS"/>
<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" 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" valignment="TOP" vgrow="ALWAYS" />
<RowConstraints />
</rowConstraints>
<children>
<Label text="%validation.rule.type" GridPane.columnSpan="2" GridPane.halignment="LEFT" GridPane.hgrow="ALWAYS"/>
<Label text="%validation.rule.format" GridPane.columnSpan="2" GridPane.halignment="LEFT" GridPane.hgrow="ALWAYS"
GridPane.rowIndex="1"/>
<ComboBox fx:id="typeComboBox" maxWidth="1.7976931348623157E308" GridPane.columnIndex="1"
GridPane.columnSpan="3" GridPane.halignment="LEFT" GridPane.hgrow="ALWAYS"/>
<CheckBox fx:id="enableNotEmptyRule" mnemonicParsing="false" text="%validation.rule.label.not_empty"
GridPane.rowIndex="3"/>
<CheckBox fx:id="enableUniqueRule" mnemonicParsing="false" text="%validation.rule.label.unique"
GridPane.columnIndex="2" GridPane.rowIndex="3"/>
<CheckBox fx:id="enableMinLengthRule" mnemonicParsing="false" text="%validation.rule.label.minlength"
GridPane.rowIndex="4"/>
<Spinner fx:id="minLengthSpinner" GridPane.columnIndex="1" GridPane.rowIndex="4"/>
<CheckBox fx:id="enableMaxLengthRule" mnemonicParsing="false" text="%validation.rule.label.maxlength"
GridPane.columnIndex="2" GridPane.rowIndex="4"/>
<Spinner fx:id="maxLengthSpinner" GridPane.columnIndex="3" GridPane.rowIndex="4"/>
<CheckBox fx:id="enableRegexpRule" mnemonicParsing="false" text="%validation.rule.label.regexp"
GridPane.rowIndex="5"/>
<TextField fx:id="regexpRuleTextField" GridPane.columnIndex="1" GridPane.columnSpan="3" GridPane.rowIndex="5"/>
<CheckBox fx:id="enableValueOfRule" mnemonicParsing="false" text="%validation.rule.label.value_of"
GridPane.rowIndex="6"/>
<TextField fx:id="valueOfRuleTextField" GridPane.columnIndex="1" GridPane.columnSpan="3" GridPane.rowIndex="6"/>
<CheckBox fx:id="enableGroovyRule" mnemonicParsing="false" text="%validation.rule.label.groovy"
GridPane.rowIndex="7">
<Label text="%validation.rule.type" GridPane.columnSpan="2" GridPane.halignment="LEFT" GridPane.hgrow="ALWAYS" />
<Label text="%validation.rule.format" GridPane.columnSpan="2" GridPane.halignment="LEFT" GridPane.hgrow="ALWAYS" GridPane.rowIndex="1" />
<ComboBox fx:id="typeComboBox" maxWidth="1.7976931348623157E308" GridPane.columnIndex="1" GridPane.columnSpan="3" GridPane.halignment="LEFT" GridPane.hgrow="ALWAYS" />
<ComboBox fx:id="formatComboBox" prefWidth="150.0" GridPane.columnIndex="1" GridPane.rowIndex="1" />
<TextField fx:id="formatTextField" GridPane.columnIndex="2" GridPane.columnSpan="2" GridPane.rowIndex="1" />
<CheckBox fx:id="enableNotEmptyRule" mnemonicParsing="false" text="%validation.rule.label.not_empty" GridPane.rowIndex="3" />
<CheckBox fx:id="enableUniqueRule" mnemonicParsing="false" text="%validation.rule.label.unique" GridPane.columnIndex="2" GridPane.rowIndex="3" />
<CheckBox fx:id="enableMinLengthRule" mnemonicParsing="false" text="%validation.rule.label.minlength" GridPane.rowIndex="4" />
<Spinner fx:id="minLengthSpinner" GridPane.columnIndex="1" GridPane.rowIndex="4" />
<CheckBox fx:id="enableMaxLengthRule" mnemonicParsing="false" text="%validation.rule.label.maxlength" GridPane.columnIndex="2" GridPane.rowIndex="4" />
<Spinner fx:id="maxLengthSpinner" GridPane.columnIndex="3" GridPane.rowIndex="4" />
<CheckBox fx:id="enableRegexpRule" mnemonicParsing="false" text="%validation.rule.label.regexp" GridPane.rowIndex="5" />
<TextField fx:id="regexpRuleTextField" GridPane.columnIndex="1" GridPane.columnSpan="3" GridPane.rowIndex="5" />
<CheckBox fx:id="enableValueOfRule" mnemonicParsing="false" text="%validation.rule.label.value_of" GridPane.rowIndex="6" />
<TextField fx:id="valueOfRuleTextField" GridPane.columnIndex="1" GridPane.columnSpan="3" GridPane.rowIndex="6" />
<CheckBox fx:id="enableGroovyRule" mnemonicParsing="false" text="%validation.rule.label.groovy" GridPane.rowIndex="7">
<GridPane.margin>
<Insets top="8.0"/>
<Insets top="8.0" />
</GridPane.margin>
</CheckBox>
<CodeArea fx:id="groovyRuleTextArea" minHeight="-Infinity" minWidth="-Infinity" prefHeight="200.0"
GridPane.columnIndex="1" GridPane.columnSpan="3" GridPane.rowIndex="7">
<CodeArea fx:id="groovyRuleTextArea" minHeight="-Infinity" minWidth="-Infinity" prefHeight="200.0" GridPane.columnIndex="1" GridPane.columnSpan="3" GridPane.rowIndex="7">
<GridPane.margin>
<Insets top="8.0"/>
<Insets top="8.0" />
</GridPane.margin>
</CodeArea>
<Separator prefWidth="200.0" GridPane.columnSpan="4" GridPane.rowIndex="2"/>
<Separator prefWidth="200.0" GridPane.columnSpan="4" GridPane.rowIndex="2" />
</children>
<padding>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0"/>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
</padding>
<stylesheets>
<URL value="@/ninja/javafx/smartcsv/fx/smartcsv.css"/>
<URL value="@/ninja/javafx/smartcsv/fx/smartcsv.css" />
</stylesheets>
</GridPane>