/** * Creates a new {@link SortModifier} instance given {@link Sort}. * * @param sort must not be {@literal null}. */ SortModifier(Sort sort) { Assert.notNull(sort, "Sort must not be null!"); for (Order order : sort) { if (order.isIgnoreCase()) { throw new IllegalArgumentException(String.format("Given sort contained an Order for %s with ignore case! " + "MongoDB does not support sorting ignoring case currently!", order.getProperty())); } } this.sort = sort; }
/** * Returns the order clause for the given {@link Order}. Will prefix the clause with the given alias if the referenced * property refers to a join alias, i.e. starts with {@code $alias.}. * * @param joinAliases the join aliases of the original query. Must not be {@literal null}. * @param alias the alias for the root entity. May be {@literal null}. * @param order the order object to build the clause for. Must not be {@literal null}. * @return a String containing a order clause. Guaranteed to be not {@literal null}. */ private static String getOrderClause(Set<String> joinAliases, Set<String> functionAlias, @Nullable String alias, Order order) { String property = order.getProperty(); checkSortExpression(order); if (functionAlias.contains(property)) { return String.format("%s %s", property, toJpaDirection(order)); } boolean qualifyReference = !property.contains("("); // ( indicates a function for (String joinAlias : joinAliases) { if (property.startsWith(joinAlias.concat("."))) { qualifyReference = false; break; } } String reference = qualifyReference && StringUtils.hasText(alias) ? String.format("%s.%s", alias, property) : property; String wrapped = order.isIgnoreCase() ? String.format("lower(%s)", reference) : reference; return String.format("%s %s", wrapped, toJpaDirection(order)); }
/** * Creates an {@link Expression} for the given {@link Order} property. * * @param order must not be {@literal null}. * @return */ private Expression<?> buildOrderPropertyPathFrom(Order order) { Assert.notNull(order, "Order must not be null!"); PropertyPath path = PropertyPath.from(order.getProperty(), builder.getType()); Expression<?> sortPropertyExpression = builder; while (path != null) { if (!path.hasNext() && order.isIgnoreCase()) { // if order is ignore-case we have to treat the last path segment as a String. sortPropertyExpression = Expressions.stringPath((Path<?>) sortPropertyExpression, path.getSegment()).lower(); } else { sortPropertyExpression = Expressions.path(path.getType(), (Path<?>) sortPropertyExpression, path.getSegment()); } path = path.next(); } return sortPropertyExpression; } }
/** * Creates an {@link Expression} for the given {@link Order} property. * * @param order must not be {@literal null}. * @param builder must not be {@literal null}. * @return */ private static Expression<?> buildOrderPropertyPathFrom(Order order, PathBuilder<?> builder) { Assert.notNull(order, "Order must not be null!"); Assert.notNull(builder, "Builder must not be null!"); PropertyPath path = PropertyPath.from(order.getProperty(), builder.getType()); Expression<?> sortPropertyExpression = builder; while (path != null) { if (!path.hasNext() && order.isIgnoreCase()) { // if order is ignore-case we have to treat the last path segment as a String. sortPropertyExpression = Expressions.stringPath((Path<?>) sortPropertyExpression, path.getSegment()).lower(); } else { sortPropertyExpression = Expressions.path(path.getType(), (Path<?>) sortPropertyExpression, path.getSegment()); } path = path.next(); } return sortPropertyExpression; }
/** * Creates an {@link Expression} for the given {@link Order} property. * * @param order must not be {@literal null}. * @param builder must not be {@literal null}. * @return */ private static Expression<?> buildOrderPropertyPathFrom(Order order, PathBuilder<?> builder) { Assert.notNull(order, "Order must not be null!"); Assert.notNull(builder, "Builder must not be null!"); PropertyPath path = PropertyPath.from(order.getProperty(), builder.getType()); Expression<?> sortPropertyExpression = builder; while (path != null) { if (!path.hasNext() && order.isIgnoreCase()) { // if order is ignore-case we have to treat the last path segment as a String. sortPropertyExpression = Expressions.stringPath((Path<?>) sortPropertyExpression, path.getSegment()).lower(); } else { sortPropertyExpression = Expressions.path(path.getType(), (Path<?>) sortPropertyExpression, path.getSegment()); } path = path.next(); } return sortPropertyExpression; }
/** * @param sort * @return */ public Query<?> with(Sort sort) { if (sort == null) { return this; } for (Order order : sort) { if (order.isIgnoreCase()) { throw new IllegalArgumentException(String.format( "Given sort contained an Order for %s with ignore case! " + "Aerospike does not support sorting ignoreing case currently!", order.getProperty())); } } if (this.sort == null) { this.sort = sort; } else { this.sort = this.sort.and(sort); } return this; }
/** * Creates an {@link Expression} for the given {@link Order} property. * * @param order must not be {@literal null}. * @return */ private Expression<?> buildOrderPropertyPathFrom(Order order) { Assert.notNull(order, "Order must not be null!"); PropertyPath path = PropertyPath.from(order.getProperty(), builder.getType()); Expression<?> sortPropertyExpression = builder; while (path != null) { if (!path.hasNext() && order.isIgnoreCase()) { // if order is ignore-case we have to treat the last path segment as a String. sortPropertyExpression = Expressions.stringPath((Path<?>) sortPropertyExpression, path.getSegment()).lower(); } else { sortPropertyExpression = Expressions.path(path.getType(), (Path<?>) sortPropertyExpression, path.getSegment()); } path = path.next(); } return sortPropertyExpression; } }
/** * Add a {@link Sort} to the {@link Query} instance. * * @param sort must not be {@literal null}. * @return a new {@link Query} object containing the former settings with {@link Sort} applied. */ public Query sort(Sort sort) { Assert.notNull(sort, "Sort must not be null"); for (Order order : sort) { if (order.isIgnoreCase()) { throw new IllegalArgumentException(String.format("Given sort contained an Order for %s with ignore case;" + " Apache Cassandra does not support sorting ignoring case currently", order.getProperty())); } } return new Query(this.criteriaDefinitions, this.columns, this.sort.and(sort), this.pagingState, this.queryOptions, this.limit, this.allowFiltering); }
/** * Creates a criteria API {@link javax.persistence.criteria.Order} from the given {@link Order}. * * @param order the order to transform into a JPA {@link javax.persistence.criteria.Order} * @param from the {@link From} the {@link Order} expression is based on * @param cb the {@link CriteriaBuilder} to build the {@link javax.persistence.criteria.Order} with * @return */ @SuppressWarnings("unchecked") private static javax.persistence.criteria.Order toJpaOrder(Order order, From<?, ?> from, CriteriaBuilder cb) { PropertyPath property = PropertyPath.from(order.getProperty(), from.getJavaType()); Expression<?> expression = toExpressionRecursively(from, property); if (order.isIgnoreCase() && String.class.equals(expression.getJavaType())) { Expression<String> lower = cb.lower((Expression<String>) expression); return order.isAscending() ? cb.asc(lower) : cb.desc(lower); } else { return order.isAscending() ? cb.asc(expression) : cb.desc(expression); } }
/** * Transforms a {@code Sort.Order} object into a comparator item. * * @param sortOrder * the {@code Sort.Order} object * @return the comparator item */ public static ComparatorItem fromSortOrder(Sort.Order sortOrder) { if (sortOrder == null || sortOrder.getProperty() == null || sortOrder.getProperty().trim().length() == 0) { return null; } boolean nullIsFirst = Sort.NullHandling.NULLS_FIRST.equals(sortOrder.getNullHandling()); return new ComparatorItem(sortOrder.getProperty(), sortOrder.isAscending(), sortOrder.isIgnoreCase(), nullIsFirst); }
public static StringBuilder applySort(Sort sort, StringBuilder sql, Function<Order, String> sortedPropertyNameFunction) { if (sort == null || sort.isUnsorted()) { return sql; } sql.append(" ORDER BY "); StringJoiner sj = new StringJoiner(" , "); sort.iterator().forEachRemaining((o) -> { String sortedPropertyName = sortedPropertyNameFunction.apply(o); String sortedProperty = o.isIgnoreCase() ? "LOWER(" + sortedPropertyName + ")" : sortedPropertyName; sj.add(sortedProperty + (o.isAscending() ? " ASC" : " DESC")); }); return sql.append(sj); }
private static StructuredQuery.OrderBy createOrderBy(DatastorePersistentEntity<?> persistentEntity, Sort.Order order) { if (order.isIgnoreCase()) { throw new DatastoreDataException("Datastore doesn't support sorting ignoring case"); } if (!order.getNullHandling().equals(Sort.NullHandling.NATIVE)) { throw new DatastoreDataException("Datastore supports only NullHandling.NATIVE null handling"); } return new StructuredQuery.OrderBy( persistentEntity.getPersistentProperty(order.getProperty()).getFieldName(), (order.getDirection() == Sort.Direction.DESC) ? StructuredQuery.OrderBy.Direction.DESCENDING : StructuredQuery.OrderBy.Direction.ASCENDING); }
private static StructuredQuery.OrderBy createOrderBy(DatastorePersistentEntity<?> persistentEntity, Sort.Order order) { if (order.isIgnoreCase()) { throw new DatastoreDataException("Datastore doesn't support sorting ignoring case"); } if (!order.getNullHandling().equals(Sort.NullHandling.NATIVE)) { throw new DatastoreDataException("Datastore supports only NullHandling.NATIVE null handling"); } return new StructuredQuery.OrderBy( persistentEntity.getPersistentProperty(order.getProperty()).getFieldName(), (order.getDirection() == Sort.Direction.DESC) ? StructuredQuery.OrderBy.Direction.DESCENDING : StructuredQuery.OrderBy.Direction.ASCENDING); }
@Override public boolean isIgnoreCase() { return super.isIgnoreCase() || ignoreCase; }
private static String getOrderClause(Sort.Order order) { String property = order.getProperty(); String wrapped = order.isIgnoreCase() ? String.format("lower(%s)", property) : property; return String.format("%s %s", wrapped, toSqlDirection(order)); }
private String getParameter(@NonNull Sort.Order order) { Assert.isTrue(!order.isIgnoreCase(), "Ignore case is not supported"); final String direction = order.isDescending() ? "DESC" : "ASC"; return String.format("r.%s %s", order.getProperty(), direction); }
public static StringBuilder applySort(Sort sort, StringBuilder sql, Function<Order, String> sortedPropertyNameFunction) { if (sort == null || sort.isUnsorted()) { return sql; } sql.append(" ORDER BY "); StringJoiner sj = new StringJoiner(" , "); sort.iterator().forEachRemaining((o) -> { String sortedPropertyName = sortedPropertyNameFunction.apply(o); String sortedProperty = o.isIgnoreCase() ? "LOWER(" + sortedPropertyName + ")" : sortedPropertyName; sj.add(sortedProperty + (o.isAscending() ? " ASC" : " DESC")); }); return sql.append(sj); }
/** * Creates a new {@link SortModifier} instance given {@link Sort}. * * @param sort must not be {@literal null}. */ SortModifier(Sort sort) { Assert.notNull(sort, "Sort must not be null!"); for (Order order : sort) { if (order.isIgnoreCase()) { throw new IllegalArgumentException(String.format("Given sort contained an Order for %s with ignore case! " + "MongoDB does not support sorting ignoring case currently!", order.getProperty())); } } this.sort = sort; }
/** * Creates a criteria API {@link javax.persistence.criteria.Order} from the given {@link Order}. * * @param order the order to transform into a JPA {@link javax.persistence.criteria.Order} * @param from the {@link From} the {@link Order} expression is based on * @param cb the {@link CriteriaBuilder} to build the {@link javax.persistence.criteria.Order} with * @return */ @SuppressWarnings("unchecked") private static javax.persistence.criteria.Order toJpaOrder(Order order, From<?, ?> from, CriteriaBuilder cb) { PropertyPath property = PropertyPath.from(order.getProperty(), from.getJavaType()); Expression<?> expression = toExpressionRecursively(from, property); if (order.isIgnoreCase() && String.class.equals(expression.getJavaType())) { Expression<String> lower = cb.lower((Expression<String>) expression); return order.isAscending() ? cb.asc(lower) : cb.desc(lower); } else { return order.isAscending() ? cb.asc(expression) : cb.desc(expression); } }
@Override public boolean isIgnoreCase() { return super.isIgnoreCase() || ignoreCase; }