DATACMNS-387 - Improvements in null handling in PartTree area.

We're now rejecting invalid constructor arguments handed to ClassTypeInformation, Part, PartTree and PropertyPath. Beyond that we skip the creation of a Part for an empty path segment, so that you don't end up with an invalid Part instance for a findAllByOrderByFooAsc.
This commit is contained in:
Oliver Gierke
2013-10-27 16:21:01 +01:00
parent 1624fec11a
commit ae9ee5b428
7 changed files with 79 additions and 19 deletions

View File

@@ -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<PropertyPath> {
* @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<PropertyPath> {
* @see #hasNext()
*/
public PropertyPath next() {
return next;
}
@@ -144,7 +142,6 @@ public class PropertyPath implements Iterable<PropertyPath> {
* @return
*/
public boolean hasNext() {
return next != null;
}
@@ -168,7 +165,6 @@ public class PropertyPath implements Iterable<PropertyPath> {
* @return
*/
public boolean isCollection() {
return isCollection;
}
@@ -242,7 +238,6 @@ public class PropertyPath implements Iterable<PropertyPath> {
* @return
*/
public static PropertyPath from(String source, Class<?> type) {
return from(source, ClassTypeInformation.from(type));
}
@@ -255,6 +250,9 @@ public class PropertyPath implements Iterable<PropertyPath> {
*/
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<String> iteratorSource = new ArrayList<String>();
Matcher matcher = SPLITTER.matcher("_" + source);
@@ -306,7 +304,6 @@ public class PropertyPath implements Iterable<PropertyPath> {
* @return
*/
private static PropertyPath create(String source, TypeInformation<?> type, Stack<PropertyPath> base) {
return create(source, type, "", base);
}

View File

@@ -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;
}

View File

@@ -197,7 +197,9 @@ public class PartTree implements Iterable<OrPart> {
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));
}
}
}

View File

@@ -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<S> extends TypeDiscoverer<S> {
* Simple factory method to easily create new instances of {@link ClassTypeInformation}.
*
* @param <S>
* @param type
* @param type must not be {@literal null}.
* @return
*/
public static <S> TypeInformation<S> from(Class<S> type) {
Assert.notNull(type, "Type must not be null!");
Reference<TypeInformation<?>> cachedReference = CACHE.get(type);
TypeInformation<?> cachedTypeInfo = cachedReference == null ? null : cachedReference.get();
@@ -80,10 +83,12 @@ public class ClassTypeInformation<S> extends TypeDiscoverer<S> {
/**
* Creates a {@link TypeInformation} from the given method's return type.
*
* @param method
* @param method must not be {@literal null}.
* @return
*/
public static <S> TypeInformation<S> fromReturnTypeOf(Method method) {
Assert.notNull(method, "Method must not be null!");
return new ClassTypeInformation(method.getDeclaringClass()).createInfo(method.getGenericReturnType());
}