Reputation: 2038
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.password
using NullValuePropertyMappingStrategy
... but it seems it is not allowede to mix expression
and NullValuePropertyMappingStrategy
.
Thanks!
Upvotes: 5
Views: 9166
Reputation: 7521
I would start with following approach
@Mapper(config = MapperConfig.class, componentModel = "spring")
public abstract class UserMapper { // using class instead of interface to be able to inject beans
@Autowired
private PasswordEncoderMapper passwordEncoderMapper;
@Mappings({
// your non-password mappings
})
void updateUserFromDto(UpdateUserProfileDto updateUserProfileDto, @MappingTarget User user);
@AfterMapping
void setPassword(UpdateUserProfileDto updateUserProfileDto, @MappingTarget User user) {
if (updateUserProfileDto.getCurrentPassword() != null && updateUserProfileDto.getNewPassword() != null) {
user.setPassword(passwordEncoderMapper.encode( updateUserProfileDto.getNewPassword()));
}
}
}
Upvotes: 5