diff --git a/src/main/java/org/springframework/data/mapping/PropertyPath.java b/src/main/java/org/springframework/data/mapping/PropertyPath.java index 1a6548206..c98662542 100644 --- a/src/main/java/org/springframework/data/mapping/PropertyPath.java +++ b/src/main/java/org/springframework/data/mapping/PropertyPath.java @@ -1,5 +1,5 @@ /* - * Copyright 2011-2012 the original author or authors. + * Copyright 2011-2013 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. @@ -53,7 +53,6 @@ public class PropertyPath implements Iterable { * @param owningType must not be {@literal null}. */ PropertyPath(String name, Class owningType) { - this(name, ClassTypeInformation.from(owningType), null); } @@ -133,7 +132,6 @@ public class PropertyPath implements Iterable { * @see #hasNext() */ public PropertyPath next() { - return next; } @@ -144,7 +142,6 @@ public class PropertyPath implements Iterable { * @return */ public boolean hasNext() { - return next != null; } @@ -168,7 +165,6 @@ public class PropertyPath implements Iterable { * @return */ public boolean isCollection() { - return isCollection; } @@ -242,7 +238,6 @@ public class PropertyPath implements Iterable { * @return */ public static PropertyPath from(String source, Class type) { - return from(source, ClassTypeInformation.from(type)); } @@ -255,6 +250,9 @@ public class PropertyPath implements Iterable { */ public static PropertyPath from(String source, TypeInformation type) { + Assert.hasText(source, "Source must not be null or empty!"); + Assert.notNull(type, "TypeInformation must not be null or empty!"); + List iteratorSource = new ArrayList(); Matcher matcher = SPLITTER.matcher("_" + source); @@ -306,7 +304,6 @@ public class PropertyPath implements Iterable { * @return */ private static PropertyPath create(String source, TypeInformation type, Stack base) { - return create(source, type, "", base); } diff --git a/src/main/java/org/springframework/data/repository/query/parser/Part.java b/src/main/java/org/springframework/data/repository/query/parser/Part.java index 7e86b8d4b..1d3a28b45 100644 --- a/src/main/java/org/springframework/data/repository/query/parser/Part.java +++ b/src/main/java/org/springframework/data/repository/query/parser/Part.java @@ -24,6 +24,7 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import org.springframework.data.mapping.PropertyPath; +import org.springframework.util.Assert; import org.springframework.util.StringUtils; /** @@ -46,25 +47,27 @@ public class Part { * Creates a new {@link Part} from the given method name part, the {@link Class} the part originates from and the * start parameter index. * - * @param part must not be {@literal null}. + * @param source must not be {@literal null}. * @param clazz must not be {@literal null}. */ - public Part(String part, Class clazz) { - - this(part, clazz, false); + public Part(String source, Class clazz) { + this(source, clazz, false); } /** * Creates a new {@link Part} from the given method name part, the {@link Class} the part originates from and the * start parameter index. * - * @param part must not be {@literal null}. + * @param source must not be {@literal null}. * @param clazz must not be {@literal null}. * @param alwaysIgnoreCase */ - public Part(String part, Class clazz, boolean alwaysIgnoreCase) { + public Part(String source, Class clazz, boolean alwaysIgnoreCase) { - String partToUse = detectAndSetIgnoreCase(part); + Assert.hasText(source, "Part source must not be null or emtpy!"); + Assert.notNull(clazz, "Type must not be null!"); + + String partToUse = detectAndSetIgnoreCase(source); if (alwaysIgnoreCase && ignoreCase != IgnoreCaseType.ALWAYS) { this.ignoreCase = IgnoreCaseType.WHEN_POSSIBLE; } diff --git a/src/main/java/org/springframework/data/repository/query/parser/PartTree.java b/src/main/java/org/springframework/data/repository/query/parser/PartTree.java index f51eb289a..a5d9f166c 100644 --- a/src/main/java/org/springframework/data/repository/query/parser/PartTree.java +++ b/src/main/java/org/springframework/data/repository/query/parser/PartTree.java @@ -197,7 +197,9 @@ public class PartTree implements Iterable { String[] split = split(source, "And"); for (String part : split) { - children.add(new Part(part, domainClass, alwaysIgnoreCase)); + if (StringUtils.hasText(part)) { + children.add(new Part(part, domainClass, alwaysIgnoreCase)); + } } } diff --git a/src/main/java/org/springframework/data/util/ClassTypeInformation.java b/src/main/java/org/springframework/data/util/ClassTypeInformation.java index cbcd48c67..944a52dbc 100644 --- a/src/main/java/org/springframework/data/util/ClassTypeInformation.java +++ b/src/main/java/org/springframework/data/util/ClassTypeInformation.java @@ -1,5 +1,5 @@ /* - * Copyright 2011 the original author or authors. + * Copyright 2011-2013 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. @@ -29,6 +29,7 @@ import java.util.Set; import java.util.WeakHashMap; import org.springframework.core.GenericTypeResolver; +import org.springframework.util.Assert; import org.springframework.util.ClassUtils; /** @@ -60,11 +61,13 @@ public class ClassTypeInformation extends TypeDiscoverer { * Simple factory method to easily create new instances of {@link ClassTypeInformation}. * * @param - * @param type + * @param type must not be {@literal null}. * @return */ public static TypeInformation from(Class type) { + Assert.notNull(type, "Type must not be null!"); + Reference> cachedReference = CACHE.get(type); TypeInformation cachedTypeInfo = cachedReference == null ? null : cachedReference.get(); @@ -80,10 +83,12 @@ public class ClassTypeInformation extends TypeDiscoverer { /** * Creates a {@link TypeInformation} from the given method's return type. * - * @param method + * @param method must not be {@literal null}. * @return */ public static TypeInformation fromReturnTypeOf(Method method) { + + Assert.notNull(method, "Method must not be null!"); return new ClassTypeInformation(method.getDeclaringClass()).createInfo(method.getGenericReturnType()); } diff --git a/src/test/java/org/springframework/data/mapping/PropertyPathUnitTests.java b/src/test/java/org/springframework/data/mapping/PropertyPathUnitTests.java index b7c7da8c9..aefe1d05a 100644 --- a/src/test/java/org/springframework/data/mapping/PropertyPathUnitTests.java +++ b/src/test/java/org/springframework/data/mapping/PropertyPathUnitTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2011-2012 the original author or authors. + * Copyright 2011-2013 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. @@ -17,6 +17,7 @@ package org.springframework.data.mapping; import static org.hamcrest.Matchers.*; import static org.junit.Assert.*; +import static org.springframework.data.mapping.PropertyPath.*; import java.util.Iterator; import java.util.Map; @@ -319,6 +320,38 @@ public class PropertyPathUnitTests { PropertyPath.from("userNameBar", Bar.class); } + /** + * @see DATACMNS-387 + */ + @Test(expected = IllegalArgumentException.class) + public void rejectsNullSource() { + from(null, Foo.class); + } + + /** + * @see DATACMNS-387 + */ + @Test(expected = IllegalArgumentException.class) + public void rejectsEmptySource() { + from("", Foo.class); + } + + /** + * @see DATACMNS-387 + */ + @Test(expected = IllegalArgumentException.class) + public void rejectsNullClass() { + from("foo", (Class) null); + } + + /** + * @see DATACMNS-387 + */ + @Test(expected = IllegalArgumentException.class) + public void rejectsNullTypeInformation() { + from("foo", (TypeInformation) null); + } + private class Foo { String userName; diff --git a/src/test/java/org/springframework/data/repository/query/parser/PartTreeUnitTests.java b/src/test/java/org/springframework/data/repository/query/parser/PartTreeUnitTests.java index 7d2a0fe93..a47a79715 100644 --- a/src/test/java/org/springframework/data/repository/query/parser/PartTreeUnitTests.java +++ b/src/test/java/org/springframework/data/repository/query/parser/PartTreeUnitTests.java @@ -470,6 +470,18 @@ public class PartTreeUnitTests { assertThat(new PartTree("findByOrderId", Product.class), is(notNullValue())); } + /** + * @see DATACMNS-387 + */ + @Test + public void buildsPartTreeFromEmptyPredicateCorrectly() { + + PartTree tree = new PartTree("findAllByOrderByLastnameAsc", User.class); + + assertThat(tree.getParts(), is(emptyIterable())); + assertThat(tree.getSort(), is(new Sort(Direction.ASC, "lastname"))); + } + private static void assertType(Iterable sources, Type type, String property) { assertType(sources, type, property, 1, true); } diff --git a/src/test/java/org/springframework/data/util/ClassTypeInformationUnitTests.java b/src/test/java/org/springframework/data/util/ClassTypeInformationUnitTests.java index 139941a26..cb57bbcf9 100644 --- a/src/test/java/org/springframework/data/util/ClassTypeInformationUnitTests.java +++ b/src/test/java/org/springframework/data/util/ClassTypeInformationUnitTests.java @@ -277,6 +277,14 @@ public class ClassTypeInformationUnitTests { assertThat(categoryIdInfo, is((TypeInformation) from(Long.class))); } + /** + * @see DATACMNS-387 + */ + @Test(expected = IllegalArgumentException.class) + public void rejectsNullClass() { + from(null); + } + static class StringMapContainer extends MapContainer { }