/** * Performs mapping using a TypeMap if one exists, else a converter if one applies, else a newly * created TypeMap. Recursive entry point. */ public <S, D> D map(MappingContext<S, D> context) { MappingContextImpl<S, D> contextImpl = (MappingContextImpl<S, D>) context; Class<D> destinationType = context.getDestinationType(); // Resolve some circular dependencies if (!Iterables.isIterable(destinationType)) { D circularDest = contextImpl.destinationForSource(); if (circularDest != null) return circularDest; } D destination = null; TypeMap<S, D> typeMap = typeMapStore.get(context.getSourceType(), context.getDestinationType()); if (typeMap != null) { destination = typeMap(contextImpl, typeMap); } else { Converter<S, D> converter = converterFor(context); if (converter != null) { destination = convert(context, converter); } else { // Call getOrCreate in case TypeMap was created concurrently typeMap = typeMapStore.getOrCreate(context.getSourceType(), context.getDestinationType(), this); destination = typeMap(contextImpl, typeMap); } } return destination; }
@SuppressWarnings("unchecked") private Object resolveSourceValue(MappingContextImpl<?, ?> context, Mapping mapping) { Object source = context.getSource(); if (mapping instanceof PropertyMappingImpl) { for (Accessor accessor : (List<Accessor>) ((PropertyMapping) mapping).getSourceProperties()) { context.setParentSource(source); source = accessor.getValue(source); if (source == null) return null; if (!Iterables.isIterable(source.getClass())) { Object circularDest = context.sourceToDestination.get(source); if (circularDest != null) context.intermediateDestinations.add(circularDest); } } } else if (mapping instanceof ConstantMapping) source = ((ConstantMapping) mapping).getConstant(); return source; }