Clarify behavior of PropertyPath.
Update tests and documentation. Closes #2491
This commit is contained in:
committed by
Mark Paluch
parent
91d2fdc3f7
commit
ddeb70cd7b
@@ -108,7 +108,15 @@ public class PropertyPath implements Streamable<PropertyPath> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the {@link PropertyPath}.
|
||||
* Returns the first part of the {@link PropertyPath}.
|
||||
*
|
||||
* <pre>
|
||||
* {@code
|
||||
* PropertyPath.from("a.b.c", Some.class).getSegment();
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* will result in {@code "a"}
|
||||
*
|
||||
* @return the name will never be {@literal null}.
|
||||
*/
|
||||
@@ -156,7 +164,15 @@ public class PropertyPath implements Streamable<PropertyPath> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the next nested {@link PropertyPath}.
|
||||
* Returns the {@link PropertyPath} path that results from removing the first element of the current one.
|
||||
*
|
||||
* <pre>
|
||||
* {@code
|
||||
* System.out.println(PropertyPath.from("a.b.c", Some.class).next().toDotPath());
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* Will result in the output: {@code b.c}
|
||||
*
|
||||
* @return the next nested {@link PropertyPath} or {@literal null} if no nested {@link PropertyPath} available.
|
||||
* @see #hasNext()
|
||||
@@ -214,6 +230,29 @@ public class PropertyPath implements Streamable<PropertyPath> {
|
||||
return PropertyPath.from(lookup, owningType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an {@link Iterator<PropertyPath>} that iterates over all the partial property paths with the same leaf type
|
||||
* but decreasing length.
|
||||
*
|
||||
* <pre>
|
||||
* {@code
|
||||
* PropertyPath propertyPath = PropertyPath.from("a.b.c", Some.class);
|
||||
* for (p : propertyPath.iterator()) {
|
||||
* System.out.println(p.toDotPath());
|
||||
* };
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* Results in the output:
|
||||
*
|
||||
* <pre>
|
||||
* {@code
|
||||
* a.b.c
|
||||
* b.c
|
||||
* c
|
||||
* }
|
||||
* </pre>
|
||||
*/
|
||||
public Iterator<PropertyPath> iterator() {
|
||||
|
||||
return new Iterator<PropertyPath>() {
|
||||
@@ -289,11 +328,18 @@ public class PropertyPath implements Streamable<PropertyPath> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the {@link PropertyPath} chain from the given source {@link String} and type.
|
||||
* Extracts the {@link PropertyPath} chain from the given source {@link String} and {@link TypeInformation}. <br />
|
||||
* Uses {@link #SPLITTER} by default and {@link #SPLITTER_FOR_QUOTED} for {@link Pattern#quote(String) quoted}
|
||||
* literals.
|
||||
* <p>
|
||||
* Separate parts of the path may be separated by {@code "."} or by {@code "_"} or by camel case. When the match to
|
||||
* properties is ambiguous longer property names are preferred. So for "userAddressCity" the interpretation
|
||||
* "userAddress.city" is preferred over "user.address.city".
|
||||
* </p>
|
||||
*
|
||||
* @param source
|
||||
* @param type
|
||||
* @return
|
||||
* @param source a String denoting the property path. Must not be {@literal null}.
|
||||
* @param type the owning type of the property path. Must not be {@literal null}.
|
||||
* @return a new {@link PropertyPath} guaranteed to be not {@literal null}.
|
||||
*/
|
||||
public static PropertyPath from(String source, Class<?> type) {
|
||||
return from(source, TypeInformation.of(type));
|
||||
@@ -303,10 +349,15 @@ public class PropertyPath implements Streamable<PropertyPath> {
|
||||
* Extracts the {@link PropertyPath} chain from the given source {@link String} and {@link TypeInformation}. <br />
|
||||
* Uses {@link #SPLITTER} by default and {@link #SPLITTER_FOR_QUOTED} for {@link Pattern#quote(String) quoted}
|
||||
* literals.
|
||||
* <p>
|
||||
* Separate parts of the path may be separated by {@code "."} or by {@code "_"} or by camel case. When the match to
|
||||
* properties is ambiguous longer property names are preferred. So for "userAddressCity" the interpretation
|
||||
* "userAddress.city" is preferred over "user.address.city".
|
||||
* </p>
|
||||
*
|
||||
* @param source must not be {@literal null}.
|
||||
* @param type
|
||||
* @return
|
||||
* @param source a String denoting the property path. Must not be {@literal null}.
|
||||
* @param type the owning type of the property path. Must not be {@literal null}.
|
||||
* @return a new {@link PropertyPath} guaranteed to be not {@literal null}.
|
||||
*/
|
||||
public static PropertyPath from(String source, TypeInformation<?> type) {
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ import java.util.Set;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.data.util.ClassTypeInformation;
|
||||
import org.springframework.data.util.TypeInformation;
|
||||
|
||||
/**
|
||||
@@ -31,6 +32,7 @@ import org.springframework.data.util.TypeInformation;
|
||||
* @author Oliver Gierke
|
||||
* @author Christoph Strobl
|
||||
* @author Mark Paluch
|
||||
* @author Jens Schauder
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
class PropertyPathUnitTests {
|
||||
@@ -185,6 +187,16 @@ class PropertyPathUnitTests {
|
||||
assertThat(iterator.hasNext()).isFalse();
|
||||
}
|
||||
|
||||
@Test // GH-2491
|
||||
public void nextReturnsPathWithoutFirstElement() {
|
||||
|
||||
PropertyPath propertyPath = PropertyPath.from("bar.user.name", Sample.class);
|
||||
|
||||
final PropertyPath next = propertyPath.next();
|
||||
assertThat(next).isNotNull();
|
||||
assertThat(next.toDotPath()).isEqualTo("user.name");
|
||||
}
|
||||
|
||||
@Test // DATACMNS-139, GH-2395
|
||||
void rejectsInvalidPropertyWithLeadingUnderscore() {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user