diff --git a/src/main/java/org/springframework/data/mapping/PersistentPropertyPath.java b/src/main/java/org/springframework/data/mapping/PersistentPropertyPath.java index 5e76469077..cf0d2323ca 100644 --- a/src/main/java/org/springframework/data/mapping/PersistentPropertyPath.java +++ b/src/main/java/org/springframework/data/mapping/PersistentPropertyPath.java @@ -29,8 +29,6 @@ public interface PersistentPropertyPath
> extends /** * Returns the dot based path notation using {@link PersistentProperty#getName()}. - * - * @return */ @Nullable String toDotPath(); @@ -40,7 +38,6 @@ public interface PersistentPropertyPath
> extends * {@link PersistentProperty}s to path segments. * * @param converter must not be {@literal null}. - * @return */ @Nullable String toDotPath(Converter super P, String> converter); @@ -49,7 +46,6 @@ public interface PersistentPropertyPath
> extends * Returns a {@link String} path with the given delimiter based on the {@link PersistentProperty#getName()}. * * @param delimiter must not be {@literal null}. - * @return */ @Nullable String toPath(String delimiter); @@ -60,7 +56,6 @@ public interface PersistentPropertyPath
> extends * * @param delimiter must not be {@literal null}. * @param converter must not be {@literal null}. - * @return */ @Nullable String toPath(String delimiter, Converter super P, String> converter); @@ -70,7 +65,6 @@ public interface PersistentPropertyPath
> extends * {@link PersistentProperty} for {@code bar}. For a simple {@code foo} it returns {@link PersistentProperty} for * {@code foo}. * - * @return */ @Nullable P getLeafProperty(); @@ -90,28 +84,24 @@ default P getRequiredLeafProperty() { * Returns the first property in the {@link PersistentPropertyPath}. So for {@code foo.bar} it will return the * {@link PersistentProperty} for {@code foo}. For a simple {@code foo} it returns {@link PersistentProperty} for * {@code foo}. - * - * @return */ @Nullable P getBaseProperty(); /** * Returns whether the given {@link PersistentPropertyPath} is a base path of the current one. This means that the - * current {@link PersistentPropertyPath} is basically an extension of the given one. + * given {@link PersistentPropertyPath} is basically an extension of this {@link PersistentPropertyPath}. * * @param path must not be {@literal null}. - * @return */ boolean isBasePathOf(PersistentPropertyPath
path); /** * Returns the sub-path of the current one as if it was based on the given base path. So for a current path * {@code foo.bar} and a given base {@code foo} it would return {@code bar}. If the given path is not a base of the - * the current one the current {@link PersistentPropertyPath} will be returned as is. + * current one the current {@link PersistentPropertyPath} will be returned as is. * * @param base must not be {@literal null}. - * @return */ PersistentPropertyPath
getExtensionForBaseOf(PersistentPropertyPath
base); @@ -119,15 +109,11 @@ default P getRequiredLeafProperty() { * Returns the parent path of the current {@link PersistentPropertyPath}, i.e. the path without the leaf property. * This happens up to the base property. So for a direct property reference calling this method will result in * returning the property. - * - * @return */ PersistentPropertyPath
getParentPath(); /** * Returns the length of the {@link PersistentPropertyPath}. - * - * @return */ int getLength(); } diff --git a/src/main/java/org/springframework/data/mapping/context/DefaultPersistentPropertyPath.java b/src/main/java/org/springframework/data/mapping/context/DefaultPersistentPropertyPath.java index 0b1f2927db..3d9a468bf4 100644 --- a/src/main/java/org/springframework/data/mapping/context/DefaultPersistentPropertyPath.java +++ b/src/main/java/org/springframework/data/mapping/context/DefaultPersistentPropertyPath.java @@ -38,7 +38,7 @@ */ class DefaultPersistentPropertyPath
> implements PersistentPropertyPath
{
- private static final Converter properties;
@@ -131,25 +131,43 @@ public P getBaseProperty() {
}
public boolean isBasePathOf(PersistentPropertyPath path) {
+ return this.equals(getCommonBaseWith(path));
+ }
- Assert.notNull(path, "PersistentPropertyPath must not be null");
+ /**
+ * Return the common base path that this {@link PersistentPropertyPath} has with passed {@link PersistentPropertyPath}
+ *
+ * That is, for example, if this {@link PersistentPropertyPath} equals to one.two.three, and passed {@link PersistentPropertyPath}
+ * is equals to one.two.four, that the return will be the {@link PersistentPropertyPath} containing one.two properties
+ */
+ public PersistentPropertyPath getCommonBaseWith(PersistentPropertyPath anotherPath) {
+
+ Assert.notNull(anotherPath, "PersistentPropertyPath must not be null");
+
+ if (anotherPath.isEmpty()) {
+ return DefaultPersistentPropertyPath.empty();
+ }
- Iterator iterator = path.iterator();
+ List commonPart = new ArrayList<>();
- for (P property : this) {
+ Iterator iterator = anotherPath.iterator();
+
+ for (P property: this) {
if (!iterator.hasNext()) {
- return false;
+ break;
}
- P reference = iterator.next();
+ P next = iterator.next();
- if (!property.equals(reference)) {
- return false;
+ if (property.equals(next)) {
+ commonPart.add(property);
+ } else {
+ break;
}
}
- return true;
+ return new DefaultPersistentPropertyPath<>(commonPart);
}
public PersistentPropertyPath getExtensionForBaseOf(PersistentPropertyPath base) {
@@ -158,18 +176,7 @@ public PersistentPropertyPath getExtensionForBaseOf(PersistentPropertyPath
return this;
}
- List result = new ArrayList<>();
- Iterator iterator = iterator();
-
- for (int i = 0; i < base.getLength(); i++) {
- iterator.next();
- }
-
- while (iterator.hasNext()) {
- result.add(iterator.next());
- }
-
- return new DefaultPersistentPropertyPath<>(result);
+ return new DefaultPersistentPropertyPath<>(properties.subList(base.getLength(), properties.size()));
}
public PersistentPropertyPath getParentPath() {
diff --git a/src/test/java/org/springframework/data/mapping/context/DefaultPersistentPropertyPathUnitTests.java b/src/test/java/org/springframework/data/mapping/context/DefaultPersistentPropertyPathUnitTests.java
index 4da5788073..0f272f534a 100755
--- a/src/test/java/org/springframework/data/mapping/context/DefaultPersistentPropertyPathUnitTests.java
+++ b/src/test/java/org/springframework/data/mapping/context/DefaultPersistentPropertyPathUnitTests.java
@@ -21,6 +21,7 @@
import java.util.Arrays;
import java.util.Collections;
+import java.util.List;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -40,7 +41,7 @@
@ExtendWith(MockitoExtension.class)
class DefaultPersistentPropertyPathUnitTests > {
- @Mock P first, second;
+ @Mock P first, second, third;
@Mock Converter converter;
@@ -58,6 +59,65 @@ void rejectsNullProperties() {
assertThatIllegalArgumentException().isThrownBy(() -> new DefaultPersistentPropertyPath<>(null));
}
+ @Test
+ void getCommonBaseTestEmpty() {
+ DefaultPersistentPropertyPath propertyPath = new DefaultPersistentPropertyPath<>(List.of(first, second));
+
+ assertThat(propertyPath.getCommonBaseWith(DefaultPersistentPropertyPath.empty())).isEmpty();
+ }
+
+ @Test
+ void getCommonBaseTestNoCommonBase() {
+ DefaultPersistentPropertyPath propertyPath = new DefaultPersistentPropertyPath<>(List.of(first));
+
+ assertThat(propertyPath.getCommonBaseWith(new DefaultPersistentPropertyPath<>(List.of(second)))).isEmpty();
+ }
+
+ @Test
+ void getCommonBaseTestCommonBasePresentInPassed() {
+ DefaultPersistentPropertyPath propertyPath = new DefaultPersistentPropertyPath<>(List.of(first));
+
+ assertThat(propertyPath.getCommonBaseWith(new DefaultPersistentPropertyPath<>(List.of(first, second)))).isEqualTo(propertyPath);
+ }
+
+ @Test
+ void getCommonBaseTestCommonBasePresentInThis() {
+ DefaultPersistentPropertyPath propertyPath = new DefaultPersistentPropertyPath<>(List.of(first, second));
+
+ DefaultPersistentPropertyPath anotherPath = new DefaultPersistentPropertyPath<>(List.of(first));
+
+ assertThat(propertyPath.getCommonBaseWith(anotherPath)).isEqualTo(anotherPath);
+ }
+
+ @Test
+ void getCommonBaseTestTheSamePath() {
+ DefaultPersistentPropertyPath propertyPath = new DefaultPersistentPropertyPath<>(List.of(first, second));
+
+ DefaultPersistentPropertyPath anotherPath = new DefaultPersistentPropertyPath<>(List.of(first, second));
+
+ assertThat(propertyPath.getCommonBaseWith(anotherPath)).isEqualTo(anotherPath);
+ }
+
+ @Test
+ void getCommonBaseTestHasSamePropertiesInDifferentOrder() {
+ DefaultPersistentPropertyPath propertyPath = new DefaultPersistentPropertyPath<>(List.of(first, second));
+
+ DefaultPersistentPropertyPath anotherPath = new DefaultPersistentPropertyPath<>(List.of(second, first));
+
+ assertThat(propertyPath.getCommonBaseWith(anotherPath)).isEqualTo(DefaultPersistentPropertyPath.empty());
+ }
+
+
+ @Test
+ void getCommonBaseTestHasSamePropertiesButNotInBase() {
+ DefaultPersistentPropertyPath propertyPath = new DefaultPersistentPropertyPath<>(List.of(first, second));
+
+ DefaultPersistentPropertyPath anotherPath = new DefaultPersistentPropertyPath<>(List.of(third, second));
+
+ assertThat(propertyPath.getCommonBaseWith(anotherPath)).isEqualTo(DefaultPersistentPropertyPath.empty());
+ }
+
+
@Test
void usesPropertyNameForSimpleDotPath() {