UserUseCaseImpl.java
package com.wilzwert.myjobs.core.application.usecase;
import com.wilzwert.myjobs.core.domain.model.job.JobState;
import com.wilzwert.myjobs.core.domain.model.user.UserSummary;
import com.wilzwert.myjobs.core.domain.model.user.UserView;
import com.wilzwert.myjobs.core.domain.model.user.collector.UserSummaryCollector;
import com.wilzwert.myjobs.core.domain.model.user.command.UpdateUserCommand;
import com.wilzwert.myjobs.core.domain.model.user.command.UpdateUserLangCommand;
import com.wilzwert.myjobs.core.domain.model.user.event.integration.UserUpdatedEvent;
import com.wilzwert.myjobs.core.domain.model.user.exception.UserAlreadyExistsException;
import com.wilzwert.myjobs.core.domain.model.user.exception.UserNotFoundException;
import com.wilzwert.myjobs.core.domain.model.user.User;
import com.wilzwert.myjobs.core.domain.model.user.UserId;
import com.wilzwert.myjobs.core.domain.model.user.ports.driven.EmailVerificationMessageProvider;
import com.wilzwert.myjobs.core.domain.model.user.ports.driven.UserDataManager;
import com.wilzwert.myjobs.core.domain.model.user.ports.driving.*;
import com.wilzwert.myjobs.core.domain.shared.event.integration.IntegrationEventId;
import com.wilzwert.myjobs.core.domain.shared.ports.driven.event.IntegrationEventPublisher;
import com.wilzwert.myjobs.core.domain.shared.ports.driven.transaction.TransactionProvider;
import java.util.List;
/**
* @author Wilhelm Zwertvaegher
*/
public class UserUseCaseImpl implements SendVerificationEmailUseCase, GetUserViewUseCase, UpdateUserUseCase, UpdateUserLangUseCase, GetUserSummaryUseCase {
private final TransactionProvider transactionProvider;
private final IntegrationEventPublisher integrationEventPublisher;
private final UserDataManager userDataManager;
private final EmailVerificationMessageProvider emailVerificationMessageProvider;
public UserUseCaseImpl(
TransactionProvider transactionProvider,
IntegrationEventPublisher integrationEventPublisher,
UserDataManager userDataManager,
EmailVerificationMessageProvider emailVerificationMessageProvider) {
this.transactionProvider = transactionProvider;
this.integrationEventPublisher = integrationEventPublisher;
this.userDataManager = userDataManager;
this.emailVerificationMessageProvider = emailVerificationMessageProvider;
}
@Override
public void sendVerificationEmail(UserId userId) {
userDataManager.findMinimalById(userId).ifPresent(emailVerificationMessageProvider::send);
}
@Override
public User updateUser(UpdateUserCommand command) {
User user = userDataManager.findMinimalById(command.userId()).orElseThrow(UserNotFoundException::new);
// if email changes, check availability
if(!command.email().equals(user.getEmail())) {
User existingUser = userDataManager.findMinimalByEmail(command.email()).orElse(null);
if(existingUser != null && !existingUser.equals(user)) {
throw new UserAlreadyExistsException();
}
}
// if username changes, check availability
if(!command.username().equals(user.getUsername())) {
User existingUser = userDataManager.findMinimalByUsername(command.username()).orElse(null);
if(existingUser != null && !existingUser.equals(user)) {
throw new UserAlreadyExistsException();
}
}
boolean shouldResendVerificationEmail = !user.getEmail().equals(command.email());
return transactionProvider.executeInTransaction(() -> {
User updatedUser = user.update(command.email(), command.username(), command.firstName(), command.lastName(), command.jobFollowUpReminderDays());
updatedUser = userDataManager.save(updatedUser);
if (shouldResendVerificationEmail) {
emailVerificationMessageProvider.send(updatedUser);
}
integrationEventPublisher.publish(new UserUpdatedEvent(IntegrationEventId.generate(), updatedUser.getId()));
return updatedUser;
});
}
@Override
public User updateUserLang(UpdateUserLangCommand command) {
User user = userDataManager.findMinimalById(command.userId()).orElseThrow(UserNotFoundException::new);
if(user.getLang().equals(command.lang())) {
return user;
}
return transactionProvider.executeInTransaction(() -> {
User updatedUser = userDataManager.save(user.updateLang(command.lang()));
integrationEventPublisher.publish(new UserUpdatedEvent(IntegrationEventId.generate(), updatedUser.getId()));
return updatedUser;
});
}
@Override
public UserView getUser(UserId userId) {
return userDataManager.findViewById(userId).orElseThrow(UserNotFoundException::new);
}
@Override
public UserSummary getUserSummary(UserId userId) {
User user = userDataManager.findMinimalById(userId).orElseThrow(UserNotFoundException::new);
List<JobState> jobStatuses = userDataManager.getJobsState(user);
return jobStatuses.stream().collect(new UserSummaryCollector(user));
}
}