diff --git a/src/main/java/com/mediamanager/model/Album.java b/src/main/java/com/mediamanager/model/Album.java index 6a740fc..6bedc3a 100644 --- a/src/main/java/com/mediamanager/model/Album.java +++ b/src/main/java/com/mediamanager/model/Album.java @@ -2,6 +2,9 @@ package com.mediamanager.model; import jakarta.persistence.*; import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; @Entity @Table(name = "album") @@ -34,6 +37,10 @@ public class Album { @JoinColumn(name = "fk_albumart_id") private AlbumArt albumArt; + // Relacionamento ManyToMany com Artist através da tabela de junção + @OneToMany(mappedBy = "album", cascade = CascadeType.ALL, orphanRemoval = true) + private List albumArtists = new ArrayList<>(); + @Column(name = "created_at", nullable = false, updatable = false) private LocalDateTime createdAt; @@ -53,6 +60,27 @@ public class Album { public Album() {} + // Métodos helper para Artist (ManyToMany) + public void addArtist(Artist artist) { + AlbumHasArtist albumHasArtist = new AlbumHasArtist(); + albumHasArtist.setAlbum(this); + albumHasArtist.setArtist(artist); + albumArtists.add(albumHasArtist); + } + + public void removeArtist(Artist artist) { + albumArtists.removeIf(aa -> + aa.getArtist() != null && aa.getArtist().getId().equals(artist.getId()) + ); + } + + // Método conveniente para pegar só os artistas + public List getArtists() { + return albumArtists.stream() + .map(AlbumHasArtist::getArtist) + .collect(Collectors.toList()); + } + // Getters and Setters public Integer getId() { return id; @@ -118,6 +146,14 @@ public class Album { this.albumArt = albumArt; } + public List getAlbumArtists() { + return albumArtists; + } + + public void setAlbumArtists(List albumArtists) { + this.albumArtists = albumArtists; + } + public LocalDateTime getCreatedAt() { return createdAt; } diff --git a/src/main/java/com/mediamanager/service/album/AlbumService.java b/src/main/java/com/mediamanager/service/album/AlbumService.java index 82d1664..bf41a46 100644 --- a/src/main/java/com/mediamanager/service/album/AlbumService.java +++ b/src/main/java/com/mediamanager/service/album/AlbumService.java @@ -71,50 +71,73 @@ public class AlbumService { return repository.findById(id); } - public Optional updateAlbum(Integer id, String name, Integer year, Integer numberOfDiscs, String code, Boolean isCompilation, Integer albumTypeId, Integer albumArtId) { + public Optional updateAlbum(Integer id, String name, Integer year, + Integer numberOfDiscs, String code, + Boolean isCompilation, Integer albumTypeId, + Integer albumArtId, + boolean updateYear, // ← Novo! + boolean updateNumberOfDiscs, // ← Novo! + boolean updateAlbumType, // ← Novo! + boolean updateAlbumArt) { // ← Novo! if (id == null) { throw new IllegalArgumentException("ID cannot be null"); } - logger.info("Updating album:{}", name); + logger.info("Updating album: {}", name); if (name == null || name.trim().isEmpty()) { throw new IllegalArgumentException("Album name cannot be null or empty"); } Optional existingAlbum = repository.findById(id); - if(existingAlbum.isEmpty()) { - logger.warn("Album not found with id:{}", id); + if (existingAlbum.isEmpty()) { + logger.warn("Album not found with id: {}", id); return Optional.empty(); } Album album = existingAlbum.get(); album.setName(name); - album.setYear(year); - album.setNumberOfDiscs(numberOfDiscs); album.setCode(code); album.setIsCompilation(isCompilation); - // Update AlbumType if provided - if (albumTypeId != null && albumTypeId > 0) { - Optional albumType = albumTypeRepository.findById(albumTypeId); - if (albumType.isEmpty()) { - throw new IllegalArgumentException("AlbumType not found with id: " + albumTypeId); - } - album.setAlbumType(albumType.get()); - } else { - album.setAlbumType(null); + // Atualiza year SOMENTE se o campo foi fornecido + if (updateYear) { + album.setYear(year); } - // Update AlbumArt if provided - if (albumArtId != null && albumArtId > 0) { - Optional albumArt = albumArtRepository.findById(albumArtId); - if (albumArt.isEmpty()) { - throw new IllegalArgumentException("AlbumArt not found with id: " + albumArtId); - } - album.setAlbumArt(albumArt.get()); - } else { - album.setAlbumArt(null); + // Atualiza numberOfDiscs SOMENTE se o campo foi fornecido + if (updateNumberOfDiscs) { + album.setNumberOfDiscs(numberOfDiscs); } + // Update AlbumType SOMENTE se o campo foi fornecido + if (updateAlbumType) { + if (albumTypeId != null && albumTypeId > 0) { + Optional albumType = albumTypeRepository.findById(albumTypeId); + if (albumType.isEmpty()) { + throw new IllegalArgumentException("AlbumType not found with id: " + albumTypeId); + } + album.setAlbumType(albumType.get()); + } else { + // Explicitamente passado como 0 ou null = remover a relação + album.setAlbumType(null); + } + } + // Se não foi fornecido, mantém o existente + + // Update AlbumArt SOMENTE se o campo foi fornecido + if (updateAlbumArt) { + if (albumArtId != null && albumArtId > 0) { + Optional albumArt = albumArtRepository.findById(albumArtId); + if (albumArt.isEmpty()) { + throw new IllegalArgumentException("AlbumArt not found with id: " + albumArtId); + } + album.setAlbumArt(albumArt.get()); + } else { + // Explicitamente passado como 0 ou null = remover a relação + album.setAlbumArt(null); + } + } + // Se não foi fornecido, mantém o existente + Album updatedAlbum = repository.update(album); return Optional.of(updatedAlbum); } diff --git a/src/main/java/com/mediamanager/service/delegate/handler/album/UpdateAlbumHandler.java b/src/main/java/com/mediamanager/service/delegate/handler/album/UpdateAlbumHandler.java index ac10f55..d9f81b4 100644 --- a/src/main/java/com/mediamanager/service/delegate/handler/album/UpdateAlbumHandler.java +++ b/src/main/java/com/mediamanager/service/delegate/handler/album/UpdateAlbumHandler.java @@ -24,24 +24,47 @@ public class UpdateAlbumHandler implements ActionHandler { } @Override - public TransportProtocol.Response.Builder handle(ByteString requestPayload) throws InvalidProtocolBufferException { - try{ + public TransportProtocol.Response.Builder handle(ByteString requestPayload) + throws InvalidProtocolBufferException { + try { AlbumMessages.UpdateAlbumRequest updateRequest = AlbumMessages.UpdateAlbumRequest.parseFrom(requestPayload); int id = updateRequest.getId(); + + // Extrai valores dos wrappers - null se não foi fornecido + Integer year = updateRequest.hasYear() + ? updateRequest.getYear().getValue() + : null; + + Integer numberOfDiscs = updateRequest.hasNumberOfDiscs() + ? updateRequest.getNumberOfDiscs().getValue() + : null; + + Integer albumTypeId = updateRequest.hasFkAlbumtypeId() + ? updateRequest.getFkAlbumtypeId().getValue() + : null; + + Integer albumArtId = updateRequest.hasFkAlbumartId() + ? updateRequest.getFkAlbumartId().getValue() + : null; + Optional albumOpt = albumService.updateAlbum( id, updateRequest.getName(), - updateRequest.getYear() > 0 ? updateRequest.getYear() : null, - updateRequest.getNumberOfDiscs() > 0 ? updateRequest.getNumberOfDiscs() : null, + year, + numberOfDiscs, updateRequest.getCode().isEmpty() ? null : updateRequest.getCode(), updateRequest.getIsCompilation(), - updateRequest.getFkAlbumtypeId() > 0 ? updateRequest.getFkAlbumtypeId() : null, - updateRequest.getFkAlbumartId() > 0 ? updateRequest.getFkAlbumartId() : null + albumTypeId, + albumArtId, + updateRequest.hasYear(), // ← Novo! + updateRequest.hasNumberOfDiscs(), // ← Novo! + updateRequest.hasFkAlbumtypeId(), // ← Novo! + updateRequest.hasFkAlbumartId() // ← Novo! ); - if(albumOpt.isEmpty()){ + if (albumOpt.isEmpty()) { logger.warn("Album not found with ID: {}", id); return TransportProtocol.Response.newBuilder() .setStatusCode(404) @@ -50,14 +73,15 @@ public class UpdateAlbumHandler implements ActionHandler { AlbumMessages.Album albumProto = AlbumMapper.toProtobuf(albumOpt.get()); - AlbumMessages.UpdateAlbumResponse updateResponse = AlbumMessages.UpdateAlbumResponse.newBuilder() - .setAlbum(albumProto) - .build(); + AlbumMessages.UpdateAlbumResponse updateResponse = + AlbumMessages.UpdateAlbumResponse.newBuilder() + .setAlbum(albumProto) + .build(); return TransportProtocol.Response.newBuilder() .setPayload(updateResponse.toByteString()); - } catch (IllegalArgumentException e){ + } catch (IllegalArgumentException e) { logger.error("Validation error", e); return TransportProtocol.Response.newBuilder() .setStatusCode(400) @@ -69,4 +93,4 @@ public class UpdateAlbumHandler implements ActionHandler { .setPayload(ByteString.copyFromUtf8("Error: " + e.getMessage())); } } -} +} \ No newline at end of file diff --git a/src/main/proto/album.proto b/src/main/proto/album.proto index 44e876e..e7d350a 100644 --- a/src/main/proto/album.proto +++ b/src/main/proto/album.proto @@ -1,5 +1,7 @@ syntax = "proto3"; +import "google/protobuf/wrappers.proto"; // ← Adicione esse import! + option java_package = "com.mediamanager.protocol.messages"; option java_outer_classname = "AlbumMessages"; @@ -13,11 +15,9 @@ message Album { string code = 5; bool is_compilation = 6; - int32 fk_albumtype_id = 7; int32 fk_albumart_id = 8; - int64 created_at = 9; int64 updated_at = 10; } @@ -55,12 +55,12 @@ message GetAlbumByIdResponse { message UpdateAlbumRequest { int32 id = 1; string name = 2; - int32 year = 3; - int32 number_of_discs = 4; + google.protobuf.Int32Value year = 3; // ← Mudou! + google.protobuf.Int32Value number_of_discs = 4; // ← Mudou! string code = 5; bool is_compilation = 6; - int32 fk_albumtype_id = 7; - int32 fk_albumart_id = 8; + google.protobuf.Int32Value fk_albumtype_id = 7; // ← Mudou! + google.protobuf.Int32Value fk_albumart_id = 8; // ← Mudou! } message UpdateAlbumResponse { @@ -74,4 +74,4 @@ message DeleteAlbumRequest { message DeleteAlbumResponse { bool success = 1; string message = 2; -} +} \ No newline at end of file