Beispiel #1
0
 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);
    }
  }
Beispiel #3
0
 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;
  }