Skip to content

Commit 5f117a0

Browse files
committed
DATACMNS-867 - Polishing of Property value type in mapping package.
1 parent baccb41 commit 5f117a0

File tree

3 files changed

+79
-15
lines changed

3 files changed

+79
-15
lines changed

src/main/java/org/springframework/data/mapping/context/AbstractMappingContext.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -520,7 +520,12 @@ public void doWith(Field field) {
520520
String fieldName = field.getName();
521521

522522
ReflectionUtils.makeAccessible(field);
523-
createAndRegisterProperty(Property.of(field, Optional.ofNullable(descriptors.get(fieldName))));
523+
524+
Property property = Optional.ofNullable(descriptors.get(fieldName))//
525+
.map(it -> Property.of(field, it))//
526+
.orElseGet(() -> Property.of(field));
527+
528+
createAndRegisterProperty(property);
524529

525530
this.remainingDescriptors.remove(fieldName);
526531
}

src/main/java/org/springframework/data/mapping/model/Property.java

Lines changed: 63 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
package org.springframework.data.mapping.model;
1717

1818
import lombok.Getter;
19-
import lombok.RequiredArgsConstructor;
2019

2120
import java.beans.FeatureDescriptor;
2221
import java.beans.PropertyDescriptor;
@@ -28,10 +27,11 @@
2827
import org.springframework.util.Assert;
2928

3029
/**
30+
* Value object to abstract the concept of a property backed by a {@link Field} and / or a {@link PropertyDescriptor}.
31+
*
3132
* @author Oliver Gierke
3233
* @author Christoph Strobl
3334
*/
34-
@RequiredArgsConstructor
3535
public class Property {
3636

3737
private final @Getter Optional<Field> field;
@@ -45,54 +45,107 @@ private Property(Optional<Field> field, Optional<PropertyDescriptor> descriptor)
4545
this.field = field;
4646
this.descriptor = descriptor;
4747
this.hashCode = Lazy.of(this::computeHashCode);
48-
this.rawType = Lazy
49-
.of(() -> field.<Class<?>>map(Field::getType).orElseGet(() -> descriptor.map(PropertyDescriptor::getPropertyType)//
48+
this.rawType = Lazy.of(
49+
() -> field.<Class<?>> map(Field::getType).orElseGet(() -> descriptor.map(PropertyDescriptor::getPropertyType)//
5050
.orElseThrow(IllegalStateException::new)));
5151
}
5252

53+
/**
54+
* Creates a new {@link Property} backed by the given field.
55+
*
56+
* @param field must not be {@literal null}.
57+
* @return
58+
*/
5359
public static Property of(Field field) {
54-
return of(field, Optional.empty());
60+
61+
Assert.notNull(field, "Field must not be null!");
62+
63+
return new Property(Optional.of(field), Optional.empty());
5564
}
5665

57-
public static Property of(Field field, Optional<PropertyDescriptor> descriptor) {
66+
/**
67+
* Creates a new {@link Property} backed by the given {@link Field} and {@link PropertyDescriptor}.
68+
*
69+
* @param field must not be {@literal null}.
70+
* @param descriptor must not be {@literal null}.
71+
* @return
72+
*/
73+
public static Property of(Field field, PropertyDescriptor descriptor) {
5874

5975
Assert.notNull(field, "Field must not be null!");
76+
Assert.notNull(descriptor, "PropertyDescriptor must not be null!");
6077

61-
return new Property(Optional.of(field), descriptor);
78+
return new Property(Optional.of(field), Optional.of(descriptor));
6279
}
6380

81+
/**
82+
* Creates a new {@link Property} for the given {@link PropertyDescriptor}.
83+
*
84+
* @param descriptor must not be {@literal null}.
85+
* @return
86+
*/
6487
public static Property of(PropertyDescriptor descriptor) {
6588

6689
Assert.notNull(descriptor, "PropertyDescriptor must not be null!");
90+
6791
return new Property(Optional.empty(), Optional.of(descriptor));
6892
}
6993

94+
/**
95+
* Returns whether the property is backed by a field.
96+
*
97+
* @return
98+
*/
7099
public boolean isFieldBacked() {
71100
return field.isPresent();
72101
}
73102

103+
/**
104+
* Returns the getter of the property if available and if it matches the type of the property.
105+
*
106+
* @return will never be {@literal null}.
107+
*/
74108
public Optional<Method> getGetter() {
75109
return descriptor.map(PropertyDescriptor::getReadMethod)//
76110
.filter(it -> getType().isAssignableFrom(it.getReturnType()));
77111
}
78112

113+
/**
114+
* Returns the setter of the property if available and if its first (only) parameter matches the type of the property.
115+
*
116+
* @return will never be {@literal null}.
117+
*/
79118
public Optional<Method> getSetter() {
80119
return descriptor.map(PropertyDescriptor::getWriteMethod)//
81120
.filter(it -> it.getParameterTypes()[0].isAssignableFrom(getType()));
82121
}
83122

123+
/**
124+
* Returns whether the property exposes a getter or a setter.
125+
*
126+
* @return
127+
*/
84128
public boolean hasAccessor() {
85129
return getGetter().isPresent() || getSetter().isPresent();
86130
}
87131

88132
/**
89-
* @return
133+
* Returns the name of the property.
134+
*
135+
* @return will never be {@literal null}.
90136
*/
91137
public String getName() {
92-
return field.map(Field::getName).orElseGet(() -> descriptor.map(FeatureDescriptor::getName)//
93-
.orElseThrow(IllegalStateException::new));
138+
139+
return field.map(Field::getName)//
140+
.orElseGet(() -> descriptor.map(FeatureDescriptor::getName)//
141+
.orElseThrow(IllegalStateException::new));
94142
}
95143

144+
/**
145+
* Returns the type of the property.
146+
*
147+
* @return will never be {@literal null}.
148+
*/
96149
public Class<?> getType() {
97150
return rawType.get();
98151
}

src/test/java/org/springframework/data/mapping/model/AbstractPersistentPropertyUnitTests.java

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -207,10 +207,16 @@ private <T> BasicPersistentEntity<T, SamplePersistentProperty> getEntity(Class<T
207207
private <T> SamplePersistentProperty getProperty(Class<T> type, String name) {
208208

209209
Optional<Field> field = Optional.ofNullable(ReflectionUtils.findField(type, name));
210-
211-
Property property = field.map(it -> Property.of(it, getPropertyDescriptor(type, name)))
212-
.orElseGet(() -> Property.of(getPropertyDescriptor(type, name).orElseThrow(
213-
() -> new IllegalArgumentException(String.format("Couldn't find property %s on %s!", name, type)))));
210+
Optional<PropertyDescriptor> descriptor = getPropertyDescriptor(type, name);
211+
212+
Property property = field
213+
.map(it -> descriptor//
214+
.map(foo -> Property.of(it, foo))//
215+
.orElseGet(() -> Property.of(it)))
216+
.orElseGet(() -> getPropertyDescriptor(type, name)//
217+
.map(it -> Property.of(it))//
218+
.orElseThrow(
219+
() -> new IllegalArgumentException(String.format("Couldn't find property %s on %s!", name, type))));
214220

215221
return new SamplePersistentProperty(property, getEntity(type), typeHolder);
216222
}

0 commit comments

Comments
 (0)