1
16 package org.modelmapper.internal.converter;
17
18 import net.jodah.typetools.TypeResolver;
19 import org.modelmapper.internal.util.Types;
20 import org.modelmapper.spi.*;
21
22 import java.lang.reflect.ParameterizedType;
23 import java.util.Optional;
24
25
28 class OptionalConverter implements ConditionalConverter<Optional<?>, Optional<?>> {
29 @Override
30 public MatchResult match(Class<?> sourceType, Class<?> destinationType) {
31 return (Optional.class.equals(sourceType) && Optional.class.equals(destinationType))
32 ? MatchResult.FULL
33 : MatchResult.NONE;
34 }
35
36 @Override
37 @SuppressWarnings("all")
38 public Optional<?> convert(MappingContext<Optional<?>, Optional<?>> mappingContext) {
39 Class<?> optionalType = getElementType(mappingContext);
40 Optional<?> source = mappingContext.getSource();
41 if (source == null) {
42 return null;
43 } else if (source.isPresent()) {
44 MappingContext<?, ?> optionalContext = mappingContext.create(source.get(), optionalType);
45 return Optional.ofNullable(mappingContext.getMappingEngine().map(optionalContext));
46 } else {
47 return Optional.empty();
48 }
49 }
50
51
52 private Class<?> getElementType(MappingContext<Optional<?>, Optional<?>> mappingContext) {
53 Mapping mapping = mappingContext.getMapping();
54 if (mapping instanceof PropertyMapping) {
55 PropertyInfo destInfo = mapping.getLastDestinationProperty();
56 Class<?> elementType = TypeResolver.resolveRawArgument(destInfo.getGenericType(),
57 destInfo.getInitialType());
58 return elementType == TypeResolver.Unknown.class ? Object.class : elementType;
59 } else if (mappingContext.getGenericDestinationType() instanceof ParameterizedType) {
60 return Types.rawTypeFor(((ParameterizedType) mappingContext.getGenericDestinationType()).getActualTypeArguments()[0]);
61 }
62
63 return Object.class;
64 }
65
66 }
67