Skip to content

Commit 9b88fe3

Browse files
committed
refactor mappers to use dependency injection and update mapping policies
1 parent 59f6120 commit 9b88fe3

File tree

10 files changed

+52
-38
lines changed

10 files changed

+52
-38
lines changed

backend/spring-boot/src/main/java/org/bugzkit/api/admin/service/impl/UserServiceImpl.java

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,18 +34,21 @@ public class UserServiceImpl implements UserService {
3434
private final AccessTokenService accessTokenService;
3535
private final RefreshTokenService refreshTokenService;
3636
private final PasswordEncoder bCryptPasswordEncoder;
37+
private final UserMapper userMapper;
3738

3839
public UserServiceImpl(
3940
UserRepository userRepository,
4041
RoleRepository roleRepository,
4142
AccessTokenService accessTokenService,
4243
RefreshTokenService refreshTokenService,
43-
PasswordEncoder bCryptPasswordEncoder) {
44+
PasswordEncoder bCryptPasswordEncoder,
45+
UserMapper userMapper) {
4446
this.userRepository = userRepository;
4547
this.roleRepository = roleRepository;
4648
this.accessTokenService = accessTokenService;
4749
this.refreshTokenService = refreshTokenService;
4850
this.bCryptPasswordEncoder = bCryptPasswordEncoder;
51+
this.userMapper = userMapper;
4952
}
5053

5154
@Override
@@ -70,7 +73,7 @@ public UserDTO create(UserRequest userRequest) {
7073
.build();
7174
final var saved = userRepository.save(user);
7275
log.info("Admin created user '{}' (id={})", saved.getUsername(), saved.getId());
73-
return UserMapper.INSTANCE.userToAdminUserDTO(saved);
76+
return userMapper.userToAdminUserDTO(saved);
7477
}
7578

7679
/*
@@ -83,9 +86,7 @@ public UserDTO create(UserRequest userRequest) {
8386
public PageableDTO<UserDTO> findAll(Pageable pageable) {
8487
final var userIds = userRepository.findAllUserIds(pageable);
8588
final var users =
86-
userRepository.findAllByIdIn(userIds).stream()
87-
.map(UserMapper.INSTANCE::userToAdminUserDTO)
88-
.toList();
89+
userRepository.findAllByIdIn(userIds).stream().map(userMapper::userToAdminUserDTO).toList();
8990
final long total = userRepository.count();
9091
return new PageableDTO<>(users, total);
9192
}
@@ -95,7 +96,7 @@ public PageableDTO<UserDTO> findAll(Pageable pageable) {
9596
public UserDTO findById(Long id) {
9697
return userRepository
9798
.findWithRolesById(id)
98-
.map(UserMapper.INSTANCE::userToAdminUserDTO)
99+
.map(userMapper::userToAdminUserDTO)
99100
.orElseThrow(
100101
() -> {
101102
log.warn("Admin user lookup failed: no user found with id '{}'", id);
@@ -127,7 +128,7 @@ public UserDTO update(Long id, UserRequest userRequest) {
127128

128129
final var updated = userRepository.save(user);
129130
log.info("Admin updated user '{}' (id={})", updated.getUsername(), id);
130-
return UserMapper.INSTANCE.userToAdminUserDTO(updated);
131+
return userMapper.userToAdminUserDTO(updated);
131132
}
132133

133134
@Override
@@ -154,7 +155,7 @@ public UserDTO patch(Long id, PatchUserRequest patchUserRequest) {
154155

155156
final var updated = userRepository.save(user);
156157
log.info("Admin patched user '{}' (id={})", updated.getUsername(), id);
157-
return UserMapper.INSTANCE.userToAdminUserDTO(updated);
158+
return userMapper.userToAdminUserDTO(updated);
158159
}
159160

160161
private boolean isSelf(Long id) {

backend/spring-boot/src/main/java/org/bugzkit/api/auth/mapper/AuthMapper.java

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,12 @@
33
import org.bugzkit.api.auth.model.Device;
44
import org.bugzkit.api.auth.payload.dto.DeviceDTO;
55
import org.mapstruct.Context;
6-
import org.mapstruct.InjectionStrategy;
76
import org.mapstruct.Mapper;
87
import org.mapstruct.Mapping;
9-
import org.mapstruct.factory.Mappers;
8+
import org.mapstruct.ReportingPolicy;
109

11-
@Mapper(injectionStrategy = InjectionStrategy.CONSTRUCTOR)
10+
@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.ERROR)
1211
public interface AuthMapper {
13-
AuthMapper INSTANCE = Mappers.getMapper(AuthMapper.class);
1412

1513
@Mapping(target = "current", expression = "java(device.getDeviceId().equals(currentDeviceId))")
1614
DeviceDTO deviceToDeviceDTO(Device device, @Context String currentDeviceId);

backend/spring-boot/src/main/java/org/bugzkit/api/auth/service/impl/AuthServiceImpl.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ public class AuthServiceImpl implements AuthService {
4545
private final VerificationTokenService verificationTokenService;
4646
private final ResetPasswordTokenService resetPasswordTokenService;
4747
private final DeviceService deviceService;
48+
private final UserMapper userMapper;
4849

4950
public AuthServiceImpl(
5051
UserRepository userRepository,
@@ -55,7 +56,8 @@ public AuthServiceImpl(
5556
RefreshTokenService refreshTokenService,
5657
VerificationTokenService verificationTokenService,
5758
ResetPasswordTokenService resetPasswordTokenService,
58-
DeviceService deviceService) {
59+
DeviceService deviceService,
60+
UserMapper userMapper) {
5961
this.userRepository = userRepository;
6062
this.roleRepository = roleRepository;
6163
this.bCryptPasswordEncoder = bCryptPasswordEncoder;
@@ -65,6 +67,7 @@ public AuthServiceImpl(
6567
this.verificationTokenService = verificationTokenService;
6668
this.resetPasswordTokenService = resetPasswordTokenService;
6769
this.deviceService = deviceService;
70+
this.userMapper = userMapper;
6871
}
6972

7073
@Override
@@ -82,7 +85,7 @@ public UserDTO register(RegisterUserRequest registerUserRequest) {
8285
final var token = verificationTokenService.create(user.getId());
8386
verificationTokenService.sendToEmail(user, token);
8487
log.info("User '{}' registered, verification email sent", user.getUsername());
85-
return UserMapper.INSTANCE.userToProfileUserDTO(user);
88+
return userMapper.userToProfileUserDTO(user);
8689
}
8790

8891
@Override
@@ -97,7 +100,7 @@ public AuthTokens authenticate(
97100
userRepository
98101
.findWithRolesByUsername(auth.getName())
99102
.orElseThrow(() -> new UnauthorizedException("auth.unauthorized"));
100-
final var roleDTOs = UserMapper.INSTANCE.rolesToRoleDTOs(user.getRoles());
103+
final var roleDTOs = userMapper.rolesToRoleDTOs(user.getRoles());
101104
final var accessToken = accessTokenService.create(user.getId(), roleDTOs, deviceId);
102105
final var refreshToken = refreshTokenService.create(user.getId(), roleDTOs, deviceId);
103106
deviceService.createOrUpdate(user.getId(), deviceId, userAgent);

backend/spring-boot/src/main/java/org/bugzkit/api/auth/service/impl/DeviceServiceImpl.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ public class DeviceServiceImpl implements DeviceService {
2323
private final UserRepository userRepository;
2424
private final AccessTokenService accessTokenService;
2525
private final RefreshTokenService refreshTokenService;
26+
private final AuthMapper authMapper;
2627

2728
@Value("${jwt.refresh-token.duration}")
2829
private int refreshTokenDuration;
@@ -31,19 +32,21 @@ public DeviceServiceImpl(
3132
DeviceRepository deviceRepository,
3233
UserRepository userRepository,
3334
AccessTokenService accessTokenService,
34-
RefreshTokenService refreshTokenService) {
35+
RefreshTokenService refreshTokenService,
36+
AuthMapper authMapper) {
3537
this.deviceRepository = deviceRepository;
3638
this.userRepository = userRepository;
3739
this.accessTokenService = accessTokenService;
3840
this.refreshTokenService = refreshTokenService;
41+
this.authMapper = authMapper;
3942
}
4043

4144
@Override
4245
@Transactional(readOnly = true)
4346
public List<DeviceDTO> findAll(String currentDeviceId) {
4447
final var userId = AuthUtil.findSignedInUser().getId();
4548
return deviceRepository.findAllByUserId(userId).stream()
46-
.map(device -> AuthMapper.INSTANCE.deviceToDeviceDTO(device, currentDeviceId))
49+
.map(device -> authMapper.deviceToDeviceDTO(device, currentDeviceId))
4750
.toList();
4851
}
4952

backend/spring-boot/src/main/java/org/bugzkit/api/user/mapper/UserMapper.java

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,12 @@
66
import org.bugzkit.api.user.model.User;
77
import org.bugzkit.api.user.payload.dto.RoleDTO;
88
import org.bugzkit.api.user.payload.dto.UserDTO;
9-
import org.mapstruct.InjectionStrategy;
109
import org.mapstruct.Mapper;
1110
import org.mapstruct.Mapping;
12-
import org.mapstruct.factory.Mappers;
11+
import org.mapstruct.ReportingPolicy;
1312

14-
@Mapper(injectionStrategy = InjectionStrategy.CONSTRUCTOR)
13+
@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.ERROR)
1514
public interface UserMapper {
16-
UserMapper INSTANCE = Mappers.getMapper(UserMapper.class);
1715

1816
Set<RoleDTO> rolesToRoleDTOs(Set<Role> roles);
1917

backend/spring-boot/src/main/java/org/bugzkit/api/user/service/impl/ProfileServiceImpl.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,25 +29,28 @@ public class ProfileServiceImpl implements ProfileService {
2929
private final RefreshTokenService refreshTokenService;
3030
private final VerificationTokenService verificationTokenService;
3131
private final DeviceService deviceService;
32+
private final UserMapper userMapper;
3233

3334
public ProfileServiceImpl(
3435
UserRepository userRepository,
3536
PasswordEncoder bCryptPasswordEncoder,
3637
AccessTokenService accessTokenService,
3738
RefreshTokenService refreshTokenService,
3839
VerificationTokenService verificationTokenService,
39-
DeviceService deviceService) {
40+
DeviceService deviceService,
41+
UserMapper userMapper) {
4042
this.userRepository = userRepository;
4143
this.bCryptPasswordEncoder = bCryptPasswordEncoder;
4244
this.accessTokenService = accessTokenService;
4345
this.refreshTokenService = refreshTokenService;
4446
this.verificationTokenService = verificationTokenService;
4547
this.deviceService = deviceService;
48+
this.userMapper = userMapper;
4649
}
4750

4851
@Override
4952
public UserDTO find() {
50-
return UserMapper.INSTANCE.userPrincipalToProfileUserDTO(AuthUtil.findSignedInUser());
53+
return userMapper.userPrincipalToProfileUserDTO(AuthUtil.findSignedInUser());
5154
}
5255

5356
@Override
@@ -70,7 +73,7 @@ public UserDTO patch(PatchProfileRequest patchProfileRequest) {
7073

7174
final var updated = userRepository.save(user);
7275
log.info("Profile updated for user '{}'", userId);
73-
return UserMapper.INSTANCE.userToProfileUserDTO(updated);
76+
return userMapper.userToProfileUserDTO(updated);
7477
}
7578

7679
private void deleteAuthTokens(Long userId) {

backend/spring-boot/src/main/java/org/bugzkit/api/user/service/impl/RoleServiceImpl.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,16 @@
1313
@PreAuthorize("hasAuthority('ADMIN')")
1414
public class RoleServiceImpl implements RoleService {
1515
private final RoleRepository roleRepository;
16+
private final UserMapper userMapper;
1617

17-
public RoleServiceImpl(RoleRepository roleRepository) {
18+
public RoleServiceImpl(RoleRepository roleRepository, UserMapper userMapper) {
1819
this.roleRepository = roleRepository;
20+
this.userMapper = userMapper;
1921
}
2022

2123
@Override
2224
@Transactional(readOnly = true)
2325
public List<RoleDTO> findAll() {
24-
return roleRepository.findAll().stream().map(UserMapper.INSTANCE::roleToRoleDTO).toList();
26+
return roleRepository.findAll().stream().map(userMapper::roleToRoleDTO).toList();
2527
}
2628
}

backend/spring-boot/src/main/java/org/bugzkit/api/user/service/impl/UserServiceImpl.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,18 @@
1818
@Service
1919
public class UserServiceImpl implements UserService {
2020
private final UserRepository userRepository;
21+
private final UserMapper userMapper;
2122

22-
public UserServiceImpl(UserRepository userRepository) {
23+
public UserServiceImpl(UserRepository userRepository, UserMapper userMapper) {
2324
this.userRepository = userRepository;
25+
this.userMapper = userMapper;
2426
}
2527

2628
@Override
2729
@Transactional(readOnly = true)
2830
public PageableDTO<UserDTO> findAll(Pageable pageable) {
2931
final var users =
30-
userRepository.findAll(pageable).stream()
31-
.map(UserMapper.INSTANCE::userToSimpleUserDTO)
32-
.toList();
32+
userRepository.findAll(pageable).stream().map(userMapper::userToSimpleUserDTO).toList();
3333
final var total = userRepository.count();
3434
return new PageableDTO<>(users, total);
3535
}
@@ -39,7 +39,7 @@ public PageableDTO<UserDTO> findAll(Pageable pageable) {
3939
public UserDTO findById(Long id) {
4040
return userRepository
4141
.findById(id)
42-
.map(UserMapper.INSTANCE::userToSimpleUserDTO)
42+
.map(userMapper::userToSimpleUserDTO)
4343
.orElseThrow(
4444
() -> {
4545
log.warn("User not found with id '{}'", id);
@@ -52,7 +52,7 @@ public UserDTO findById(Long id) {
5252
public UserDTO findByUsername(String username) {
5353
return userRepository
5454
.findByUsername(username)
55-
.map(UserMapper.INSTANCE::userToSimpleUserDTO)
55+
.map(userMapper::userToSimpleUserDTO)
5656
.orElseThrow(
5757
() -> {
5858
log.warn("User not found with username '{}'", username);

backend/spring-boot/src/test/java/org/bugzkit/api/auth/unit/AuthMapperTest.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,11 @@
88
import org.bugzkit.api.auth.mapper.AuthMapper;
99
import org.bugzkit.api.auth.model.Device;
1010
import org.junit.jupiter.api.Test;
11+
import org.mapstruct.factory.Mappers;
1112

1213
class AuthMapperTest {
14+
private final AuthMapper authMapper = Mappers.getMapper(AuthMapper.class);
15+
1316
@Test
1417
void deviceToDeviceDTO_mapsAllFields() {
1518
final var now = LocalDateTime.now();
@@ -21,7 +24,7 @@ void deviceToDeviceDTO_mapsAllFields() {
2124
.lastActiveAt(now)
2225
.build();
2326

24-
final var dto = AuthMapper.INSTANCE.deviceToDeviceDTO(device, "device-1");
27+
final var dto = authMapper.deviceToDeviceDTO(device, "device-1");
2528

2629
assertEquals("device-1", dto.deviceId());
2730
assertEquals("Mozilla/5.0", dto.userAgent());
@@ -33,7 +36,7 @@ void deviceToDeviceDTO_mapsAllFields() {
3336
void deviceToDeviceDTO_currentTrue_whenDeviceIdMatches() {
3437
final var device = Device.builder().deviceId("device-1").build();
3538

36-
final var dto = AuthMapper.INSTANCE.deviceToDeviceDTO(device, "device-1");
39+
final var dto = authMapper.deviceToDeviceDTO(device, "device-1");
3740

3841
assertTrue(dto.current());
3942
}
@@ -42,7 +45,7 @@ void deviceToDeviceDTO_currentTrue_whenDeviceIdMatches() {
4245
void deviceToDeviceDTO_currentFalse_whenDeviceIdDoesNotMatch() {
4346
final var device = Device.builder().deviceId("device-1").build();
4447

45-
final var dto = AuthMapper.INSTANCE.deviceToDeviceDTO(device, "device-2");
48+
final var dto = authMapper.deviceToDeviceDTO(device, "device-2");
4649

4750
assertFalse(dto.current());
4851
}

backend/spring-boot/src/test/java/org/bugzkit/api/user/unit/UserMapperTest.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,11 @@
1111
import org.bugzkit.api.user.model.Role.RoleName;
1212
import org.bugzkit.api.user.model.User;
1313
import org.junit.jupiter.api.Test;
14+
import org.mapstruct.factory.Mappers;
1415

1516
class UserMapperTest {
17+
private final UserMapper userMapper = Mappers.getMapper(UserMapper.class);
18+
1619
@Test
1720
void userToAdminUserDTO_mapsAllFields() {
1821
final var now = LocalDateTime.now();
@@ -28,7 +31,7 @@ void userToAdminUserDTO_mapsAllFields() {
2831
.roles(Set.of(role))
2932
.build();
3033

31-
final var dto = UserMapper.INSTANCE.userToAdminUserDTO(user);
34+
final var dto = userMapper.userToAdminUserDTO(user);
3235

3336
assertEquals(1L, dto.id());
3437
assertEquals("admin", dto.username());
@@ -52,7 +55,7 @@ void userToProfileUserDTO_ignoresActiveLockAndRoles() {
5255
.lock(false)
5356
.build();
5457

55-
final var dto = UserMapper.INSTANCE.userToProfileUserDTO(user);
58+
final var dto = userMapper.userToProfileUserDTO(user);
5659

5760
assertEquals("user", dto.username());
5861
assertEquals("user@localhost", dto.email());
@@ -72,7 +75,7 @@ void userToSimpleUserDTO_ignoresEmailActiveLockAndRoles() {
7275
.lock(false)
7376
.build();
7477

75-
final var dto = UserMapper.INSTANCE.userToSimpleUserDTO(user);
78+
final var dto = userMapper.userToSimpleUserDTO(user);
7679

7780
assertEquals("user", dto.username());
7881
assertNull(dto.email());

0 commit comments

Comments
 (0)