Skip to content

Commit

Permalink
HV-1780 Add @Normalized contraint that validates unicode normalizatio…
Browse files Browse the repository at this point in the history
…n form
  • Loading branch information
candrews authored and gsmet committed Jun 8, 2020
1 parent 038f0f0 commit 423ecc1
Show file tree
Hide file tree
Showing 14 changed files with 302 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,7 @@ public ConstraintHelper(Types typeUtils, AnnotationApiHelper annotationApiHelper
registerAllowedTypesForBuiltInConstraint( HibernateValidatorTypes.PESEL_CHECK, CharSequence.class );
registerAllowedTypesForBuiltInConstraint( HibernateValidatorTypes.NOT_BLANK, CharSequence.class );
registerAllowedTypesForBuiltInConstraint( HibernateValidatorTypes.NOT_EMPTY, TYPES_SUPPORTED_BY_SIZE_AND_NOT_EMPTY_ANNOTATIONS );
registerAllowedTypesForBuiltInConstraint( HibernateValidatorTypes.NORMALIZED, CharSequence.class );
registerAllowedTypesForBuiltInConstraint( HibernateValidatorTypes.SAFE_HTML, CharSequence.class );
registerAllowedTypesForBuiltInConstraint( HibernateValidatorTypes.SCRIPT_ASSERT, Object.class );
registerAllowedTypesForBuiltInConstraint( HibernateValidatorTypes.UNIQUE_ELEMENTS, Collection.class );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ public static class HibernateValidatorTypes {
public static final String REGON_CHECK = ORG_HIBERNATE_VALIDATOR_CONSTRAINTS + ".pl.REGON";
public static final String NIP_CHECK = ORG_HIBERNATE_VALIDATOR_CONSTRAINTS + ".pl.NIP";
public static final String PESEL_CHECK = ORG_HIBERNATE_VALIDATOR_CONSTRAINTS + ".pl.PESEL";
public static final String NORMALIZED = ORG_HIBERNATE_VALIDATOR_CONSTRAINTS + ".Normalized";
public static final String NOT_BLANK = ORG_HIBERNATE_VALIDATOR_CONSTRAINTS + ".NotBlank";
public static final String NOT_EMPTY = ORG_HIBERNATE_VALIDATOR_CONSTRAINTS + ".NotEmpty";
public static final String SAFE_HTML = ORG_HIBERNATE_VALIDATOR_CONSTRAINTS + ".SafeHtml";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import org.hibernate.validator.ap.testmodel.ModelWithJava8DateTime;
import org.hibernate.validator.ap.testmodel.ModelWithJavaMoneyTypes;
import org.hibernate.validator.ap.testmodel.ModelWithJodaTypes;
import org.hibernate.validator.ap.testmodel.ModelWithNormalizedConstraints;
import org.hibernate.validator.ap.testmodel.ModelWithUniqueElementsConstraints;
import org.hibernate.validator.ap.testmodel.ModelWithoutConstraints;
import org.hibernate.validator.ap.testmodel.MultipleConstraintsOfSameType;
Expand Down Expand Up @@ -724,6 +725,25 @@ public void codePointLengthConstraints() {
);
}

@Test
@TestForIssue(jiraKey = "HV-1780")
public void normalizedConstraints() {
File[] sourceFiles = new File[] {
compilerHelper.getSourceFile( ModelWithNormalizedConstraints.class )
};

boolean compilationResult =
compilerHelper.compile( new ConstraintValidationProcessor(), diagnostics, false, true, sourceFiles );

assertFalse( compilationResult );
assertThatDiagnosticsMatch(
diagnostics,
new DiagnosticExpectation( Kind.ERROR, 17 ),
new DiagnosticExpectation( Kind.ERROR, 20 ),
new DiagnosticExpectation( Kind.ERROR, 23 )
);
}

@Test
public void isbnConstraints() {
File[] sourceFiles = new File[] {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* Hibernate Validator, declare and validate application constraints
*
* License: Apache License, Version 2.0
* See the license.txt file in the root directory or <http://www.apache.org/licenses/LICENSE-2.0>.
*/
package org.hibernate.validator.ap.testmodel;

import java.util.Collection;
import java.util.List;
import java.util.Set;

import org.hibernate.validator.constraints.Normalized;

public class ModelWithNormalizedConstraints {

@Normalized
public Collection<String> collection;

@Normalized
public List<String> list;

@Normalized
public Set<String> set;

@Normalized
public String string;
}
4 changes: 4 additions & 0 deletions documentation/src/main/asciidoc/ch02.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -707,6 +707,10 @@ With one exception also these constraints apply to the field/property level, onl
Supported data types::: `CharSequence`
Hibernate metadata impact::: None

`@Normalized(form=)`:: Validates that the annotated character sequence is normalized according to the given `form`.
Supported data types::: `CharSequence`
Hibernate metadata impact::: None

`@Range(min=, max=)`:: Checks whether the annotated value lies between (inclusive) the specified minimum and maximum
Supported data types::: `BigDecimal`, `BigInteger`, `CharSequence`, `byte`, `short`, `int`, `long` and the respective wrappers of the primitive types
Hibernate metadata impact::: None
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* Hibernate Validator, declare and validate application constraints
*
* License: Apache License, Version 2.0
* See the license.txt file in the root directory or <http://www.apache.org/licenses/LICENSE-2.0>.
*/

package org.hibernate.validator.cfg.defs;

import org.hibernate.validator.cfg.ConstraintDef;
import org.hibernate.validator.constraints.Normalized;

import java.text.Normalizer;


/**
* Constraint definition for {@link Normalized}.
* @author Craig Andrews
* @since 6.1.6
*/
public class NormalizedDef extends ConstraintDef<NormalizedDef, Normalized> {

public NormalizedDef() {
super( Normalized.class );
}

public NormalizedDef normalizationStrategy(Normalizer.Form form) {
addParameter( "normalizationForm", form );
return this;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
* Hibernate Validator, declare and validate application constraints
*
* License: Apache License, Version 2.0
* See the license.txt file in the root directory or <http://www.apache.org/licenses/LICENSE-2.0>.
*/
package org.hibernate.validator.constraints;

import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
import static java.lang.annotation.ElementType.CONSTRUCTOR;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.ElementType.TYPE_USE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

import java.lang.annotation.Documented;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import java.text.Normalizer;

import javax.validation.Constraint;
import javax.validation.Payload;

import org.hibernate.validator.constraints.Normalized.List;


/**
* Validate that a character sequence is of normalization form.
* <p>
* It is possible to validate a normalized value by setting the normalization strategy.
*
* @author Craig Andrews
* @since 6.1.6
*/
@Documented
@Constraint(validatedBy = { })
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
@Retention(RUNTIME)
@Repeatable(List.class)
public @interface Normalized {

Normalizer.Form form() default Normalizer.Form.NFC;

String message() default "{org.hibernate.validator.constraints.Normalized.message}";

Class<?>[] groups() default { };

Class<? extends Payload>[] payload() default { };

/**
* Defines several {@code @Normalized} annotations on the same element.
*/
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
@Retention(RUNTIME)
@Documented
public @interface List {
Normalized[] value();
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* Hibernate Validator, declare and validate application constraints
*
* License: Apache License, Version 2.0
* See the license.txt file in the root directory or <http://www.apache.org/licenses/LICENSE-2.0>.
*/
package org.hibernate.validator.internal.constraintvalidators.hv;

import java.text.Normalizer;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;

import org.hibernate.validator.constraints.Normalized;

/**
* Check that a character sequence is normalized.
*
* @author Craig Andrews
*/
public class NormalizedValidator implements ConstraintValidator<Normalized, CharSequence> {

private Normalizer.Form form;

@Override
public void initialize(Normalized parameters) {
form = parameters.form();
}

@Override
public boolean isValid(CharSequence value, ConstraintValidatorContext constraintValidatorContext) {
if ( value == null ) {
return true;
}
return Normalizer.isNormalized( value, form );
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ enum BuiltinConstraint {
ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_MOD10_CHECK("org.hibernate.validator.constraints.Mod10Check"),
ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_MOD11_CHECK("org.hibernate.validator.constraints.Mod11Check"),
ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_MOD_CHECK("org.hibernate.validator.constraints.ModCheck"),
ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_NORMALIZED("org.hibernate.validator.constraints.Normalized"),
ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_EAN("org.hibernate.validator.constraints.EAN", Arrays.asList( ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_MOD10_CHECK ) ),
ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_NOT_BLANK("org.hibernate.validator.constraints.NotBlank",
Arrays.asList( JAVAX_VALIDATION_CONSTRAINTS_NOT_NULL ) ),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_MOD10_CHECK;
import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_MOD11_CHECK;
import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_MOD_CHECK;
import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_NORMALIZED;
import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_NOT_BLANK;
import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_NOT_EMPTY;
import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_PARAMETER_SCRIPT_ASSERT;
Expand Down Expand Up @@ -114,6 +115,7 @@
import org.hibernate.validator.constraints.Mod10Check;
import org.hibernate.validator.constraints.Mod11Check;
import org.hibernate.validator.constraints.ModCheck;
import org.hibernate.validator.constraints.Normalized;
import org.hibernate.validator.constraints.ParameterScriptAssert;
import org.hibernate.validator.constraints.Range;
import org.hibernate.validator.constraints.SafeHtml;
Expand Down Expand Up @@ -331,6 +333,7 @@
import org.hibernate.validator.internal.constraintvalidators.hv.Mod10CheckValidator;
import org.hibernate.validator.internal.constraintvalidators.hv.Mod11CheckValidator;
import org.hibernate.validator.internal.constraintvalidators.hv.ModCheckValidator;
import org.hibernate.validator.internal.constraintvalidators.hv.NormalizedValidator;
import org.hibernate.validator.internal.constraintvalidators.hv.ParameterScriptAssertValidator;
import org.hibernate.validator.internal.constraintvalidators.hv.SafeHtmlValidator;
import org.hibernate.validator.internal.constraintvalidators.hv.ScriptAssertValidator;
Expand Down Expand Up @@ -776,6 +779,9 @@ private ConstraintHelper(Set<BuiltinConstraint> enabledBuiltinConstraints) {
if ( enabledBuiltinConstraints.contains( ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_MOD11_CHECK ) ) {
putBuiltinConstraint( tmpConstraints, Mod11Check.class, Mod11CheckValidator.class );
}
if ( enabledBuiltinConstraints.contains( ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_NORMALIZED ) ) {
putBuiltinConstraint( tmpConstraints, Normalized.class, NormalizedValidator.class );
}
if ( enabledBuiltinConstraints.contains( ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_PL_NIP ) ) {
putBuiltinConstraint( tmpConstraints, NIP.class, NIPValidator.class );
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ org.hibernate.validator.constraints.LuhnCheck.message = the check
org.hibernate.validator.constraints.Mod10Check.message = the check digit for ${validatedValue} is invalid, Modulo 10 checksum failed
org.hibernate.validator.constraints.Mod11Check.message = the check digit for ${validatedValue} is invalid, Modulo 11 checksum failed
org.hibernate.validator.constraints.ModCheck.message = the check digit for ${validatedValue} is invalid, {modType} checksum failed
org.hibernate.validator.constraints.Normalized.message = must be normalized
org.hibernate.validator.constraints.NotBlank.message = may not be empty
org.hibernate.validator.constraints.NotEmpty.message = may not be empty
org.hibernate.validator.constraints.ParametersScriptAssert.message = script expression "{script}" didn't evaluate to true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
import org.hibernate.validator.constraints.Mod10Check;
import org.hibernate.validator.constraints.Mod11Check;
import org.hibernate.validator.constraints.ModCheck;
import org.hibernate.validator.constraints.Normalized;
import org.hibernate.validator.constraints.ParameterScriptAssert;
import org.hibernate.validator.constraints.Range;
import org.hibernate.validator.constraints.SafeHtml;
Expand Down Expand Up @@ -157,6 +158,7 @@ public void testMessageProperties() throws NoSuchMethodException, SecurityExcept
violationOf( Mod10Check.class ),
violationOf( Mod11Check.class ),
violationOf( ModCheck.class ),
violationOf( Normalized.class ),
violationOf( org.hibernate.validator.constraints.NotBlank.class ),
violationOf( org.hibernate.validator.constraints.NotEmpty.class ),
violationOf( Range.class ),
Expand Down Expand Up @@ -308,6 +310,9 @@ private static class Bean {
@ModCheck(multiplier = 2, modType = ModCheck.ModType.MOD10)
private String modCheck = "4";

@Normalized(form = java.text.Normalizer.Form.NFKC)
private String normalized = "\uFE64script\uFE65";

@org.hibernate.validator.constraints.NotBlank
private String hvNotBlank = "";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
import org.hibernate.validator.constraints.Mod10Check;
import org.hibernate.validator.constraints.Mod11Check;
import org.hibernate.validator.constraints.ModCheck;
import org.hibernate.validator.constraints.Normalized;
import org.hibernate.validator.constraints.ParameterScriptAssert;
import org.hibernate.validator.constraints.Range;
import org.hibernate.validator.constraints.SafeHtml;
Expand Down Expand Up @@ -116,6 +117,7 @@ public void testConstraints() throws NoSuchMethodException, SecurityException {
testConstraint( Mod10Check.class, new Mod10CheckBean() );
testConstraint( Mod11Check.class, new Mod11CheckBean() );
testConstraint( ModCheck.class, new ModCheckBean() );
testConstraint( Normalized.class, new NormalizedBean() );
testConstraint( org.hibernate.validator.constraints.NotBlank.class, new HvNotBlankBean() );
testConstraint( org.hibernate.validator.constraints.NotEmpty.class, new HvNotEmptyBean() );
testConstraint( Range.class, new RangeBean() );
Expand Down Expand Up @@ -356,6 +358,13 @@ private static class ModCheckBean {
private String modCheck = "4";
}

private static class NormalizedBean {

@Normalized(form = java.text.Normalizer.Form.NFKC)
private String normalized = "\uFE64script\uFE65";

}

private static class HvNotBlankBean {

@org.hibernate.validator.constraints.NotBlank
Expand Down
Loading

0 comments on commit 423ecc1

Please sign in to comment.