Skip to content

Commit ddeb70c

Browse files
schaudermp911de
authored andcommitted
Clarify behavior of PropertyPath.
Update tests and documentation. Closes #2491
1 parent 91d2fdc commit ddeb70c

File tree

2 files changed

+72
-9
lines changed

2 files changed

+72
-9
lines changed

src/main/java/org/springframework/data/mapping/PropertyPath.java

+60-9
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,15 @@ public TypeInformation<?> getOwningType() {
108108
}
109109

110110
/**
111-
* Returns the name of the {@link PropertyPath}.
111+
* Returns the first part of the {@link PropertyPath}.
112+
*
113+
* <pre>
114+
* {@code
115+
* PropertyPath.from("a.b.c", Some.class).getSegment();
116+
* }
117+
* </pre>
118+
*
119+
* will result in {@code "a"}
112120
*
113121
* @return the name will never be {@literal null}.
114122
*/
@@ -156,7 +164,15 @@ public TypeInformation<?> getTypeInformation() {
156164
}
157165

158166
/**
159-
* Returns the next nested {@link PropertyPath}.
167+
* Returns the {@link PropertyPath} path that results from removing the first element of the current one.
168+
*
169+
* <pre>
170+
* {@code
171+
* System.out.println(PropertyPath.from("a.b.c", Some.class).next().toDotPath());
172+
* }
173+
* </pre>
174+
*
175+
* Will result in the output: {@code b.c}
160176
*
161177
* @return the next nested {@link PropertyPath} or {@literal null} if no nested {@link PropertyPath} available.
162178
* @see #hasNext()
@@ -214,6 +230,29 @@ public PropertyPath nested(String path) {
214230
return PropertyPath.from(lookup, owningType);
215231
}
216232

233+
/**
234+
* Returns an {@link Iterator<PropertyPath>} that iterates over all the partial property paths with the same leaf type
235+
* but decreasing length.
236+
*
237+
* <pre>
238+
* {@code
239+
* PropertyPath propertyPath = PropertyPath.from("a.b.c", Some.class);
240+
* for (p : propertyPath.iterator()) {
241+
* System.out.println(p.toDotPath());
242+
* };
243+
* }
244+
* </pre>
245+
*
246+
* Results in the output:
247+
*
248+
* <pre>
249+
* {@code
250+
* a.b.c
251+
* b.c
252+
* c
253+
* }
254+
* </pre>
255+
*/
217256
public Iterator<PropertyPath> iterator() {
218257

219258
return new Iterator<PropertyPath>() {
@@ -289,11 +328,18 @@ private PropertyPath requiredNext() {
289328
}
290329

291330
/**
292-
* Extracts the {@link PropertyPath} chain from the given source {@link String} and type.
331+
* Extracts the {@link PropertyPath} chain from the given source {@link String} and {@link TypeInformation}. <br />
332+
* Uses {@link #SPLITTER} by default and {@link #SPLITTER_FOR_QUOTED} for {@link Pattern#quote(String) quoted}
333+
* literals.
334+
* <p>
335+
* Separate parts of the path may be separated by {@code "."} or by {@code "_"} or by camel case. When the match to
336+
* properties is ambiguous longer property names are preferred. So for "userAddressCity" the interpretation
337+
* "userAddress.city" is preferred over "user.address.city".
338+
* </p>
293339
*
294-
* @param source
295-
* @param type
296-
* @return
340+
* @param source a String denoting the property path. Must not be {@literal null}.
341+
* @param type the owning type of the property path. Must not be {@literal null}.
342+
* @return a new {@link PropertyPath} guaranteed to be not {@literal null}.
297343
*/
298344
public static PropertyPath from(String source, Class<?> type) {
299345
return from(source, TypeInformation.of(type));
@@ -303,10 +349,15 @@ public static PropertyPath from(String source, Class<?> type) {
303349
* Extracts the {@link PropertyPath} chain from the given source {@link String} and {@link TypeInformation}. <br />
304350
* Uses {@link #SPLITTER} by default and {@link #SPLITTER_FOR_QUOTED} for {@link Pattern#quote(String) quoted}
305351
* literals.
352+
* <p>
353+
* Separate parts of the path may be separated by {@code "."} or by {@code "_"} or by camel case. When the match to
354+
* properties is ambiguous longer property names are preferred. So for "userAddressCity" the interpretation
355+
* "userAddress.city" is preferred over "user.address.city".
356+
* </p>
306357
*
307-
* @param source must not be {@literal null}.
308-
* @param type
309-
* @return
358+
* @param source a String denoting the property path. Must not be {@literal null}.
359+
* @param type the owning type of the property path. Must not be {@literal null}.
360+
* @return a new {@link PropertyPath} guaranteed to be not {@literal null}.
310361
*/
311362
public static PropertyPath from(String source, TypeInformation<?> type) {
312363

src/test/java/org/springframework/data/mapping/PropertyPathUnitTests.java

+12
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import java.util.regex.Pattern;
2424

2525
import org.junit.jupiter.api.Test;
26+
import org.springframework.data.util.ClassTypeInformation;
2627
import org.springframework.data.util.TypeInformation;
2728

2829
/**
@@ -31,6 +32,7 @@
3132
* @author Oliver Gierke
3233
* @author Christoph Strobl
3334
* @author Mark Paluch
35+
* @author Jens Schauder
3436
*/
3537
@SuppressWarnings("unused")
3638
class PropertyPathUnitTests {
@@ -185,6 +187,16 @@ void returnsCorrectIteratorForMultipleElement() {
185187
assertThat(iterator.hasNext()).isFalse();
186188
}
187189

190+
@Test // GH-2491
191+
public void nextReturnsPathWithoutFirstElement() {
192+
193+
PropertyPath propertyPath = PropertyPath.from("bar.user.name", Sample.class);
194+
195+
final PropertyPath next = propertyPath.next();
196+
assertThat(next).isNotNull();
197+
assertThat(next.toDotPath()).isEqualTo("user.name");
198+
}
199+
188200
@Test // DATACMNS-139, GH-2395
189201
void rejectsInvalidPropertyWithLeadingUnderscore() {
190202

0 commit comments

Comments
 (0)