diff --git a/spring-data-commons-core/src/main/java/org/springframework/data/repository/query/parser/Part.java b/spring-data-commons-core/src/main/java/org/springframework/data/repository/query/parser/Part.java index 16a8a1235..fefe9d69e 100644 --- a/spring-data-commons-core/src/main/java/org/springframework/data/repository/query/parser/Part.java +++ b/spring-data-commons-core/src/main/java/org/springframework/data/repository/query/parser/Part.java @@ -36,7 +36,7 @@ public class Part { private final Property property; private final Part.Type type; - private boolean ignoreCase; + private IgnoreCaseType ignoreCase = IgnoreCaseType.NEVER; /** * Creates a new {@link Part} from the given method name part, the {@link Class} the part originates from and the @@ -61,7 +61,9 @@ public class Part { public Part(String part, Class clazz, boolean alwaysIgnoreCase) { part = detectAndSetIgnoreCase(part); - this.ignoreCase = this.ignoreCase || alwaysIgnoreCase; + if (alwaysIgnoreCase && ignoreCase != IgnoreCaseType.ALWAYS) { + this.ignoreCase = IgnoreCaseType.WHEN_POSSIBLE; + } this.type = Type.fromProperty(part, clazz); this.property = Property.from(type.extractProperty(part), clazz); } @@ -70,7 +72,7 @@ public class Part { Matcher matcher = IGNORE_CASE.matcher(part); if (matcher.find()) { - ignoreCase = true; + ignoreCase = IgnoreCaseType.ALWAYS; part = part.substring(0, matcher.start()) + part.substring(matcher.end(), part.length()); } return part; @@ -112,7 +114,7 @@ public class Part { * * @return */ - public boolean shouldIgnoreCase() { + public IgnoreCaseType shouldIgnoreCase() { return ignoreCase; } @@ -203,7 +205,7 @@ public class Part { /** * Creates a new {@link Type} using the given keyword, number of arguments to be bound and operator. Keyword and * operator can be {@literal null}. - * + * * @param numberOfArguments * @param keywords */ @@ -289,4 +291,27 @@ public class Part { return candidate; } } + + /** + * The various types of ignore case that are supported. + * + * @author Phillip Webb + */ + public enum IgnoreCaseType { + + /** + * Should not ignore the sentence case. + */ + NEVER, + + /** + * Should ignore the sentence case, throwing an exception if this is not possible. + */ + ALWAYS, + + /** + * Should ignore the sentence case when possible to do so, silently ignoring the option when not possible. + */ + WHEN_POSSIBLE + } } \ No newline at end of file diff --git a/spring-data-commons-core/src/test/java/org/springframework/data/repository/query/parser/PartTreeUnitTests.java b/spring-data-commons-core/src/test/java/org/springframework/data/repository/query/parser/PartTreeUnitTests.java index 45bef5ce7..ba838f2a0 100644 --- a/spring-data-commons-core/src/test/java/org/springframework/data/repository/query/parser/PartTreeUnitTests.java +++ b/spring-data-commons-core/src/test/java/org/springframework/data/repository/query/parser/PartTreeUnitTests.java @@ -25,14 +25,15 @@ import java.util.Iterator; import org.junit.Test; import org.springframework.data.domain.Sort; import org.springframework.data.domain.Sort.Direction; +import org.springframework.data.repository.query.parser.Part.IgnoreCaseType; import org.springframework.data.repository.query.parser.Part.Type; import org.springframework.data.repository.query.parser.PartTree.OrPart; /** * Unit tests for {@link PartTree}. - * + * * @author Oliver Gierke - * @author Phil Webb + * @author Phillip Webb */ public class PartTreeUnitTests { @@ -93,7 +94,7 @@ public class PartTreeUnitTests { } private void hasSortIfOrderByIsGivenWithAllIgnoreCase(String source) throws Exception { - PartTree partTree= partTree(source); + PartTree partTree = partTree(source); assertThat(partTree.getSort(), is(new Sort(Direction.DESC, "lastname"))); } @@ -150,15 +151,15 @@ public class PartTreeUnitTests { @Test public void detectsIgnoreAllCase() throws Exception { - detectsIgnoreAllCase("firstnameOrderByLastnameDescAllIgnoreCase",true); - detectsIgnoreAllCase("firstnameOrderByLastnameDescAllIgnoringCase",true); - detectsIgnoreAllCase("firstnameAllIgnoreCaseOrderByLastnameDesc",true); - detectsIgnoreAllCase("getByFirstnameAllIgnoreCase",true); - detectsIgnoreAllCase("getByFirstname",false); - detectsIgnoreAllCase("firstnameOrderByLastnameDesc",false); + detectsIgnoreAllCase("firstnameOrderByLastnameDescAllIgnoreCase", IgnoreCaseType.WHEN_POSSIBLE); + detectsIgnoreAllCase("firstnameOrderByLastnameDescAllIgnoringCase", IgnoreCaseType.WHEN_POSSIBLE); + detectsIgnoreAllCase("firstnameAllIgnoreCaseOrderByLastnameDesc", IgnoreCaseType.WHEN_POSSIBLE); + detectsIgnoreAllCase("getByFirstnameAllIgnoreCase", IgnoreCaseType.WHEN_POSSIBLE); + detectsIgnoreAllCase("getByFirstname", IgnoreCaseType.NEVER); + detectsIgnoreAllCase("firstnameOrderByLastnameDesc", IgnoreCaseType.NEVER); } - private void detectsIgnoreAllCase(String source, boolean expected) throws Exception { + private void detectsIgnoreAllCase(String source, IgnoreCaseType expected) throws Exception { PartTree tree = partTree(source); for (Part part : tree.getParts()) { assertThat(part.shouldIgnoreCase(), is(expected)); @@ -168,19 +169,19 @@ public class PartTreeUnitTests { @Test public void detectsSpecificIgnoreCase() throws Exception { PartTree tree = partTree("findByFirstnameIgnoreCaseAndLastname"); - assertPart(tree, parts("firstname","lastname")); + assertPart(tree, parts("firstname", "lastname")); Iterator parts = tree.getParts().iterator(); - assertThat(parts.next().shouldIgnoreCase(), is(true)); - assertThat(parts.next().shouldIgnoreCase(), is(false)); + assertThat(parts.next().shouldIgnoreCase(), is(IgnoreCaseType.ALWAYS)); + assertThat(parts.next().shouldIgnoreCase(), is(IgnoreCaseType.NEVER)); } @Test public void detectsSpecificIgnoringCase() throws Exception { PartTree tree = partTree("findByFirstnameIgnoringCaseAndLastname"); - assertPart(tree, parts("firstname","lastname")); + assertPart(tree, parts("firstname", "lastname")); Iterator parts = tree.getParts().iterator(); - assertThat(parts.next().shouldIgnoreCase(), is(true)); - assertThat(parts.next().shouldIgnoreCase(), is(false)); + assertThat(parts.next().shouldIgnoreCase(), is(IgnoreCaseType.ALWAYS)); + assertThat(parts.next().shouldIgnoreCase(), is(IgnoreCaseType.NEVER)); } private PartTree partTree(String source) { @@ -209,8 +210,7 @@ public class PartTreeUnitTests { assertThat(iterator.hasNext(), is(true)); Iterator partIterator = iterator.next().iterator(); for (int k = 0; k < part.length; k++) { - assertThat(String.format("Expected %d parts but have %d", part.length, k), partIterator.hasNext(), - is(true)); + assertThat(String.format("Expected %d parts but have %d", part.length, k), partIterator.hasNext(), is(true)); Part next = partIterator.next(); assertThat(String.format("Expected %s but got %s!", part[k], next), part[k], is(next)); }