Skip to content

Adding a custom validator

Gal Koren edited this page Nov 12, 2020 · 1 revision

I assume you read the previous chapter "State Consumer" because this validator is a state consumer.
The basic validators we saw before had a limited functionality regarding the set of fields you can validate.
Wanna be unlimited? Let's take a look at the ChangesValidator.

This validator has no optimization. It is always triggered because PL doesn't know what are you validating.

In our example, we have an AdEntity and a CampaignEntity where an Ad has a reference (direct or through other entities) to the Campaign that contains it.
Let's create a validation based on 3 different fields: The URL and HEADLINE of the Ad entity, and the CAMPAIGN_TYPE of the Campaign entity.

class AdUrlMustNotIncludeHeadlineOnVideoCampaigns implements ChangesValidator<AdEntity> {

    @Override
    public Stream<? extends EntityField<?, ?>> requiredFields(Collection<? extends EntityField<AdEntity, ?>> fieldsToUpdate, ChangeOperation operator) {
        return Stream.of(
            CampaignEntity.CAMPAIGN_TYPE, 
            AdEntity.URL, 
            AdEntity.HEADLINE);
    }

    @Override
    public void validate(Collection<? extends EntityChange<AdEntity>> commands, ChangeOperation op, ChangeContext ctx) {

        commands.forEach(cmd -> {
            final var values = ctx.getFinalEntity(cmd);  
            if (values.get(CAMPAIGN_TYPE) == Video && values.get(URL).contains(values.get(HEADLINE))) {
               ctx.addValidationError(cmd, new ValidationError("URL must not contain the headline text on video campaigns"));
            }
        });

    }

}