From 9b77a045822cd888d545c308e18118dfabd4e7ec Mon Sep 17 00:00:00 2001 From: Gavin King Date: Mon, 20 Jan 2025 12:09:07 +0100 Subject: [PATCH] finish off javadoc for Restriction and Range --- .../java/org/hibernate/query/range/Range.java | 101 +++++++++++ .../query/restriction/Restriction.java | 166 ++++++++++++++++++ 2 files changed, 267 insertions(+) diff --git a/hibernate-core/src/main/java/org/hibernate/query/range/Range.java b/hibernate-core/src/main/java/org/hibernate/query/range/Range.java index 8d9f1b300975..d0dbb56a6b26 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/range/Range.java +++ b/hibernate-core/src/main/java/org/hibernate/query/range/Range.java @@ -22,6 +22,7 @@ * @param The type of the value being restricted * * @see org.hibernate.query.restriction.Restriction + * @see org.hibernate.query.restriction.Restriction#restrict(jakarta.persistence.metamodel.SingularAttribute, Range) * * @author Gavin King * @@ -30,6 +31,9 @@ @Incubating public interface Range { + /** + * The Java class of the values belonging to this range. + */ Class getType(); /** @@ -40,92 +44,189 @@ public interface Range { @Internal Predicate toPredicate(Path path, CriteriaBuilder builder); + /** + * A range containing a single value. + */ static Range singleValue(U value) { return new Value<>( value ); } + /** + * A range containing all strings which are equal to the given string, + * ignoring case. + */ static Range singleCaseInsensitiveValue(String value) { return new CaseInsensitiveValue( value ); } + /** + * A range containing all values belonging to the given list. + */ static Range valueList(List values) { return new ValueList<>( values ); } + /** + * A range containing all values strictly greater than the given + * lower bound. + */ static > Range greaterThan(U bound) { return new LowerBound<>( bound, true ); } + /** + * A range containing all values greater than or equal to the given + * lower bound. + */ static > Range greaterThanOrEqualTo(U bound) { return new LowerBound<>( bound, false ); } + /** + * A range containing all values strictly less than the given + * upper bound. + */ static > Range lessThan(U bound) { return new UpperBound<>( bound, true ); } + /** + * A range containing all values less than or equal to the given + * upper bound. + */ static > Range lessThanOrEqualTo(U bound) { return new UpperBound<>( bound, false ); } + /** + * An open range containing all values strictly greater than the + * given lower bound, and strictly less than the given upper bound. + */ static > Range open(U lowerBound, U upperBound) { return new Interval<>( new LowerBound<>( lowerBound, true ), new UpperBound<>( upperBound, true ) ); } + /** + * A closed range containing all values greater than or equal to the + * given lower bound, and less than or equal to the given upper bound. + */ static > Range closed(U lowerBound, U upperBound) { return new Interval<>( new LowerBound<>( lowerBound, false ), new UpperBound<>( upperBound, false ) ); } + /** + * A range containing all strings which match the given pattern, + * with case-sensitivity specified explicitly. The pattern must + * be expressed in terms of the default wildcard characters + * {@code _} and {@code %}. + * + * @param pattern A pattern involving the default wildcard characters + * @param caseSensitive {@code true} if matching is case-sensitive + */ static Range pattern(String pattern, boolean caseSensitive) { return new Pattern( pattern, caseSensitive ); } + /** + * A range containing all strings which match the given pattern, + * with case-sensitivity specified explicitly. The pattern must + * be expressed in terms of the given single-character and + * multi-character wildcards. + * + * @param pattern A pattern involving the given wildcard characters + * @param caseSensitive {@code true} if matching is case-sensitive + * @param charWildcard A wildcard character which matches any single character + * @param stringWildcard A wildcard character which matches any string of characters + */ static Range pattern(String pattern, boolean caseSensitive, char charWildcard, char stringWildcard) { return new Pattern( pattern, caseSensitive, charWildcard, stringWildcard ); } + /** + * A range containing all strings which match the given pattern, + * with case-sensitivity. The pattern must be expressed in terms + * of the default wildcard characters {@code _} and {@code %}. + */ static Range pattern(String pattern) { return pattern( pattern, true ); } + /** + * A range containing all strings which begin with the given prefix, + * with case-sensitivity specified explicitly. + */ static Range prefix(String prefix, boolean caseSensitive) { return pattern( escape( prefix ) + '%', caseSensitive ); } + /** + * A range containing all strings which end with the given suffix, + * with case-sensitivity specified explicitly. + */ static Range suffix(String suffix, boolean caseSensitive) { return pattern( '%' + escape( suffix ), caseSensitive ); } + /** + * A range containing all strings which contain the given substring, + * with case-sensitivity specified explicitly. + */ static Range containing(String substring, boolean caseSensitive) { return pattern( '%' + escape( substring ) + '%', caseSensitive ); } + /** + * A range containing all strings which begin with the given prefix, + * with case-sensitivity. + */ static Range prefix(String prefix) { return prefix( prefix, true ); } + /** + * A range containing all strings which end with the given suffix, + * with case-sensitivity. + */ static Range suffix(String suffix) { return pattern( suffix, true ); } + /** + * A range containing all strings which contain the given substring, + * with case-sensitivity. + */ static Range containing(String substring) { return pattern( substring, true ); } + /** + * An empty range containing no values. + */ static Range empty(Class type) { return new EmptyRange<>( type ); } + /** + * A complete range containing all values of the given type. + */ static Range full(Class type) { return new FullRange<>( type ); } + /** + * A range containing all allowed values of the given type + * except {@code null}. + */ static Range notNull(Class type) { return new NotNull<>( type ); } + /** + * Escape occurrences of the default wildcard characters in the + * given literal string. + */ private static String escape(String literal) { final var result = new StringBuilder(); for ( int i = 0; i < literal.length(); i++ ) { diff --git a/hibernate-core/src/main/java/org/hibernate/query/restriction/Restriction.java b/hibernate-core/src/main/java/org/hibernate/query/restriction/Restriction.java index ce78e274c18d..a5ec44ca7b21 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/restriction/Restriction.java +++ b/hibernate-core/src/main/java/org/hibernate/query/restriction/Restriction.java @@ -64,10 +64,20 @@ public interface Restriction { */ Restriction negated(); + /** + * Combine this restriction with the given restriction using logical or. + * + * @see #any(List) + */ default Restriction or(Restriction restriction) { return any( this, restriction ); } + /** + * Combine this restriction with the given restriction using logical and. + * + * @see #all(List) + */ default Restriction and(Restriction restriction) { return all( this, restriction ); } @@ -109,60 +119,128 @@ static Restriction restrict(Class type, String attributeName, Range return new NamedAttributeRange<>( type, attributeName, range ); } + /** + * Restrict the given attribute to be exactly equal to the given value. + * + * @see Range#singleValue(Object) + */ static Restriction equal(SingularAttribute attribute, U value) { return restrict( attribute, Range.singleValue( value ) ); } + /** + * Restrict the given attribute to be not equal to the given value. + */ static Restriction unequal(SingularAttribute attribute, U value) { return equal( attribute, value ).negated(); } + /** + * Restrict the given attribute to be equal to the given string, ignoring case. + * + * @see Range#singleCaseInsensitiveValue(String) + */ static Restriction equalIgnoringCase(SingularAttribute attribute, String value) { return restrict( attribute, Range.singleCaseInsensitiveValue( value ) ); } + /** + * Restrict the given attribute to be exactly equal to one of the given values. + * + * @see Range#valueList(List) + */ @SafeVarargs static Restriction in(SingularAttribute attribute, U... values) { return in( attribute, List.of(values ) ); } + /** + * Restrict the given attribute to be not equal to any of the given values. + */ @SafeVarargs static Restriction notIn(SingularAttribute attribute, U... values) { return notIn( attribute, List.of(values ) ); } + /** + * Restrict the given attribute to be exactly equal to one of the given values. + * + * @see Range#valueList(List) + */ static Restriction in(SingularAttribute attribute, java.util.List values) { return restrict( attribute, Range.valueList( values ) ); } + /** + * Restrict the given attribute to be not equal to any of the given values. + */ static Restriction notIn(SingularAttribute attribute, java.util.List values) { return in( attribute, values ).negated(); } + /** + * Restrict the given attribute to fall between the given values. + * + * @see Range#closed(Comparable, Comparable) + */ static > Restriction between(SingularAttribute attribute, U lowerBound, U upperBound) { return restrict( attribute, Range.closed( lowerBound, upperBound ) ); } + /** + * Restrict the given attribute to not fall between the given values. + */ static > Restriction notBetween(SingularAttribute attribute, U lowerBound, U upperBound) { return between( attribute, lowerBound, upperBound ).negated(); } + /** + * Restrict the given attribute to be strictly greater than the given lower bound. + * + * @see Range#greaterThan(Comparable) + */ static > Restriction greaterThan(SingularAttribute attribute, U lowerBound) { return restrict( attribute, Range.greaterThan( lowerBound ) ); } + /** + * Restrict the given attribute to be strictly less than the given upper bound. + * + * @see Range#lessThan(Comparable) + */ static > Restriction lessThan(SingularAttribute attribute, U upperBound) { return restrict( attribute, Range.lessThan( upperBound ) ); } + /** + * Restrict the given attribute to be greater than or equal to the given lower bound. + * + * @see Range#greaterThanOrEqualTo(Comparable) + */ static > Restriction greaterThanOrEqual(SingularAttribute attribute, U lowerBound) { return restrict( attribute, Range.greaterThanOrEqualTo( lowerBound ) ); } + /** + * Restrict the given attribute to be less than or equal to the given upper bound. + * + * @see Range#lessThanOrEqualTo(Comparable) + */ static > Restriction lessThanOrEqual(SingularAttribute attribute, U upperBound) { return restrict( attribute, Range.lessThanOrEqualTo( upperBound ) ); } + /** + * Restrict the given attribute to match the given pattern, explicitly specifying + * case sensitivity, along with single-character and multi-character wildcards. + * + * @param pattern A pattern involving the given wildcard characters + * @param caseSensitive {@code true} if matching is case-sensitive + * @param charWildcard A wildcard character which matches any single character + * @param stringWildcard A wildcard character which matches any string of characters + * + * @see Range#pattern(String, boolean, char, char) + */ static Restriction like( SingularAttribute attribute, String pattern, boolean caseSensitive, @@ -170,76 +248,164 @@ static Restriction like( return restrict( attribute, Range.pattern( pattern, caseSensitive, charWildcard, stringWildcard ) ); } + /** + * Restrict the given attribute to match the given pattern, explicitly specifying + * case sensitivity. The pattern must be expressed in terms of the default wildcard + * characters {@code _} and {@code %}. + * + * @param pattern A pattern involving the default wildcard characters + * @param caseSensitive {@code true} if matching is case-sensitive + * + * @see Range#pattern(String, boolean) + */ static Restriction like(SingularAttribute attribute, String pattern, boolean caseSensitive) { return restrict( attribute, Range.pattern( pattern, caseSensitive ) ); } + /** + * Restrict the given attribute to match the given pattern. The pattern must be + * expressed in terms of the default wildcard characters {@code _} and {@code %}. + * + * @see Range#pattern(String) + */ static Restriction like(SingularAttribute attribute, String pattern) { return like( attribute, pattern, true ); } + /** + * Restrict the given attribute to not match the given pattern. The pattern must + * be expressed in terms of the default wildcard characters {@code _} and {@code %}. + * + * @see Range#pattern(String) + */ static Restriction notLike(SingularAttribute attribute, String pattern) { return like( attribute, pattern, true ).negated(); } + /** + * Restrict the given attribute to not match the given pattern, explicitly specifying + * case sensitivity. The pattern must be expressed in terms of the default wildcard + * characters {@code _} and {@code %}. + * + * @param pattern A pattern involving the default wildcard characters + * @param caseSensitive {@code true} if matching is case-sensitive + */ static Restriction notLike(SingularAttribute attribute, String pattern, boolean caseSensitive) { return like( attribute, pattern, caseSensitive ).negated(); } + /** + * Restrict the given attribute to start with the given string prefix. + * + * @see Range#prefix(String) + */ static Restriction startsWith(SingularAttribute attribute, String prefix) { return startsWith( attribute, prefix, true ); } + /** + * Restrict the given attribute to end with the given string suffix. + * + * @see Range#suffix(String) + */ static Restriction endsWith(SingularAttribute attribute, String suffix) { return endsWith( attribute, suffix, true ); } + /** + * Restrict the given attribute to contain the given substring. + * + * @see Range#containing(String) + */ static Restriction contains(SingularAttribute attribute, String substring) { return contains( attribute, substring, true ); } + /** + * Restrict the given attribute to not contain the given substring. + */ static Restriction notContains(SingularAttribute attribute, String substring) { return notContains( attribute, substring, true ); } + /** + * Restrict the given attribute to start with the given string prefix, explicitly + * specifying case sensitivity. + * + * @see Range#prefix(String, boolean) + */ static Restriction startsWith(SingularAttribute attribute, String prefix, boolean caseSensitive) { return restrict( attribute, Range.prefix( prefix, caseSensitive ) ); } + /** + * Restrict the given attribute to end with the given string suffix, explicitly + * specifying case sensitivity. + * + * @see Range#suffix(String, boolean) + */ static Restriction endsWith(SingularAttribute attribute, String suffix, boolean caseSensitive) { return restrict( attribute, Range.suffix( suffix, caseSensitive ) ); } + /** + * Restrict the given attribute to contain the given substring, explicitly + * specifying case sensitivity. + * + * @see Range#containing(String, boolean) + */ static Restriction contains(SingularAttribute attribute, String substring, boolean caseSensitive) { return restrict( attribute, Range.containing( substring, caseSensitive ) ); } + /** + * Restrict the given attribute to not contain the given substring, explicitly + * specifying case sensitivity. + */ static Restriction notContains(SingularAttribute attribute, String substring, boolean caseSensitive) { return contains( attribute, substring, caseSensitive ).negated(); } + /** + * Restrict the given attribute to be non-null. + */ static Restriction notNull(SingularAttribute attribute) { return restrict( attribute, Range.notNull( attribute.getJavaType() ) ); } + /** + * Combine the given restrictions using logical and. + */ static Restriction all(List> restrictions) { return new Conjunction<>( restrictions ); } + /** + * Combine the given restrictions using logical or. + */ static Restriction any(List> restrictions) { return new Disjunction<>( restrictions ); } + /** + * Combine the given restrictions using logical and. + */ @SafeVarargs static Restriction all(Restriction... restrictions) { return new Conjunction( java.util.List.of( restrictions ) ); } + /** + * Combine the given restrictions using logical or. + */ @SafeVarargs static Restriction any(Restriction... restrictions) { return new Disjunction( java.util.List.of( restrictions ) ); } + /** + * An empty restriction. + */ static Restriction unrestricted() { return new Unrestricted<>(); }