UserResourceServiceImpl.java
package fr.avenirsesr.portfolio.file.domain.service;
import fr.avenirsesr.portfolio.file.domain.exception.FileNotFoundException;
import fr.avenirsesr.portfolio.file.domain.exception.FileSizeTooBigException;
import fr.avenirsesr.portfolio.file.domain.exception.FileTypeNotSupportedException;
import fr.avenirsesr.portfolio.file.domain.model.EUserPhotoType;
import fr.avenirsesr.portfolio.file.domain.model.UserPhoto;
import fr.avenirsesr.portfolio.file.domain.model.shared.EFileType;
import fr.avenirsesr.portfolio.file.domain.model.shared.FileResource;
import fr.avenirsesr.portfolio.file.domain.port.input.UserResourceService;
import fr.avenirsesr.portfolio.file.domain.port.output.repository.UserPhotoRepository;
import fr.avenirsesr.portfolio.file.domain.port.output.service.FileStorageService;
import fr.avenirsesr.portfolio.file.infrastructure.configuration.FileStorageConstants;
import fr.avenirsesr.portfolio.user.domain.model.*;
import fr.avenirsesr.portfolio.user.domain.model.enums.EUserCategory;
import java.io.IOException;
import java.util.List;
import java.util.UUID;
import java.util.stream.Stream;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@AllArgsConstructor
public class UserResourceServiceImpl implements UserResourceService {
public static final List<EFileType> ALLOWED_FILE_TYPES =
List.of(EFileType.PNG, EFileType.JPEG, EFileType.GIF, EFileType.WEBP, EFileType.PJPEG);
private final FileStorageService fileStorageService;
private final UserPhotoRepository userPhotoRepository;
@Override
public String getUserPhotoUrl(User user, EUserCategory userCategory, EUserPhotoType type) {
return userPhotoRepository.findActiveByUser(user, userCategory, type).stream()
.map(photo -> FileStorageConstants.PHOTO_ENDPOINT_PREFIX + "/" + photo.getId())
.findAny()
.orElse(
switch (type) {
case PROFILE -> FileStorageConstants.DEFAULT_PROFILE_FILE_URL;
case COVER -> FileStorageConstants.DEFAULT_COVER_FILE_URL;
});
}
@Override
public byte[] fetchContent(UserPhoto userPhoto) throws IOException {
return fileStorageService.get(userPhoto.getUri());
}
@Override
public UserPhoto getUserPhotoById(UUID fileId) {
return userPhotoRepository.findById(fileId).orElseThrow(FileNotFoundException::new);
}
@Override
public UserPhoto uploadPhoto(
User user,
EUserCategory category,
EUserPhotoType photoType,
String fileName,
String mimeType,
long size,
byte[] content)
throws IOException {
var fileResource =
new FileResource(
UUID.randomUUID(), fileName, EFileType.fromMimeType(mimeType), size, content);
if (!ALLOWED_FILE_TYPES.contains(fileResource.fileType())) {
throw new FileTypeNotSupportedException();
}
if (fileResource.fileType().getSizeLimit().isLessThan(size)) {
throw new FileSizeTooBigException();
}
var uri = fileStorageService.upload(fileResource);
var allPhotos = userPhotoRepository.findAllByUser(user, category, photoType);
var version =
allPhotos.stream().map(UserPhoto::getVersion).max(Integer::compareTo).orElse(0) + 1;
allPhotos.forEach(a -> a.setActiveVersion(false));
var photo =
UserPhoto.create(
fileResource.id(),
fileResource.fileType(),
fileResource.size(),
version,
true,
uri,
user,
user,
category,
photoType);
userPhotoRepository.saveAll(Stream.concat(allPhotos.stream(), Stream.of(photo)).toList());
log.info("New user photo saved: {}", photo);
return photo;
}
}