Data Validations
Validations can be implemented in 2 locations:
- In the data layerLayerLogical separation of functionality within a single system/application, focused on code organization. for simple validations
- In the logic layerLayerLogical separation of functionality within a single system/application, focused on code organization. if the validation also requires access to other Components or other resources
In both layersLayerLogical separation of functionality within a single system/application, focused on code organization., the create and modify methods have the custom-preCreate and custom-preModify anchorsAnchorA marker within generated source code reserved for adding custom logic during re-expansion..
We can use these anchorsAnchorA marker within generated source code reserved for adding custom logic during re-expansion. to validate all incoming values:
// anchor:custom-preCreate:start
CrudsResult<DataRef> licensePlateValidation = validateLicensePlate(details.getLicensePlate());
if (licensePlateValidation.getLicensePlate()) {
return licensePlateValidation;
}
// anchor:custom-preCreate:end
// anchor:custom-preModify:start
CrudsResult<DataRef> licensePlateValidation = validateLicensePlate(starshipDetails.getLicensePlate());
if (licensePlateValidation.getLicensePlate()) {
return licensePlateValidation;
}
// anchor:custom-preModify:end
Now creating an invalid Starship instance or making an invalid change will be rejected before any changes to the database are made.
Error Messages
However, we might also need a clear error message:
CrudsResult<DataRef> error = CrudsResult.error(
Diagnostic.error("space", "Starship", "space.starship.invalidLicensePlate")
);
Diagnostics represent error messages. They are defined with 3 parameters:
- component: the name of the component, space in this case
- element: the name of the element, Starship in this case
- key: a key that uniquely defines the error message you wish to propagate, the convention is to define it
as
{component}.{element}.{errorDescription}or{component}.{element}.{field}.{errorDescription}
There are also some helper classes that can be used to create cruds error with error messages.
// DiagnosticFactory can create diagnostics
DiagnosticFactory diagnosticFactory = new DiagnosticFactory("space","starship");
Diagnostic errorMsg = diagnosticFactory.error("space.starship.demoError");
// DiagnosticHelper can create crudsErrors with diagnostics
DiagnosticHelper diagnosticHelper = new DiagnosticHelper("space", "starship");
CrudsResult<DataRef> crudsError = diagnosticHelper.createCrudsError("space.starship.invalidLicensePlate");
// DiagnosticFieldFactory can be used to create diagnostics on field level
DiagnosticFieldFactory fieldFactory = diagnosticFactory.fieldFactory("licensePlate");
Diagnostic fieldErrorMsg = fieldFactory.error("rentWork.car.licensePlate.invalidLicensePlate");
Last, we need to add the translations of the errors to the translation properties files. There are 3 properties files for each Component, which can be found in the Control LayerLayerLogical separation of functionality within a single system/application, focused on code organization.:
{component}.properties{component}_nl.properties{component}_en.properties
In these files, there are custom-translations anchorsAnchorA marker within generated source code reserved for adding custom logic during re-expansion. to add any additional translations:
# anchor:custom-translations:start
space.starship.invalidLicensePlate=Not a valid licensePlate
# anchor:custom-translations:end
You can also add additional translation files in the accompanying ext directory.
Options
FieldAdds a validation that rejects any undefined values for this FieldFieldA property of a DataElement expanded to a database column and user interface input element..
<options>
<isRequired/>
</options>
FieldRejects any new values for this fieldFieldA property of a DataElement expanded to a database column and user interface input element. that are not listed as a valid TagValuePair.
<options>
<validation.listField/>
</options>