Tosan Validation is a Java library for field validation using Hibernate Validator. It extends Jakarta Validation with custom validators for Iranian-specific validations (national codes, IBAN, mobile numbers, Jalali dates) and advanced validation features.
Key Dependencies:
- Java 17
- Hibernate Validator
- Jakarta Validation API
- jalali-calendar (for Persian date support)
The library builds on top of Jakarta Validation/Hibernate Validator with three key architectural patterns:
-
Parameter Injection via Properties File: Validators can reference dynamic values from a
validation-key-value.propertiesfile. This allows validation rules to be configurable without code changes. -
ValidatorBuilder Pattern: Entry point for creating validator instances. Located in
com.tosan.validation.core.ValidatorBuilder, it:- Loads parameters from properties files or maps
- Configures a custom
CustomMessageInterpolatorfor parameter substitution - Sets up
MapAwareValidatorFactoryto inject parameters into validators - Returns a fully configured Jakarta
Validatorinstance
-
Map-Aware Validation: Support for validating Map structures dynamically using
@FieldDescriptorannotations. TheMapAwareValidatorFactoryandMapAwareValidatorbase class enable validators to access external parameters and validator context.
-
com.tosan.validation.constraints: Annotation definitions for all custom validators- Iranian-specific:
@NationalCode,@Iban,@MobileNumber,@Pervasive - Date validations:
@ValidateJalaliDate,@PastJalaliDate,@FutureJalaliDate,@DateDifference - Advanced:
@Expression,@Compare,@ConditionalNotEmpty,@Group
- Iranian-specific:
-
com.tosan.validation.constraints.impl: Validator implementations- All validators extend either
BaseValidatoror implement standard Jakarta validation interfaces - Many validators inherit from
MapAwareValidatorto access external parameters
- All validators extend either
-
com.tosan.validation.core: Core framework classesValidatorBuilder: Main entry point for creating validatorsMapAwareValidatorFactory: Custom factory for injecting parametersFieldDescriptorExtractor*: Classes for extracting validation metadata from Map structuresCustomMessageInterpolator: Substitutes parameter placeholders in error messages
-
com.tosan.validation.util: UtilitiesValidationConstraintViolationInfoTreeGenerator: Generates hierarchical validation error structuresExpressionUtil: SPEL expression evaluation for@Expressionvalidatorsdate/: Date comparison utilities supporting multiple temporal types and Jalali dates
-
Expression-Based Validation:
@Expressionand@Expressionsuse Spring Expression Language (SPEL) to evaluate complex conditional validation rules referencing other fields in the object. -
Field Comparison:
@Comparevalidates relationships between fields (e.g., endDate > startDate). -
Conditional Validation:
@ConditionalNotEmptymakes fields required based on conditions. -
Map Validation:
@ValidMapand@ValidCollectionwith@FieldDescriptorenable validation of dynamic Map/Collection structures where field names aren't known at compile time. -
Date Difference Validation:
@DateDifferencevalidates time spans between two date fields with configurable units (days, months, years). -
Group Sequencing:
@Groupallows conditional validation group execution based on field values.
- Tests use TestNG framework (not JUnit)
- Test files are in
src/test/java/com/tosan/validation/ - Test resources (including sample properties) are in
src/test/resource/ - Most tests validate constraint violations using the standard Jakarta Validation API pattern
The project uses maven-release-plugin with:
- Tag format:
v{version}(e.g., v5.2.5) - Release profile for GitHub Packages deployment
- Build profile for Maven Central with GPG signing
- Resources are in
src/main/resourceandsrc/test/resource(not the standardresourcesnaming) - The library expects a
validation-key-value.propertiesfile in the classpath for parameterized validations (optional, but enables key features) - When creating new validators that need external parameters, extend
BaseValidatororMapAwareValidator - Custom validators requiring validator context should implement
ValidatorContextAwareConstraintValidator