Skip to content

Commit e9b52ef

Browse files
authored
Merge pull request #502 from AuthMe/479-move-return-null-constant
#479 Move RETURN_NULL constant from MapperImpl to LeafValueHandler
2 parents 98131fc + 5f90ac8 commit e9b52ef

File tree

4 files changed

+49
-13
lines changed

4 files changed

+49
-13
lines changed

src/main/java/ch/jalu/configme/beanmapper/MapperImpl.java

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,6 @@
6666
*/
6767
public class MapperImpl implements Mapper {
6868

69-
/** Marker object to signal that null is meant to be used as value. */
70-
public static final Object RETURN_NULL = new Object();
71-
7269
// ---------
7370
// Fields and general configurable methods
7471
// ---------
@@ -125,13 +122,13 @@ public MapperImpl(@NotNull BeanDefinitionService beanDefinitionService,
125122
// Step 1: attempt simple value transformation
126123
Object exportValue = leafValueHandler.toExportValue(value, exportContext);
127124
if (exportValue != null || value == null) {
128-
return unwrapReturnNull(exportValue);
125+
return LeafValueHandler.unwrapReturnNull(exportValue);
129126
}
130127

131128
// Step 2: handle special cases like Collection
132129
exportValue = createExportValueForSpecialTypes(value, exportContext);
133130
if (exportValue != null) {
134-
return unwrapReturnNull(exportValue);
131+
return LeafValueHandler.unwrapReturnNull(exportValue);
135132
}
136133

137134
// Step 3: treat as bean
@@ -159,12 +156,12 @@ public MapperImpl(@NotNull BeanDefinitionService beanDefinitionService,
159156

160157
/**
161158
* Handles values of types which need special handling (such as Optional). Null means the value is not
162-
* a special type and that the export value should be built differently. Use {@link #RETURN_NULL} to
159+
* a special type and that the export value should be built differently. Use {@link LeafValueHandler#RETURN_NULL} to
163160
* signal that null should be used as the export value of the provided value.
164161
*
165162
* @param value the value to convert
166163
* @param exportContext export context
167-
* @return the export value to use or {@link #RETURN_NULL}, or null if not applicable
164+
* @return the export value to use or {@link LeafValueHandler#RETURN_NULL}, or null if not applicable
168165
*/
169166
protected @Nullable Object createExportValueForSpecialTypes(@Nullable Object value,
170167
@NotNull ExportContext exportContext) {
@@ -192,16 +189,12 @@ public MapperImpl(@NotNull BeanDefinitionService beanDefinitionService,
192189
Optional<?> optional = (Optional<?>) value;
193190
return optional
194191
.map(v -> toExportValue(v, exportContext.createChildContext(OPTIONAL_SPECIFIER)))
195-
.orElse(RETURN_NULL);
192+
.orElse(LeafValueHandler.RETURN_NULL);
196193
}
197194

198195
return null;
199196
}
200197

201-
protected static @Nullable Object unwrapReturnNull(@Nullable Object o) {
202-
return o == RETURN_NULL ? null : o;
203-
}
204-
205198
// ---------
206199
// Bean mapping
207200
// ---------

src/main/java/ch/jalu/configme/beanmapper/leafvaluehandler/LeafValueHandler.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@
2020
*/
2121
public interface LeafValueHandler {
2222

23+
/** Marker object to signal that null is meant to be used as value. */
24+
Object RETURN_NULL = new Object();
25+
2326
/**
2427
* Converts the given value to the target type (as defined by the mapping context), if supported. Otherwise,
2528
* null is returned. If a value is returned, its type is guaranteed to match the target type.
@@ -33,11 +36,25 @@ public interface LeafValueHandler {
3336
/**
3437
* Converts the value of a property to a value suitable for exporting. This method converts the opposite
3538
* way of {@link #convert}. Null is returned if this leaf value handler does not support the object's type.
39+
* If the leaf value handler determines that {@code null} should be used as export value, then {@link #RETURN_NULL}
40+
* is returned, which the caller needs to unwrap to {@code null}.
3641
*
3742
* @param value the value to convert
3843
* @param exportContext the export context (usually not needed)
3944
* @return the value suitable for exporting, or null if not applicable
4045
*/
4146
@Nullable Object toExportValue(@Nullable Object value, @NotNull ExportContext exportContext);
4247

48+
/**
49+
* Returns null if the object is {@link #RETURN_NULL}, otherwise the given object. Used to process return values
50+
* from methods like {@link #toExportValue}, where {@code null} means the instance doesn't support the value,
51+
* while {@link #RETURN_NULL} means null should be used as export value.
52+
*
53+
* @param object the object to potentially unwrap
54+
* @param <T> the object type
55+
* @return null, or the provided object
56+
*/
57+
static <T> @Nullable T unwrapReturnNull(@Nullable T object) {
58+
return object == RETURN_NULL ? null : object;
59+
}
4360
}

src/main/java/ch/jalu/configme/beanmapper/leafvaluehandler/MapperLeafType.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public interface MapperLeafType {
3030
* when {@link ch.jalu.configme.beanmapper.MapperImpl#toExportValue(Object)} is called.
3131
* Returns null if the leaf value handler cannot handle the value.
3232
* <p>
33-
* Return {@link ch.jalu.configme.beanmapper.MapperImpl#RETURN_NULL} to signal that null should be used
33+
* Return {@link LeafValueHandler#RETURN_NULL} to signal that null should be used
3434
* as the export value (returning {@code null} itself means this leaf value handler cannot handle it).
3535
*
3636
* @param value the value to convert to an export value, if possible
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package ch.jalu.configme.beanmapper.leafvaluehandler;
2+
3+
import org.junit.jupiter.api.Test;
4+
5+
import java.util.concurrent.TimeUnit;
6+
7+
import static org.hamcrest.MatcherAssert.assertThat;
8+
import static org.hamcrest.Matchers.equalTo;
9+
import static org.hamcrest.Matchers.nullValue;
10+
11+
/**
12+
* Test for {@link LeafValueHandler}.
13+
*/
14+
class LeafValueHandlerTest {
15+
16+
@Test
17+
void shouldUnwrapReturnNull() {
18+
// given / when / then
19+
assertThat(LeafValueHandler.unwrapReturnNull(null), nullValue());
20+
assertThat(LeafValueHandler.unwrapReturnNull(LeafValueHandler.RETURN_NULL), nullValue());
21+
22+
assertThat(LeafValueHandler.unwrapReturnNull("null"), equalTo("null"));
23+
assertThat(LeafValueHandler.unwrapReturnNull(TimeUnit.SECONDS), equalTo(TimeUnit.SECONDS));
24+
assertThat(LeafValueHandler.unwrapReturnNull(12), equalTo(12));
25+
}
26+
}

0 commit comments

Comments
 (0)