From bff8caba755233bbfbf2e291acfbca213ec8cd3e Mon Sep 17 00:00:00 2001 From: Oliver Gierke Date: Wed, 4 Feb 2015 12:06:58 +0100 Subject: [PATCH] DATACMNS-641 - Order clauses in derived repository clauses now default to ascending order. OrderBySource now considers the Asc and Desc keywords in an OrderBy-clause optional defaulting to ascending order as Sort defaults to anyway. --- .../query/parser/OrderBySource.java | 30 ++++++++++++++----- .../query/parser/OrderBySourceUnitTests.java | 11 ++++++- 2 files changed, 33 insertions(+), 8 deletions(-) diff --git a/src/main/java/org/springframework/data/repository/query/parser/OrderBySource.java b/src/main/java/org/springframework/data/repository/query/parser/OrderBySource.java index 5c03c898d..c4715f891 100644 --- a/src/main/java/org/springframework/data/repository/query/parser/OrderBySource.java +++ b/src/main/java/org/springframework/data/repository/query/parser/OrderBySource.java @@ -1,5 +1,5 @@ /* - * Copyright 2008-2012 the original author or authors. + * Copyright 2008-2015 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,7 +16,10 @@ package org.springframework.data.repository.query.parser; import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; import java.util.List; +import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -36,7 +39,9 @@ import org.springframework.util.StringUtils; public class OrderBySource { private static final String BLOCK_SPLIT = "(?<=Asc|Desc)(?=\\p{Lu})"; - private static final Pattern DIRECTION_SPLIT = Pattern.compile("(.+)(Asc|Desc)$"); + private static final Pattern DIRECTION_SPLIT = Pattern.compile("(.+?)(Asc|Desc)?$"); + private static final String INVALID_ORDER_SYNTAX = "Invalid order syntax for part %s!"; + private static final Set DIRECTION_KEYWORDS = new HashSet(Arrays.asList("Asc", "Desc")); private final List orders; @@ -47,7 +52,6 @@ public class OrderBySource { * @param clause must not be {@literal null}. */ public OrderBySource(String clause) { - this(clause, null); } @@ -56,18 +60,30 @@ public class OrderBySource { * type. * * @param clause must not be {@literal null}. - * @param domainClass + * @param domainClass can be {@literal null}. */ public OrderBySource(String clause, Class domainClass) { this.orders = new ArrayList(); + for (String part : clause.split(BLOCK_SPLIT)) { + Matcher matcher = DIRECTION_SPLIT.matcher(part); + if (!matcher.find()) { - throw new IllegalArgumentException(String.format("Invalid order syntax for part %s!", part)); + throw new IllegalArgumentException(String.format(INVALID_ORDER_SYNTAX, part)); } - Direction direction = Direction.fromString(matcher.group(2)); - this.orders.add(createOrder(matcher.group(1), direction, domainClass)); + + String propertyString = matcher.group(1); + String directionString = matcher.group(2); + + // No property, but only a direction keyword + if (DIRECTION_KEYWORDS.contains(propertyString) && directionString == null) { + throw new IllegalArgumentException(String.format(INVALID_ORDER_SYNTAX, part)); + } + + Direction direction = StringUtils.hasText(directionString) ? Direction.fromString(directionString) : null; + this.orders.add(createOrder(propertyString, direction, domainClass)); } } diff --git a/src/test/java/org/springframework/data/repository/query/parser/OrderBySourceUnitTests.java b/src/test/java/org/springframework/data/repository/query/parser/OrderBySourceUnitTests.java index 7bd486093..620e83587 100644 --- a/src/test/java/org/springframework/data/repository/query/parser/OrderBySourceUnitTests.java +++ b/src/test/java/org/springframework/data/repository/query/parser/OrderBySourceUnitTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2008-2010 the original author or authors. + * Copyright 2008-2015 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -60,7 +60,16 @@ public class OrderBySourceUnitTests { OrderBySource source = new OrderBySource("BarNameDesc", Foo.class); assertThat(source.toSort(), is(new Sort(new Order(DESC, "bar.name")))); + } + /** + * @see DATACMNS-641 + */ + @Test + public void defaultsSortOrderToAscendingSort() { + + OrderBySource source = new OrderBySource("lastname"); + assertThat(source.toSort(), is(new Sort("lastname"))); } @SuppressWarnings("unused")