HHH-17773 review and improve API of Order class

This commit is contained in:
Gavin King 2024-03-12 22:29:54 +01:00
parent 237e339e2c
commit 276a93e95e
1 changed files with 152 additions and 6 deletions

View File

@ -13,6 +13,8 @@ import java.util.List;
import java.util.Objects;
import static java.util.stream.Collectors.toList;
import static org.hibernate.query.SortDirection.ASCENDING;
import static org.hibernate.query.SortDirection.DESCENDING;
/**
* A rule for sorting a query result set.
@ -96,6 +98,16 @@ public class Order<X> {
this.ignoreCase = ignoreCase;
}
private Order(SortDirection order, NullPrecedence nullPrecedence, int element, boolean ignoreCase) {
this.order = order;
this.entityClass = null;
this.attributeName = null;
this.attribute = null;
this.nullPrecedence = nullPrecedence;
this.element = element;
this.ignoreCase = ignoreCase;
}
private Order(Order<X> other, SortDirection order) {
this.order = order;
this.attribute = other.attribute;
@ -106,58 +118,163 @@ public class Order<X> {
this.ignoreCase = other.ignoreCase;
}
private Order(Order<X> other, boolean ignoreCase) {
this.order = other.order;
this.attribute = other.attribute;
this.entityClass = other.entityClass;
this.attributeName = other.attributeName;
this.nullPrecedence = other.nullPrecedence;
this.element = other.element;
this.ignoreCase = ignoreCase;
}
private Order(Order<X> other, NullPrecedence nullPrecedence) {
this.order = other.order;
this.attribute = other.attribute;
this.entityClass = other.entityClass;
this.attributeName = other.attributeName;
this.nullPrecedence = nullPrecedence;
this.element = other.element;
this.ignoreCase = other.ignoreCase;
}
/**
* An order where an entity is sorted by the given attribute,
* with smaller values first. If the give attribute is of textual
* type, the ordering is case-sensitive.
*/
public static <T> Order<T> asc(SingularAttribute<T,?> attribute) {
return new Order<>(SortDirection.ASCENDING, NullPrecedence.NONE, attribute);
return new Order<>(ASCENDING, NullPrecedence.NONE, attribute);
}
/**
* An order where an entity is sorted by the given attribute,
* with larger values first. If the give attribute is of textual
* type, the ordering is case-sensitive.
*/
public static <T> Order<T> desc(SingularAttribute<T,?> attribute) {
return new Order<>(SortDirection.DESCENDING, NullPrecedence.NONE, attribute);
return new Order<>(DESCENDING, NullPrecedence.NONE, attribute);
}
/**
* An order where an entity is sorted by the given attribute,
* in the given direction. If the give attribute is of textual
* type, the ordering is case-sensitive.
*/
public static <T> Order<T> by(SingularAttribute<T,?> attribute, SortDirection direction) {
return new Order<>(direction, NullPrecedence.NONE, attribute);
}
/**
* An order where an entity is sorted by the given attribute,
* in the given direction, with the specified case-sensitivity.
*/
public static <T> Order<T> by(SingularAttribute<T,?> attribute, SortDirection direction, boolean ignoreCase) {
return new Order<>(direction, NullPrecedence.NONE, attribute, ignoreCase);
}
/**
* An order where an entity is sorted by the given attribute,
* in the given direction, with the specified precedence for
* null values. If the give attribute is of textual type, the
* ordering is case-sensitive.
*/
public static <T> Order<T> by(SingularAttribute<T,?> attribute, SortDirection direction, NullPrecedence nullPrecedence) {
return new Order<>(direction, nullPrecedence, attribute);
}
/**
* An order where an entity of the given class is sorted by the
* attribute with the given name, with smaller values first. If
* the named attribute is of textual type, the ordering is
* case-sensitive.
*/
public static <T> Order<T> asc(Class<T> entityClass, String attributeName) {
return new Order<>( SortDirection.ASCENDING, NullPrecedence.NONE, entityClass, attributeName );
return new Order<>( ASCENDING, NullPrecedence.NONE, entityClass, attributeName );
}
/**
* An order where an entity of the given class is sorted by the
* attribute with the given name, with larger values first. If
* the named attribute is of textual type, the ordering is
* case-sensitive.
*/
public static <T> Order<T> desc(Class<T> entityClass, String attributeName) {
return new Order<>( SortDirection.DESCENDING, NullPrecedence.NONE, entityClass, attributeName );
return new Order<>( DESCENDING, NullPrecedence.NONE, entityClass, attributeName );
}
/**
* An order where an entity of the given class is sorted by the
* attribute with the given name, in the given direction. If the
* named attribute is of textual type, the ordering is
* case-sensitive.
*/
public static <T> Order<T> by(Class<T> entityClass, String attributeName, SortDirection direction) {
return new Order<>( direction, NullPrecedence.NONE, entityClass, attributeName );
}
/**
* An order where an entity of the given class is sorted by the
* attribute with the given name, in the given direction, with
* the specified case-sensitivity.
*/
public static <T> Order<T> by(Class<T> entityClass, String attributeName, SortDirection direction, boolean ignoreCase) {
return new Order<>( direction, NullPrecedence.NONE, entityClass, attributeName, ignoreCase );
}
/**
* An order where an entity of the given class is sorted by the
* attribute with the given name, in the given direction. If the
* named attribute is of textual type, with the specified
* precedence for null values. If the named attribute is of
* textual type, the ordering is case-sensitive.
*/
public static <T> Order<T> by(Class<T> entityClass, String attributeName, SortDirection direction, NullPrecedence nullPrecedence) {
return new Order<>( direction, nullPrecedence, entityClass, attributeName );
}
/**
* An order where the result set is sorted by the select item
* in the given position with smaller values first. If the
* item is of textual type, the ordering is case-sensitive.
*/
public static Order<Object[]> asc(int element) {
return new Order<>( SortDirection.ASCENDING, NullPrecedence.NONE, element );
return new Order<>( ASCENDING, NullPrecedence.NONE, element );
}
/**
* An order where the result set is sorted by the select item
* in the given position with larger values first. If the
* item is of textual type, the ordering is case-sensitive.
*/
public static Order<Object[]> desc(int element) {
return new Order<>( SortDirection.DESCENDING, NullPrecedence.NONE, element );
return new Order<>( DESCENDING, NullPrecedence.NONE, element );
}
/**
* An order where the result set is sorted by the select item
* in the given position, in the given direction. If the item
* is of textual type, the ordering is case-sensitive.
*/
public static Order<Object[]> by(int element, SortDirection direction) {
return new Order<>( direction, NullPrecedence.NONE, element );
}
/**
* An order where the result set is sorted by the select item
* in the given position in the given direction, with the specified
* case-sensitivity.
*/
public static Order<Object[]> by(int element, SortDirection direction, boolean ignoreCase) {
return new Order<>( direction, NullPrecedence.NONE, element, ignoreCase );
}
/**
* An order where the result set is sorted by the select item
* in the given position in the given direction, with the specified
* precedence for null values. If the named attribute is of
* textual type, the ordering is case-sensitive.
*/
public static Order<Object[]> by(int element, SortDirection direction, NullPrecedence nullPrecedence) {
return new Order<>( direction, nullPrecedence, element );
}
@ -190,10 +307,38 @@ public class Order<X> {
return element;
}
/**
* @return this order, but with the sorting direction reversed.
* @since 6.5
*/
public Order<X> reverse() {
return new Order<>( this, order.reverse() );
}
/**
* @return this order, but without case-sensitivity.
* @since 6.5
*/
public Order<X> ignoringCase() {
return new Order<>( this, true );
}
/**
* @return this order, but with nulls sorted first.
* @since 6.5
*/
public Order<X> withNullsFirst() {
return new Order<>( this, NullPrecedence.FIRST );
}
/**
* @return this order, but with nulls sorted last.
* @since 6.5
*/
public Order<X> withNullsLast() {
return new Order<>( this, NullPrecedence.LAST );
}
@Override
public String toString() {
return attributeName + " " + order;
@ -205,6 +350,7 @@ public class Order<X> {
Order<?> that = (Order<?>) o;
return that.order == this.order
&& that.nullPrecedence == this.nullPrecedence
&& that.ignoreCase == this.ignoreCase
&& that.element == this.element
&& Objects.equals( that.attributeName, this.attributeName )
&& Objects.equals( that.entityClass, this.entityClass );