I apologize if the title is not clear, let me make it clear by giving sample codes:
UpdateProfileDto
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
}
EncodedMapping
@Qualifier
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.CLASS)
public @interface EncodedMapping {
}
PasswordEncoderMapper
public class PasswordEncoderMapper {
protected final PasswordEncoder passwordEncoder;
public PasswordEncoderMapper(PasswordEncoder passwordEncoder) {
this.passwordEncoder = passwordEncoder;
}
@EncodedMapping
public String encode(String value) {
return passwordEncoder.encode(value);
}
}
UserMapper
@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);
}
Generated UserMapperImpl
@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() );
}
}
From the generated UserMapperImpl, I would like to check not only if newPassword has value... but to check currentPassword and newPassword have values and proceed with user.setPassword().
I mean something like this:
...
if ( updateUserProfileDto.getCurrentPassword() != null && updateUserProfileDto.getNewPassword() != null ) {
user.setPassword( passwordEncoderMapper.encode( updateUserProfileDto.getNewPassword() ) );
}
...
Problem
How could I change my mapper interface UserMapper so that i will check both currentPassword and newPassword before it will set the target user.password and will still use PasswordEncoderMapper.encode(password)?
If I try to use expression instead of source and check both currentPassword and newPassword if both have values and then set user.password to newPassword. Otherwise, it will not do anything to user.passwordusing NullValuePropertyMappingStrategy... but it seems it is not allowede to mix expression and NullValuePropertyMappingStrategy.
Thanks!