public boolean canInheritFrom(SourceMethod method) { return isMapMapping() == method.isMapMapping() && isIterableMapping() == method.isIterableMapping() && isEnumMapping() == method.isEnumMapping() && getResultType().isAssignableTo(method.getResultType()) && allParametersAreAssignable(getSourceParameters(), method.getSourceParameters()); }
private void reportErrorWhenAmbigousReverseMapping( List<SourceMethod> candidates, SourceMethod method, InheritInverseConfigurationPrism reversePrism) { List<String> candidateNames = new ArrayList<String>(); for (SourceMethod candidate : candidates) { candidateNames.add(candidate.getName()); } String name = reversePrism.name(); if (name.isEmpty()) { messager.printMessage( method.getExecutable(), reversePrism.mirror, Message.INHERITINVERSECONFIGURATION_DUPLICATES, Strings.join(candidateNames, "(), ")); } else { messager.printMessage( method.getExecutable(), reversePrism.mirror, Message.INHERITINVERSECONFIGURATION_INVALID_NAME, Strings.join(candidateNames, "(), "), name); } }
public boolean isSame(SourceMethod method) { return getSourceParameters().size() == 1 && method.getSourceParameters().size() == 1 && equals( first(getSourceParameters()).getType(), first(method.getSourceParameters()).getType()) && equals(getResultType(), method.getResultType()); }
private void reportErrorWhenInheritForwardAlsoHasInheritReverseMapping(SourceMethod method) { InheritInverseConfigurationPrism reversePrism = InheritInverseConfigurationPrism.getInstanceOn(method.getExecutable()); if (reversePrism != null) { messager.printMessage( method.getExecutable(), reversePrism.mirror, Message.INHERITCONFIGURATION_BOTH); } }
private void reportErrorIfNoImplementationTypeIsRegisteredForInterfaceReturnType( SourceMethod method) { if (method.getReturnType().getTypeMirror().getKind() != TypeKind.VOID && method.getReturnType().isInterface() && method.getReturnType().getImplementationType() == null) { messager.printMessage( method.getExecutable(), Message.GENERAL_NO_IMPLEMENTATION, method.getReturnType()); } }
private void mergeInheritedOptions( SourceMethod method, MapperConfiguration mapperConfig, List<SourceMethod> availableMethods, List<SourceMethod> initializingMethods) { if (initializingMethods.contains(method)) { // cycle detected initializingMethods.add(method); messager.printMessage( method.getExecutable(), Message.INHERITCONFIGURATION_CYCLE, Strings.join(initializingMethods, " -> ")); return; } initializingMethods.add(method); MappingOptions mappingOptions = method.getMappingOptions(); List<SourceMethod> applicablePrototypeMethods = method.getApplicablePrototypeMethods(); MappingOptions inverseMappingOptions = getInverseMappingOptions(availableMethods, method, initializingMethods, mapperConfig); MappingOptions templateMappingOptions = getTemplateMappingOptions( join(availableMethods, applicablePrototypeMethods), method, initializingMethods, mapperConfig); if (templateMappingOptions != null) { mappingOptions.applyInheritedOptions( templateMappingOptions, false, method, messager, typeFactory); } else if (inverseMappingOptions != null) { mappingOptions.applyInheritedOptions( inverseMappingOptions, true, method, messager, typeFactory); } else if (mapperConfig.getMappingInheritanceStrategy() == AUTO_INHERIT_FROM_CONFIG) { if (applicablePrototypeMethods.size() == 1) { mappingOptions.applyInheritedOptions( first(applicablePrototypeMethods).getMappingOptions(), false, method, messager, typeFactory); } else if (applicablePrototypeMethods.size() > 1) { messager.printMessage( method.getExecutable(), Message.INHERITCONFIGURATION_MULTIPLE_PROTOTYPE_METHODS_MATCH, Strings.join(applicablePrototypeMethods, ", ")); } } mappingOptions.markAsFullyInitialized(); }
private static List<SourceMethod> filterAfterMappingMethods(List<SourceMethod> methods) { List<SourceMethod> result = new ArrayList<SourceMethod>(); for (SourceMethod method : methods) { if (method.isAfterMappingMethod()) { result.add(method); } } return result; }
private void reportErrorWhenNonMatchingName( SourceMethod onlyCandidate, SourceMethod method, InheritConfigurationPrism prims) { messager.printMessage( method.getExecutable(), prims.mirror, Message.INHERITCONFIGURATION_NO_NAME_MATCH, prims.name(), onlyCandidate.getName()); }
private void reportErrorWhenNonMatchingName( SourceMethod onlyCandidate, SourceMethod method, InheritInverseConfigurationPrism reversePrism) { messager.printMessage( method.getExecutable(), reversePrism.mirror, Message.INHERITINVERSECONFIGURATION_NO_NAME_MATCH, reversePrism.name(), onlyCandidate.getName()); }
private static boolean isValidCandidate( SourceMethod candidate, Method method, List<Parameter> parameterAssignments) { if (parameterAssignments == null) { return false; } if (!candidate.matches(extractSourceTypes(parameterAssignments), method.getResultType())) { return false; } return (candidate.getReturnType().isVoid() || candidate.getReturnType().isTypeVar() || candidate.getReturnType().isAssignableTo(method.getResultType())); }
/** * Returns the configuring inverse method's options in case the given method is annotated with * {@code @InheritInverseConfiguration} and exactly one such configuring method can unambiguously * be selected (as per the source/target type and optionally the name given via * {@code @InheritInverseConfiguration}). */ private MappingOptions getInverseMappingOptions( List<SourceMethod> rawMethods, SourceMethod method, List<SourceMethod> initializingMethods, MapperConfiguration mapperConfig) { SourceMethod resultMethod = null; InheritInverseConfigurationPrism reversePrism = InheritInverseConfigurationPrism.getInstanceOn(method.getExecutable()); if (reversePrism != null) { // method is configured as being reverse method, collect candidates List<SourceMethod> candidates = new ArrayList<SourceMethod>(); for (SourceMethod oneMethod : rawMethods) { if (oneMethod.reverses(method)) { candidates.add(oneMethod); } } String name = reversePrism.name(); if (candidates.size() == 1) { // no ambiguity: if no configuredBy is specified, or configuredBy specified and match if (name.isEmpty()) { resultMethod = candidates.get(0); } else if (candidates.get(0).getName().equals(name)) { resultMethod = candidates.get(0); } else { reportErrorWhenNonMatchingName(candidates.get(0), method, reversePrism); } } else if (candidates.size() > 1) { // ambiguity: find a matching method that matches configuredBy List<SourceMethod> nameFilteredcandidates = new ArrayList<SourceMethod>(); for (SourceMethod candidate : candidates) { if (candidate.getName().equals(name)) { nameFilteredcandidates.add(candidate); } } if (nameFilteredcandidates.size() == 1) { resultMethod = nameFilteredcandidates.get(0); } else if (nameFilteredcandidates.size() > 1) { reportErrorWhenSeveralNamesMatch(nameFilteredcandidates, method, reversePrism); } else { reportErrorWhenAmbigousReverseMapping(candidates, method, reversePrism); } } } return extractInitializedOptions(resultMethod, rawMethods, mapperConfig, initializingMethods); }
private MappingOptions extractInitializedOptions( SourceMethod resultMethod, List<SourceMethod> rawMethods, MapperConfiguration mapperConfig, List<SourceMethod> initializingMethods) { if (resultMethod != null) { if (!resultMethod.getMappingOptions().isFullyInitialized()) { mergeInheritedOptions(resultMethod, mapperConfig, rawMethods, initializingMethods); } return resultMethod.getMappingOptions(); } return null; }
private void reportMappingError(Message msg, Object... objects) { messager.printMessage( method.getExecutable(), mapping.getMirror(), mapping.getSourceAnnotationValue(), msg, objects); }
private void reportErrorWhenNoSuitableConstrutor( SourceMethod method, InheritInverseConfigurationPrism reversePrism) { messager.printMessage( method.getExecutable(), reversePrism.mirror, Message.INHERITINVERSECONFIGURATION_NO_SUITABLE_CONSTRUCTOR, reversePrism.name()); }
private void reportErrorWhenSeveralNamesMatch( List<SourceMethod> candidates, SourceMethod method, InheritConfigurationPrism prism) { messager.printMessage( method.getExecutable(), prism.mirror, Message.INHERITCONFIGURATION_DUPLICATE_MATCHES, prism.name(), Strings.join(candidates, ", ")); }
/** * Returns the configuring forward method's options in case the given method is annotated with * {@code @InheritConfiguration} and exactly one such configuring method can unambiguously be * selected (as per the source/target type and optionally the name given via * {@code @InheritConfiguration}). The method cannot be marked forward mapping itself (hence * 'ohter'). And neither can it contain an {@code @InheritReverseConfiguration} */ private MappingOptions getTemplateMappingOptions( List<SourceMethod> rawMethods, SourceMethod method, List<SourceMethod> initializingMethods, MapperConfiguration mapperConfig) { SourceMethod resultMethod = null; InheritConfigurationPrism forwardPrism = InheritConfigurationPrism.getInstanceOn(method.getExecutable()); if (forwardPrism != null) { reportErrorWhenInheritForwardAlsoHasInheritReverseMapping(method); List<SourceMethod> candidates = new ArrayList<SourceMethod>(); for (SourceMethod oneMethod : rawMethods) { // method must be similar but not equal if (method.canInheritFrom(oneMethod) && !(oneMethod.equals(method))) { candidates.add(oneMethod); } } String name = forwardPrism.name(); if (candidates.size() == 1) { // no ambiguity: if no configuredBy is specified, or configuredBy specified and match SourceMethod sourceMethod = first(candidates); if (name.isEmpty()) { resultMethod = sourceMethod; } else if (sourceMethod.getName().equals(name)) { resultMethod = sourceMethod; } else { reportErrorWhenNonMatchingName(sourceMethod, method, forwardPrism); } } else if (candidates.size() > 1) { // ambiguity: find a matching method that matches configuredBy List<SourceMethod> nameFilteredcandidates = new ArrayList<SourceMethod>(); for (SourceMethod candidate : candidates) { if (candidate.getName().equals(name)) { nameFilteredcandidates.add(candidate); } } if (nameFilteredcandidates.size() == 1) { resultMethod = first(nameFilteredcandidates); } else if (nameFilteredcandidates.size() > 1) { reportErrorWhenSeveralNamesMatch(nameFilteredcandidates, method, forwardPrism); } else { reportErrorWhenAmbigousMapping(candidates, method, forwardPrism); } } } return extractInitializedOptions(resultMethod, rawMethods, mapperConfig, initializingMethods); }
private static List<SourceMethod> filterCandidatesByType( Method method, List<SourceMethod> callbackMethods, Map<SourceMethod, List<Parameter>> parameterAssignmentsForSourceMethod, MappingBuilderContext ctx) { List<SourceMethod> candidates = new ArrayList<SourceMethod>(); List<Parameter> availableParams = getAvailableParameters(method, ctx); for (SourceMethod callback : callbackMethods) { List<Parameter> parameterAssignments = ParameterAssignmentUtil.getParameterAssignments( availableParams, callback.getParameters()); if (isValidCandidate(callback, method, parameterAssignments)) { parameterAssignmentsForSourceMethod.put(callback, parameterAssignments); candidates.add(callback); } } return candidates; }
/** * Creates a copy of this reference, which is adapted to the given method * * @param method the method to create the copy for * @return the copy */ public SourceReference copyForInheritanceTo(SourceMethod method) { List<Parameter> replacementParamCandidates = new ArrayList<Parameter>(); for (Parameter sourceParam : method.getSourceParameters()) { if (sourceParam.getType().isAssignableTo(parameter.getType())) { replacementParamCandidates.add(sourceParam); } } Parameter replacement = parameter; if (replacementParamCandidates.size() == 1) { replacement = first(replacementParamCandidates); } return new SourceReference(replacement, propertyEntries, isValid); }
public LifecycleCallbackMethodReference( SourceMethod method, MapperReference mapperReference, List<ParameterBinding> parameterBindings, Type methodReturnType, Type methodResultType, Set<String> existingVariableNames) { super(method, mapperReference, parameterBindings); this.declaringType = method.getDeclaringMapper(); this.methodReturnType = methodReturnType; this.methodResultType = methodResultType; if (hasReturnType()) { this.targetVariableName = Strings.getSaveVariableName("target", existingVariableNames); existingVariableNames.add(this.targetVariableName); } else { this.targetVariableName = null; } }
private Decorator getDecorator( TypeElement element, List<SourceMethod> methods, String implName, String implPackage) { DecoratedWithPrism decoratorPrism = DecoratedWithPrism.getInstanceOn(element); if (decoratorPrism == null) { return null; } TypeElement decoratorElement = (TypeElement) typeUtils.asElement(decoratorPrism.value()); if (!typeUtils.isAssignable(decoratorElement.asType(), element.asType())) { messager.printMessage(element, decoratorPrism.mirror, Message.DECORATOR_NO_SUBTYPE); } List<MappingMethod> mappingMethods = new ArrayList<MappingMethod>(methods.size()); for (SourceMethod mappingMethod : methods) { boolean implementationRequired = true; for (ExecutableElement method : ElementFilter.methodsIn(decoratorElement.getEnclosedElements())) { if (elementUtils.overrides(method, mappingMethod.getExecutable(), decoratorElement)) { implementationRequired = false; break; } } Type declaringMapper = mappingMethod.getDeclaringMapper(); if (implementationRequired && !(mappingMethod.isDefault() || mappingMethod.isStatic())) { if ((declaringMapper == null) || declaringMapper.equals(typeFactory.getType(element))) { mappingMethods.add(new DelegatingMethod(mappingMethod)); } } } boolean hasDelegateConstructor = false; boolean hasDefaultConstructor = false; for (ExecutableElement constructor : ElementFilter.constructorsIn(decoratorElement.getEnclosedElements())) { if (constructor.getParameters().isEmpty()) { hasDefaultConstructor = true; } else if (constructor.getParameters().size() == 1) { if (typeUtils.isAssignable(element.asType(), first(constructor.getParameters()).asType())) { hasDelegateConstructor = true; } } } if (!hasDelegateConstructor && !hasDefaultConstructor) { messager.printMessage(element, decoratorPrism.mirror, Message.DECORATOR_CONSTRUCTOR); } Decorator decorator = new Decorator.Builder() .elementUtils(elementUtils) .typeFactory(typeFactory) .mapperElement(element) .decoratorPrism(decoratorPrism) .methods(mappingMethods) .hasDelegateConstructor(hasDelegateConstructor) .options(options) .versionInformation(versionInformation) .implName(implName) .implPackage(implPackage) .extraImports(getExtraImports(element)) .build(); return decorator; }
private List<MappingMethod> getMappingMethods( MapperConfiguration mapperConfig, List<SourceMethod> methods) { List<MappingMethod> mappingMethods = new ArrayList<MappingMethod>(); for (SourceMethod method : methods) { if (!method.overridesMethod()) { continue; } mergeInheritedOptions(method, mapperConfig, methods, new ArrayList<SourceMethod>()); MappingOptions mappingOptions = method.getMappingOptions(); boolean hasFactoryMethod = false; if (method.isIterableMapping()) { IterableMappingMethod.Builder builder = new IterableMappingMethod.Builder(); FormattingParameters formattingParameters = null; SelectionParameters selectionParameters = null; NullValueMappingStrategyPrism nullValueMappingStrategy = null; if (mappingOptions.getIterableMapping() != null) { formattingParameters = mappingOptions.getIterableMapping().getFormattingParameters(); selectionParameters = mappingOptions.getIterableMapping().getSelectionParameters(); nullValueMappingStrategy = mappingOptions.getIterableMapping().getNullValueMappingStrategy(); } IterableMappingMethod iterableMappingMethod = builder .mappingContext(mappingContext) .method(method) .formattingParameters(formattingParameters) .selectionParameters(selectionParameters) .nullValueMappingStrategy(nullValueMappingStrategy) .build(); hasFactoryMethod = iterableMappingMethod.getFactoryMethod() != null; mappingMethods.add(iterableMappingMethod); } else if (method.isMapMapping()) { MapMappingMethod.Builder builder = new MapMappingMethod.Builder(); SelectionParameters keySelectionParameters = null; FormattingParameters keyFormattingParameters = null; SelectionParameters valueSelectionParameters = null; FormattingParameters valueFormattingParameters = null; NullValueMappingStrategyPrism nullValueMappingStrategy = null; if (mappingOptions.getMapMapping() != null) { keySelectionParameters = mappingOptions.getMapMapping().getKeySelectionParameters(); keyFormattingParameters = mappingOptions.getMapMapping().getKeyFormattingParameters(); valueSelectionParameters = mappingOptions.getMapMapping().getValueSelectionParameters(); valueFormattingParameters = mappingOptions.getMapMapping().getValueFormattingParameters(); nullValueMappingStrategy = mappingOptions.getMapMapping().getNullValueMappingStrategy(); } MapMappingMethod mapMappingMethod = builder .mappingContext(mappingContext) .method(method) .keyFormattingParameters(keyFormattingParameters) .keySelectionParameters(keySelectionParameters) .valueFormattingParameters(valueFormattingParameters) .valueSelectionParameters(valueSelectionParameters) .nullValueMappingStrategy(nullValueMappingStrategy) .build(); hasFactoryMethod = mapMappingMethod.getFactoryMethod() != null; mappingMethods.add(mapMappingMethod); } else if (method.isValueMapping()) { // prefer value mappings over enum mapping ValueMappingMethod valueMappingMethod = new ValueMappingMethod.Builder() .mappingContext(mappingContext) .souceMethod(method) .valueMappings(mappingOptions.getValueMappings()) .build(); mappingMethods.add(valueMappingMethod); } else if (method.isEnumMapping()) { messager.printMessage(method.getExecutable(), Message.ENUMMAPPING_DEPRECATED); EnumMappingMethod.Builder builder = new EnumMappingMethod.Builder(); MappingMethod enumMappingMethod = builder.mappingContext(mappingContext).souceMethod(method).build(); if (enumMappingMethod != null) { mappingMethods.add(enumMappingMethod); } } else { NullValueMappingStrategyPrism nullValueMappingStrategy = null; SelectionParameters selectionParameters = null; if (mappingOptions.getBeanMapping() != null) { nullValueMappingStrategy = mappingOptions.getBeanMapping().getNullValueMappingStrategy(); selectionParameters = mappingOptions.getBeanMapping().getSelectionParameters(); } BeanMappingMethod.Builder builder = new BeanMappingMethod.Builder(); BeanMappingMethod beanMappingMethod = builder .mappingContext(mappingContext) .souceMethod(method) .nullValueMappingStrategy(nullValueMappingStrategy) .selectionParameters(selectionParameters) .build(); if (beanMappingMethod != null) { hasFactoryMethod = beanMappingMethod.getFactoryMethod() != null; mappingMethods.add(beanMappingMethod); } } if (!hasFactoryMethod) { // A factory method is allowed to return an interface type and hence, the generated // implementation as well. The check below must only be executed if there's no factory // method that could be responsible. reportErrorIfNoImplementationTypeIsRegisteredForInterfaceReturnType(method); } } return mappingMethods; }
public SourceReference build() { String sourceName = mapping.getSourceName(); if (sourceName == null) { return null; } boolean isValid = true; boolean foundEntryMatch; String[] sourcePropertyNames = new String[0]; String[] segments = sourceName.split("\\."); Parameter parameter = null; List<PropertyEntry> entries = new ArrayList<PropertyEntry>(); if (method.getSourceParameters().size() > 1) { // parameterName is mandatory for multiple source parameters if (segments.length > 0) { String sourceParameterName = segments[0]; parameter = method.getSourceParameter(sourceParameterName); if (parameter == null) { reportMappingError(Message.PROPERTYMAPPING_INVALID_PARAMETER_NAME, sourceParameterName); isValid = false; } } if (segments.length > 1 && parameter != null) { sourcePropertyNames = Arrays.copyOfRange(segments, 1, segments.length); entries = getSourceEntries(parameter.getType(), sourcePropertyNames); foundEntryMatch = (entries.size() == sourcePropertyNames.length); } else { // its only a parameter, no property foundEntryMatch = true; } } else { // parameter name is not mandatory for single source parameter sourcePropertyNames = segments; parameter = method.getSourceParameters().get(0); entries = getSourceEntries(parameter.getType(), sourcePropertyNames); foundEntryMatch = (entries.size() == sourcePropertyNames.length); if (!foundEntryMatch) { // Lets see if the expression contains the parameterName, so // parameterName.propName1.propName2 if (parameter.getName().equals(segments[0])) { sourcePropertyNames = Arrays.copyOfRange(segments, 1, segments.length); entries = getSourceEntries(parameter.getType(), sourcePropertyNames); foundEntryMatch = (entries.size() == sourcePropertyNames.length); } else { // segment[0] cannot be attributed to the parameter name. parameter = null; } } } if (!foundEntryMatch) { if (parameter != null) { reportMappingError( Message.PROPERTYMAPPING_NO_PROPERTY_IN_PARAMETER, parameter.getName(), Strings.join(Arrays.asList(sourcePropertyNames), ".")); } else { reportMappingError( Message.PROPERTYMAPPING_INVALID_PROPERTY_NAME, mapping.getSourceName()); } isValid = false; } return new SourceReference(parameter, entries, isValid); }
private List<MappingMethod> getMappingMethods( MapperConfiguration mapperConfig, List<SourceMethod> methods) { List<MappingMethod> mappingMethods = new ArrayList<MappingMethod>(); for (SourceMethod method : methods) { if (!method.overridesMethod()) { continue; } mergeInheritedOptions(method, mapperConfig, methods, new ArrayList<SourceMethod>()); MappingOptions mappingOptions = method.getMappingOptions(); boolean hasFactoryMethod = false; if (method.isIterableMapping()) { IterableMappingMethod.Builder builder = new IterableMappingMethod.Builder(); String dateFormat = null; List<TypeMirror> qualifiers = null; TypeMirror qualifyingElementTargetType = null; NullValueMappingStrategyPrism nullValueMappingStrategy = null; if (mappingOptions.getIterableMapping() != null) { dateFormat = mappingOptions.getIterableMapping().getDateFormat(); qualifiers = mappingOptions.getIterableMapping().getQualifiers(); qualifyingElementTargetType = mappingOptions.getIterableMapping().getQualifyingElementTargetType(); nullValueMappingStrategy = mappingOptions.getIterableMapping().getNullValueMappingStrategy(); } IterableMappingMethod iterableMappingMethod = builder .mappingContext(mappingContext) .method(method) .dateFormat(dateFormat) .qualifiers(qualifiers) .qualifyingElementTargetType(qualifyingElementTargetType) .nullValueMappingStrategy(nullValueMappingStrategy) .build(); hasFactoryMethod = iterableMappingMethod.getFactoryMethod() != null; mappingMethods.add(iterableMappingMethod); } else if (method.isMapMapping()) { MapMappingMethod.Builder builder = new MapMappingMethod.Builder(); String keyDateFormat = null; String valueDateFormat = null; List<TypeMirror> keyQualifiers = null; List<TypeMirror> valueQualifiers = null; TypeMirror keyQualifyingTargetType = null; TypeMirror valueQualifyingTargetType = null; NullValueMappingStrategyPrism nullValueMappingStrategy = null; if (mappingOptions.getMapMapping() != null) { keyDateFormat = mappingOptions.getMapMapping().getKeyFormat(); valueDateFormat = mappingOptions.getMapMapping().getValueFormat(); keyQualifiers = mappingOptions.getMapMapping().getKeyQualifiers(); valueQualifiers = mappingOptions.getMapMapping().getValueQualifiers(); keyQualifyingTargetType = mappingOptions.getMapMapping().getKeyQualifyingTargetType(); valueQualifyingTargetType = mappingOptions.getMapMapping().getValueQualifyingTargetType(); nullValueMappingStrategy = mappingOptions.getMapMapping().getNullValueMappingStrategy(); } MapMappingMethod mapMappingMethod = builder .mappingContext(mappingContext) .method(method) .keyDateFormat(keyDateFormat) .valueDateFormat(valueDateFormat) .keyQualifiers(keyQualifiers) .valueQualifiers(valueQualifiers) .keyQualifyingTargetType(keyQualifyingTargetType) .valueQualifyingTargetType(valueQualifyingTargetType) .nullValueMappingStrategy(nullValueMappingStrategy) .build(); hasFactoryMethod = mapMappingMethod.getFactoryMethod() != null; mappingMethods.add(mapMappingMethod); } else if (method.isEnumMapping()) { EnumMappingMethod.Builder builder = new EnumMappingMethod.Builder(); MappingMethod enumMappingMethod = builder.mappingContext(mappingContext).souceMethod(method).build(); if (enumMappingMethod != null) { mappingMethods.add(enumMappingMethod); } } else { NullValueMappingStrategyPrism nullValueMappingStrategy = null; TypeMirror resultType = null; List<TypeMirror> qualifiers = null; if (mappingOptions.getBeanMapping() != null) { nullValueMappingStrategy = mappingOptions.getBeanMapping().getNullValueMappingStrategy(); resultType = mappingOptions.getBeanMapping().getResultType(); qualifiers = mappingOptions.getBeanMapping().getQualifiers(); } BeanMappingMethod.Builder builder = new BeanMappingMethod.Builder(); BeanMappingMethod beanMappingMethod = builder .mappingContext(mappingContext) .souceMethod(method) .nullValueMappingStrategy(nullValueMappingStrategy) .qualifiers(qualifiers) .resultType(resultType) .build(); if (beanMappingMethod != null) { hasFactoryMethod = beanMappingMethod.getFactoryMethod() != null; mappingMethods.add(beanMappingMethod); } } if (!hasFactoryMethod) { // A factory method is allowed to return an interface type and hence, the generated // implementation as well. The check below must only be executed if there's no factory // method that could be responsible. reportErrorIfNoImplementationTypeIsRegisteredForInterfaceReturnType(method); } } return mappingMethods; }