diff --git a/src/main/java/com/mediamanager/mapper/AlbumHasArtistMapper.java b/src/main/java/com/mediamanager/mapper/AlbumHasArtistMapper.java new file mode 100644 index 0000000..58bf3ca --- /dev/null +++ b/src/main/java/com/mediamanager/mapper/AlbumHasArtistMapper.java @@ -0,0 +1,47 @@ +package com.mediamanager.mapper; + +import com.mediamanager.model.AlbumHasArtist; +import com.mediamanager.protocol.messages.AlbumHasArtistMessages; + +public class AlbumHasArtistMapper { + public static AlbumHasArtistMessages.AlbumHasArtist toProtobuf(AlbumHasArtist entity) { + if (entity == null) { + return null; + } + + AlbumHasArtistMessages.AlbumHasArtist.Builder builder = AlbumHasArtistMessages.AlbumHasArtist.newBuilder(); + + Integer id = entity.getId(); + if (id != null) { + builder.setId(id); + } + + // Map Album foreign key + if (entity.getAlbum() != null && entity.getAlbum().getId() != null) { + builder.setFkAlbumId(entity.getAlbum().getId()); + } + + // Map Artist foreign key + if (entity.getArtist() != null && entity.getArtist().getId() != null) { + builder.setFkArtistId(entity.getArtist().getId()); + } + + return builder.build(); + } + + public static AlbumHasArtist toEntity(AlbumHasArtistMessages.AlbumHasArtist protobuf) { + if (protobuf == null) { + return null; + } + + AlbumHasArtist entity = new AlbumHasArtist(); + + if (protobuf.getId() > 0) { + entity.setId(protobuf.getId()); + } + + // Note: Foreign key relationships (Album, Artist) are handled in the service layer + + return entity; + } +} diff --git a/src/main/java/com/mediamanager/model/AlbumHasArtist.java b/src/main/java/com/mediamanager/model/AlbumHasArtist.java new file mode 100644 index 0000000..aa04587 --- /dev/null +++ b/src/main/java/com/mediamanager/model/AlbumHasArtist.java @@ -0,0 +1,56 @@ +package com.mediamanager.model; + +import jakarta.persistence.*; + +@Entity +@Table(name = "albumshasartist") +public class AlbumHasArtist { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Integer id; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "fk_album_id", nullable = false) + private Album album; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "fk_artist_id", nullable = false) + private Artist artist; + + public AlbumHasArtist() {} + + // Getters and Setters + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public Album getAlbum() { + return album; + } + + public void setAlbum(Album album) { + this.album = album; + } + + public Artist getArtist() { + return artist; + } + + public void setArtist(Artist artist) { + this.artist = artist; + } + + @Override + public String toString() { + return "AlbumHasArtist{" + + "id=" + id + + ", albumId=" + (album != null ? album.getId() : null) + + ", artistId=" + (artist != null ? artist.getId() : null) + + '}'; + } +} diff --git a/src/main/java/com/mediamanager/repository/AlbumHasArtistRepository.java b/src/main/java/com/mediamanager/repository/AlbumHasArtistRepository.java new file mode 100644 index 0000000..f57140c --- /dev/null +++ b/src/main/java/com/mediamanager/repository/AlbumHasArtistRepository.java @@ -0,0 +1,85 @@ +package com.mediamanager.repository; + + +import com.mediamanager.model.AlbumHasArtist; +import jakarta.persistence.EntityManager; +import jakarta.persistence.EntityManagerFactory; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + + +import java.util.List; +import java.util.Optional; + +public class AlbumHasArtistRepository { + private static final Logger logger = LogManager.getLogger(AlbumHasArtistRepository.class); + + private final EntityManagerFactory entityManagerFactory; + + public AlbumHasArtistRepository(EntityManagerFactory entityManagerFactory) { + this.entityManagerFactory = entityManagerFactory; + } + + public AlbumHasArtist save(AlbumHasArtist albumHasArtist) { + logger.debug("Saving AlbumHasArtist: {}", albumHasArtist); + EntityManager em = entityManagerFactory.createEntityManager(); + em.getTransaction().begin(); + try { + em.persist(albumHasArtist); + em.getTransaction().commit(); + logger.debug("AlbumHasArtist has been saved successfully"); + return albumHasArtist; + } catch (Exception e) { + em.getTransaction().rollback(); + logger.error("Error while saving AlbumHasArtist: {}", e.getMessage()); + throw e; + } finally { + if (em.isOpen()) em.close(); + } + } + + public List findAll() { + logger.debug("Finding All AlbumHasArtist"); + EntityManager em = entityManagerFactory.createEntityManager(); + try{ + return em.createQuery("select a from AlbumHasArtist a", AlbumHasArtist.class).getResultList(); + }finally { + if (em.isOpen()) em.close(); + } + } + + public Optional findById(Integer id) { + logger.debug("Finding AlbumHasArtist with id: {}", id); + EntityManager em = entityManagerFactory.createEntityManager(); + try{ + AlbumHasArtist albumHasArtist = em.find(AlbumHasArtist.class, id); + return Optional.ofNullable(albumHasArtist); + }finally { + if (em.isOpen()) em.close(); + } + } + + public boolean deleteById(Integer id){ + logger.debug("Deleting AlbumHasArtist with id: {}", id); + EntityManager em = entityManagerFactory.createEntityManager(); + em.getTransaction().begin(); + try{ + AlbumHasArtist albumHasArtist = em.find(AlbumHasArtist.class, id); + if (albumHasArtist == null) { + em.getTransaction().rollback(); + return false; + } + em.remove(albumHasArtist); + em.getTransaction().commit(); + logger.debug("AlbumHasArtist has been deleted successfully"); + return true; + } catch (Exception e) { + em.getTransaction().rollback(); + logger.error("Error while deleting AlbumHasArtist: {}", e.getMessage()); + throw e; + } finally { + if (em.isOpen()) em.close(); + } + } + +} diff --git a/src/main/java/com/mediamanager/service/albumhasartist/AlbumHasArtistService.java b/src/main/java/com/mediamanager/service/albumhasartist/AlbumHasArtistService.java new file mode 100644 index 0000000..3687d2a --- /dev/null +++ b/src/main/java/com/mediamanager/service/albumhasartist/AlbumHasArtistService.java @@ -0,0 +1,77 @@ +package com.mediamanager.service.albumhasartist; + +import com.mediamanager.model.Album; +import com.mediamanager.model.AlbumHasArtist; +import com.mediamanager.model.Artist; +import com.mediamanager.repository.AlbumHasArtistRepository; +import com.mediamanager.repository.AlbumRepository; +import com.mediamanager.repository.ArtistRepository; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.util.List; +import java.util.Optional; + +public class AlbumHasArtistService { + private static final Logger logger = LogManager.getLogger(AlbumHasArtistService.class); + private final AlbumHasArtistRepository repository; + private final AlbumRepository albumRepository; + private final ArtistRepository artistRepository; + + public AlbumHasArtistService(AlbumHasArtistRepository repository, AlbumRepository albumRepository, ArtistRepository artistRepository) { + this.repository = repository; + this.albumRepository = albumRepository; + this.artistRepository = artistRepository; + } + + public AlbumHasArtist createAlbumHasArtist(Integer albumId, Integer artistId) { + logger.debug("Creating album has artist relationship - albumId:{}, artistId:{}", albumId, artistId); + + if (albumId == null || albumId <= 0) { + throw new IllegalArgumentException("Album ID cannot be null or invalid"); + } + if (artistId == null || artistId <= 0) { + throw new IllegalArgumentException("Artist ID cannot be null or invalid"); + } + + // Verify Album exists + Optional album = albumRepository.findById(albumId); + if (album.isEmpty()) { + throw new IllegalArgumentException("Album not found with id: " + albumId); + } + + // Verify Artist exists + Optional artist = artistRepository.findById(artistId); + if (artist.isEmpty()) { + throw new IllegalArgumentException("Artist not found with id: " + artistId); + } + + AlbumHasArtist albumHasArtist = new AlbumHasArtist(); + albumHasArtist.setAlbum(album.get()); + albumHasArtist.setArtist(artist.get()); + + return repository.save(albumHasArtist); + } + + public List getAllAlbumHasArtists() { + logger.info("Getting all album has artist relationships"); + return repository.findAll(); + } + + public Optional getAlbumHasArtistById(Integer id) { + if (id == null) { + throw new IllegalArgumentException("ID cannot be null"); + } + logger.info("Getting album has artist by id:{}", id); + return repository.findById(id); + } + + public boolean deleteAlbumHasArtist(Integer id) { + if (id == null) { + throw new IllegalArgumentException("Album has artist id cannot be null"); + } + logger.info("Deleting album has artist:{}", id); + return repository.deleteById(id); + } + +} diff --git a/src/main/java/com/mediamanager/service/delegate/DelegateActionManager.java b/src/main/java/com/mediamanager/service/delegate/DelegateActionManager.java index c8a7251..8fca373 100644 --- a/src/main/java/com/mediamanager/service/delegate/DelegateActionManager.java +++ b/src/main/java/com/mediamanager/service/delegate/DelegateActionManager.java @@ -5,6 +5,7 @@ import com.mediamanager.protocol.TransportProtocol; import com.mediamanager.repository.*; import com.mediamanager.service.album.AlbumService; import com.mediamanager.service.albumart.AlbumArtService; +import com.mediamanager.service.albumhasartist.AlbumHasArtistService; import com.mediamanager.service.albumtype.AlbumTypeService; import com.mediamanager.service.bitdepth.BitDepthService; import com.mediamanager.service.bitrate.BitRateService; @@ -90,6 +91,10 @@ public class DelegateActionManager { AlbumService albumService = new AlbumService(albumRepository, albumTypeRepository, albumArtRepository); serviceLocator.register(AlbumService.class, albumService); + AlbumHasArtistRepository albumHasArtistRepository = new AlbumHasArtistRepository(entityManagerFactory); + AlbumHasArtistService albumHasArtistService = new AlbumHasArtistService(albumHasArtistRepository, albumRepository, artistRepository); + serviceLocator.register(AlbumHasArtistService.class, albumHasArtistService); + serviceLocator.logRegisteredServices(); logger.info("Services initialized successfully"); diff --git a/src/main/java/com/mediamanager/service/delegate/handler/albumhasartist/CreateAlbumHasArtistHandler.java b/src/main/java/com/mediamanager/service/delegate/handler/albumhasartist/CreateAlbumHasArtistHandler.java new file mode 100644 index 0000000..07c65be --- /dev/null +++ b/src/main/java/com/mediamanager/service/delegate/handler/albumhasartist/CreateAlbumHasArtistHandler.java @@ -0,0 +1,54 @@ +package com.mediamanager.service.delegate.handler.albumhasartist; + +import com.google.protobuf.ByteString; +import com.google.protobuf.InvalidProtocolBufferException; +import com.mediamanager.mapper.AlbumHasArtistMapper; +import com.mediamanager.model.AlbumHasArtist; +import com.mediamanager.protocol.TransportProtocol; +import com.mediamanager.protocol.messages.AlbumHasArtistMessages; +import com.mediamanager.service.delegate.ActionHandler; +import com.mediamanager.service.delegate.annotation.Action; +import com.mediamanager.service.albumhasartist.AlbumHasArtistService; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +@Action("albumhasartist.create") +public class CreateAlbumHasArtistHandler implements ActionHandler { + private static final Logger logger = LogManager.getLogger(CreateAlbumHasArtistHandler.class); + private final AlbumHasArtistService albumHasArtistService; + + public CreateAlbumHasArtistHandler(AlbumHasArtistService albumHasArtistService) { + this.albumHasArtistService = albumHasArtistService; + } + + @Override + public TransportProtocol.Response.Builder handle(ByteString requestPayload) throws InvalidProtocolBufferException { + try{ + AlbumHasArtistMessages.CreateAlbumHasArtistRequest createRequest = + AlbumHasArtistMessages.CreateAlbumHasArtistRequest.parseFrom(requestPayload); + + AlbumHasArtist albumHasArtist = albumHasArtistService.createAlbumHasArtist( + createRequest.getFkAlbumId() > 0 ? createRequest.getFkAlbumId() : null, + createRequest.getFkArtistId() > 0 ? createRequest.getFkArtistId() : null + ); + + AlbumHasArtistMessages.AlbumHasArtist albumHasArtistProto = AlbumHasArtistMapper.toProtobuf(albumHasArtist); + AlbumHasArtistMessages.CreateAlbumHasArtistResponse createAlbumHasArtistResponse = AlbumHasArtistMessages.CreateAlbumHasArtistResponse.newBuilder() + .setAlbumhasartist(albumHasArtistProto) + .build(); + return TransportProtocol.Response.newBuilder() + .setPayload(createAlbumHasArtistResponse.toByteString()); + } catch (IllegalArgumentException e) { + logger.error("Validation error", e); + return TransportProtocol.Response.newBuilder() + .setStatusCode(400) + .setPayload(ByteString.copyFromUtf8("Validation error: " + e.getMessage())); + + } catch (Exception e) { + logger.error("Error creating album has artist", e); + return TransportProtocol.Response.newBuilder() + .setStatusCode(500) + .setPayload(ByteString.copyFromUtf8("Error: " + e.getMessage())); + } + } +} diff --git a/src/main/java/com/mediamanager/service/delegate/handler/albumhasartist/DeleteAlbumHasArtistHandler.java b/src/main/java/com/mediamanager/service/delegate/handler/albumhasartist/DeleteAlbumHasArtistHandler.java new file mode 100644 index 0000000..c095e1a --- /dev/null +++ b/src/main/java/com/mediamanager/service/delegate/handler/albumhasartist/DeleteAlbumHasArtistHandler.java @@ -0,0 +1,62 @@ +package com.mediamanager.service.delegate.handler.albumhasartist; + +import com.google.protobuf.ByteString; +import com.google.protobuf.InvalidProtocolBufferException; +import com.mediamanager.protocol.TransportProtocol; +import com.mediamanager.protocol.messages.AlbumHasArtistMessages; +import com.mediamanager.service.delegate.ActionHandler; +import com.mediamanager.service.delegate.annotation.Action; +import com.mediamanager.service.albumhasartist.AlbumHasArtistService; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +@Action("albumhasartist.delete") +public class DeleteAlbumHasArtistHandler implements ActionHandler { + private static final Logger logger = LogManager.getLogger(DeleteAlbumHasArtistHandler.class); + + private final AlbumHasArtistService albumHasArtistService; + + public DeleteAlbumHasArtistHandler(AlbumHasArtistService albumHasArtistService) { + this.albumHasArtistService = albumHasArtistService; + } + + @Override + public TransportProtocol.Response.Builder handle(ByteString requestPayload) + throws InvalidProtocolBufferException { + + try { + AlbumHasArtistMessages.DeleteAlbumHasArtistRequest deleteRequest = + AlbumHasArtistMessages.DeleteAlbumHasArtistRequest.parseFrom(requestPayload); + int id = deleteRequest.getId(); + boolean success = albumHasArtistService.deleteAlbumHasArtist(id); + AlbumHasArtistMessages.DeleteAlbumHasArtistResponse deleteResponse; + if (success) { + deleteResponse = AlbumHasArtistMessages.DeleteAlbumHasArtistResponse.newBuilder() + .setSuccess(true) + .setMessage("Album has artist deleted successfully") + .build(); + return TransportProtocol.Response.newBuilder() + .setPayload(deleteResponse.toByteString()); + } else { + deleteResponse = AlbumHasArtistMessages.DeleteAlbumHasArtistResponse.newBuilder() + .setSuccess(false) + .setMessage("Album has artist not found") + .build(); + + return TransportProtocol.Response.newBuilder() + .setStatusCode(404) + .setPayload(deleteResponse.toByteString()); + } + } catch (Exception e) { + logger.error("Error deleting album has artist", e); + AlbumHasArtistMessages.DeleteAlbumHasArtistResponse deleteResponse = + AlbumHasArtistMessages.DeleteAlbumHasArtistResponse.newBuilder() + .setSuccess(false) + .setMessage("Error: " + e.getMessage()) + .build(); + return TransportProtocol.Response.newBuilder() + .setStatusCode(500) + .setPayload(deleteResponse.toByteString()); + } + } + } diff --git a/src/main/java/com/mediamanager/service/delegate/handler/albumhasartist/GetAlbumHasArtistByIdHandler.java b/src/main/java/com/mediamanager/service/delegate/handler/albumhasartist/GetAlbumHasArtistByIdHandler.java new file mode 100644 index 0000000..03cec95 --- /dev/null +++ b/src/main/java/com/mediamanager/service/delegate/handler/albumhasartist/GetAlbumHasArtistByIdHandler.java @@ -0,0 +1,56 @@ +package com.mediamanager.service.delegate.handler.albumhasartist; + +import com.google.protobuf.ByteString; +import com.google.protobuf.InvalidProtocolBufferException; +import com.mediamanager.mapper.AlbumHasArtistMapper; +import com.mediamanager.model.AlbumHasArtist; +import com.mediamanager.protocol.TransportProtocol; +import com.mediamanager.protocol.messages.AlbumHasArtistMessages; +import com.mediamanager.service.delegate.ActionHandler; +import com.mediamanager.service.delegate.annotation.Action; +import com.mediamanager.service.albumhasartist.AlbumHasArtistService; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.util.Optional; + +@Action(value = "albumhasartist.getById") +public class GetAlbumHasArtistByIdHandler implements ActionHandler { + private static final Logger logger = LogManager.getLogger(GetAlbumHasArtistByIdHandler.class); + private final AlbumHasArtistService albumHasArtistService; + + public GetAlbumHasArtistByIdHandler(AlbumHasArtistService albumHasArtistService) { + this.albumHasArtistService = albumHasArtistService; + } + + @Override + public TransportProtocol.Response.Builder handle(ByteString requestPayload) + throws InvalidProtocolBufferException{ + + try{ + AlbumHasArtistMessages.GetAlbumHasArtistByIdRequest getByIdRequest = + AlbumHasArtistMessages.GetAlbumHasArtistByIdRequest.parseFrom(requestPayload); + int id = getByIdRequest.getId(); + + Optional albumHasArtistOpt = albumHasArtistService.getAlbumHasArtistById(id); + + if (albumHasArtistOpt.isEmpty()){ + logger.warn("AlbumHasArtist not found with ID: {}", id); + return TransportProtocol.Response.newBuilder() + .setStatusCode(404) + .setPayload(ByteString.copyFromUtf8("AlbumHasArtist not found")); + } + AlbumHasArtistMessages.AlbumHasArtist albumHasArtistProto = AlbumHasArtistMapper.toProtobuf(albumHasArtistOpt.get()); + AlbumHasArtistMessages.GetAlbumHasArtistByIdResponse getByIdResponse = AlbumHasArtistMessages.GetAlbumHasArtistByIdResponse.newBuilder() + .setAlbumhasartist(albumHasArtistProto) + .build(); + return TransportProtocol.Response.newBuilder() + .setPayload(getByIdResponse.toByteString()); + } catch (Exception e) { + logger.error("Error getting album has artist by ID", e); + return TransportProtocol.Response.newBuilder() + .setStatusCode(500) + .setPayload(ByteString.copyFromUtf8("Error: "+ e.getMessage())); + } + } +} diff --git a/src/main/java/com/mediamanager/service/delegate/handler/albumhasartist/GetAlbumHasArtistHandler.java b/src/main/java/com/mediamanager/service/delegate/handler/albumhasartist/GetAlbumHasArtistHandler.java new file mode 100644 index 0000000..1f2d0fc --- /dev/null +++ b/src/main/java/com/mediamanager/service/delegate/handler/albumhasartist/GetAlbumHasArtistHandler.java @@ -0,0 +1,48 @@ +package com.mediamanager.service.delegate.handler.albumhasartist; + +import com.google.protobuf.ByteString; +import com.google.protobuf.InvalidProtocolBufferException; +import com.mediamanager.mapper.AlbumHasArtistMapper; +import com.mediamanager.model.AlbumHasArtist; +import com.mediamanager.protocol.TransportProtocol; +import com.mediamanager.protocol.messages.AlbumHasArtistMessages; +import com.mediamanager.service.delegate.ActionHandler; +import com.mediamanager.service.delegate.annotation.Action; +import com.mediamanager.service.albumhasartist.AlbumHasArtistService; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.util.List; + + +@Action("albumhasartist.getAll") +public class GetAlbumHasArtistHandler implements ActionHandler { + private static final Logger logger = LogManager.getLogger(GetAlbumHasArtistHandler.class); + + private final AlbumHasArtistService albumHasArtistService; + + public GetAlbumHasArtistHandler(AlbumHasArtistService albumHasArtistService){this.albumHasArtistService = albumHasArtistService;} + + @Override + public TransportProtocol.Response.Builder handle(ByteString requestPayload) throws InvalidProtocolBufferException { + try{ + List albumHasArtists = albumHasArtistService.getAllAlbumHasArtists(); + AlbumHasArtistMessages.GetAlbumHasArtistsResponse.Builder responseBuilder = AlbumHasArtistMessages.GetAlbumHasArtistsResponse.newBuilder(); + + for (AlbumHasArtist albumHasArtist : albumHasArtists) { + AlbumHasArtistMessages.AlbumHasArtist albumHasArtistProto = AlbumHasArtistMapper.toProtobuf(albumHasArtist); + responseBuilder.addAlbumhasartist(albumHasArtistProto); + } + AlbumHasArtistMessages.GetAlbumHasArtistsResponse getAlbumHasArtistsResponse = responseBuilder.build(); + + return TransportProtocol.Response.newBuilder() + .setPayload(getAlbumHasArtistsResponse.toByteString()); + + }catch (Exception e){ + logger.error("Error getting album has artists", e); + return TransportProtocol.Response.newBuilder() + .setStatusCode(500) + .setPayload(ByteString.copyFromUtf8("Error: " + e.getMessage())); + } + } +} diff --git a/src/main/proto/albumhasartist.proto b/src/main/proto/albumhasartist.proto new file mode 100644 index 0000000..190a5c7 --- /dev/null +++ b/src/main/proto/albumhasartist.proto @@ -0,0 +1,46 @@ +syntax = "proto3"; + +option java_package = "com.mediamanager.protocol.messages"; +option java_outer_classname = "AlbumHasArtistMessages"; + +package mediamanager.messages; + +message AlbumHasArtist { + int32 id = 1; + int32 fk_album_id = 2; + int32 fk_artist_id = 3; +} + +message CreateAlbumHasArtistRequest { + int32 fk_album_id = 1; + int32 fk_artist_id = 2; +} + +message CreateAlbumHasArtistResponse { + AlbumHasArtist albumhasartist = 1; +} + +message GetAlbumHasArtistsRequest { + +} + +message GetAlbumHasArtistsResponse { + repeated AlbumHasArtist albumhasartist = 1; +} + +message GetAlbumHasArtistByIdRequest { + int32 id = 1; +} + +message GetAlbumHasArtistByIdResponse { + AlbumHasArtist albumhasartist = 1; +} + +message DeleteAlbumHasArtistRequest { + int32 id = 1; +} + +message DeleteAlbumHasArtistResponse { + bool success = 1; + string message = 2; +} \ No newline at end of file