title: Mapstruct mapping with condition and nullValuePropertyMappingStrategy
body: <p>I apologize if the title is not clear, let me make it clear by giving sample codes:</p>
  
  <p><strong>UpdateProfileDto</strong></p>
  
  <pre><code>public class UpdateProfileDto {
  
      @NotEmpty
      private String firstName;
  
      @NotEmpty
      private String lastName;
  
      @Size(max = 20)
      private String currentPassword;
  
      @Size(max = 20)
      private String newPassword;
  
      @Size(max = 20)
      private String confirmNewPassword;
  
      // getters and setters
  }
  </code></pre>
  
  <p><strong>EncodedMapping</strong>  </p>
  
  <pre><code>@Qualifier
  @Target(ElementType.METHOD)
  @Retention(RetentionPolicy.CLASS)
  public @interface EncodedMapping {
  }
  </code></pre>
  
  <p><strong>PasswordEncoderMapper</strong></p>
  
  <pre><code>public class PasswordEncoderMapper {
      protected final PasswordEncoder passwordEncoder;
  
      public PasswordEncoderMapper(PasswordEncoder passwordEncoder) {
          this.passwordEncoder = passwordEncoder;
      }
  
      @EncodedMapping
      public String encode(String value) {
          return passwordEncoder.encode(value);
      }
  }
  </code></pre>
  
  <p><strong>UserMapper</strong></p>
  
  <pre><code>@Mapper(config = MapperConfig.class, componentModel = "spring", uses = PasswordEncoderMapper.class)
  public interface UserMapper {
  
      @Mappings({
              @Mapping(target = "firstName", source = "firstName"),
              @Mapping(target = "lastName", source = "lastName"),
              @Mapping(target = "fullName", expression = "java(user.getFirstName() + \" \" + user.getLastName())"),
              @Mapping(target = "password",
                      source = "newPassword",
                      nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE,
                      qualifiedBy = EncodedMapping.class)
      })
      void updateUserFromDto(UpdateUserProfileDto updateUserProfileDto, @MappingTarget User user);
  }
  </code></pre>
  
  <p><strong>Generated UserMapperImpl</strong></p>
  
  <pre><code>@Generated(
      value = "org.mapstruct.ap.MappingProcessor",
      date = "2020-03-11T13:51:34+0800",
      comments = "version: 1.3.0.Final, compiler: javac, environment: Java 1.8.0_231 (Oracle Corporation)"
  )
  @Component
  public class UserMapperImpl implements UserMapper {
  
      @Autowired
      private PasswordEncoderMapper passwordEncoderMapper;
  
      @Override
      public void updateUserFromDto(UpdateUserProfileDto updateUserProfileDto, User user) {
          if ( updateUserProfileDto == null ) {
              return;
          }
  
          if ( updateUserProfileDto.getFirstName() != null ) {
              user.setFirstName( updateUserProfileDto.getFirstName() );
          }
          else {
              user.setFirstName( null );
          }
          if ( updateUserProfileDto.getLastName() != null ) {
              user.setLastName( updateUserProfileDto.getLastName() );
          }
          else {
              user.setLastName( null );
          }
          if ( updateUserProfileDto.getNewPassword() != null ) {
              user.setPassword( passwordEncoderMapper.encode( updateUserProfileDto.getNewPassword() ) );
          }
  
          user.setFullName( user.getFirstName() + " " + user.getLastName() );
      }
  }
  </code></pre>
  
  <p>From the generated <code>UserMapperImpl</code>, I would like to check not only if <code>newPassword</code> has value... but to check <code>currentPassword</code> and <code>newPassword</code> have values and proceed with <code>user.setPassword()</code>.</p>
  
  <p>I mean something like this:</p>
  
  <pre><code>...
  if ( updateUserProfileDto.getCurrentPassword() != null &amp;&amp; updateUserProfileDto.getNewPassword() != null ) {
      user.setPassword( passwordEncoderMapper.encode( updateUserProfileDto.getNewPassword() ) );
  }
  ...
  </code></pre>
  
  <p><strong>Problem</strong></p>
  
  <p>How could I change my mapper interface <code>UserMapper</code> so that i will check both <code>currentPassword</code> and <code>newPassword</code> before it will set the target <code>user.password</code> and will still use <code>PasswordEncoderMapper.encode(password)</code>?  </p>
  
  <p>If I try to use <code>expression</code> instead of <code>source</code> and check both <code>currentPassword</code> and <code>newPassword</code> if both have values and then set <code>user.password</code> to <code>newPassword</code>. Otherwise, it will not do anything to <code>user.password</code>using <code>NullValuePropertyMappingStrategy</code>... but it seems it is not allowede to mix <code>expression</code> and <code>NullValuePropertyMappingStrategy</code>.</p>
  
  <p>Thanks!</p>