diff --git a/src/main/java/com/mediamanager/mapper/TrackMapper.java b/src/main/java/com/mediamanager/mapper/TrackMapper.java new file mode 100644 index 0000000..0c6742a --- /dev/null +++ b/src/main/java/com/mediamanager/mapper/TrackMapper.java @@ -0,0 +1,95 @@ +package com.mediamanager.mapper; + +import com.mediamanager.model.Track; +import com.mediamanager.protocol.messages.TrackMessages; + +public class TrackMapper { + public static TrackMessages.Track toProtobuf(Track entity) { + if (entity == null) { + return null; + } + + Integer trackNumber = entity.getTrackNumber(); + if (trackNumber == null) { + throw new IllegalArgumentException("Track number cannot be null"); + } + + String title = entity.getTitle(); + if (title == null) { + throw new IllegalArgumentException("Title cannot be null"); + } + + String filepath = entity.getFilepath(); + if (filepath == null) { + throw new IllegalArgumentException("Filepath cannot be null"); + } + + TrackMessages.Track.Builder builder = TrackMessages.Track.newBuilder() + .setTrackNumber(trackNumber) + .setTitle(title) + .setFilepath(filepath); + + Integer id = entity.getId(); + if (id != null) { + builder.setId(id); + } + + // Map duration (optional) + Integer duration = entity.getDuration(); + if (duration != null) { + builder.setDuration(duration); + } + + // Map Disc foreign key (required) + if (entity.getDisc() != null && entity.getDisc().getId() != null) { + builder.setFkDiscId(entity.getDisc().getId()); + } + + // Map Composer foreign key (optional) + if (entity.getComposer() != null && entity.getComposer().getId() != null) { + builder.setFkComposerId(entity.getComposer().getId()); + } + + // Map BitDepth foreign key (optional) + if (entity.getBitDepth() != null && entity.getBitDepth().getId() != null) { + builder.setFkBitdepthId(entity.getBitDepth().getId()); + } + + // Map BitRate foreign key (optional) + if (entity.getBitRate() != null && entity.getBitRate().getId() != null) { + builder.setFkBitrateId(entity.getBitRate().getId()); + } + + // Map SamplingRate foreign key (optional) + if (entity.getSamplingRate() != null && entity.getSamplingRate().getId() != null) { + builder.setFkSamplingrateId(entity.getSamplingRate().getId()); + } + + return builder.build(); + } + + public static Track toEntity(TrackMessages.Track protobuf) { + if (protobuf == null) { + return null; + } + + Track entity = new Track(); + + if (protobuf.getId() > 0) { + entity.setId(protobuf.getId()); + } + + entity.setTrackNumber(protobuf.getTrackNumber()); + entity.setTitle(protobuf.getTitle()); + entity.setFilepath(protobuf.getFilepath()); + + if (protobuf.getDuration() > 0) { + entity.setDuration(protobuf.getDuration()); + } + + // Note: Foreign key relationships (Disc, Composer, BitDepth, BitRate, SamplingRate) + // are handled in the service layer + + return entity; + } +} diff --git a/src/main/java/com/mediamanager/model/Track.java b/src/main/java/com/mediamanager/model/Track.java new file mode 100644 index 0000000..b939554 --- /dev/null +++ b/src/main/java/com/mediamanager/model/Track.java @@ -0,0 +1,128 @@ +package com.mediamanager.model; + +import jakarta.persistence.*; + +@Entity +@Table(name = "track") +public class Track { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Integer id; + + @Column(name = "track_number") + private Integer trackNumber; + + @Column + private String title; + + @Column + private Integer duration; + + @Column + private String filepath; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "fk_disc_id") + private Disc disc; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "fk_composer_id") + private Composer composer; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "fk_bit_depth_id") + private BitDepth bitDepth; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "fk_bit_rate_id") + private BitRate bitRate; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "fk_sampling_rate_id") + private SamplingRate samplingRate; + + public Track() { + + } + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public Integer getTrackNumber() { + return trackNumber; + } + + public void setTrackNumber(Integer trackNumber) { + this.trackNumber = trackNumber; + } + + public String getTitle() { + return title; + } + + public void setTitle(String name) { + this.title = name; + } + + public Integer getDuration() { + return duration; + } + + public void setDuration(Integer duration) { + this.duration = duration; + } + + public String getFilepath() { + return filepath; + } + + public void setFilepath(String filepath) { + this.filepath = filepath; + } + + public Disc getDisc() { + return disc; + } + + public void setDisc(Disc disc) { + this.disc = disc; + } + + public Composer getComposer() { + return composer; + } + + public void setComposer(Composer composer) { + this.composer = composer; + } + + public BitDepth getBitDepth() { + return bitDepth; + } + + public void setBitDepth(BitDepth bitDepth) { + this.bitDepth = bitDepth; + } + + public BitRate getBitRate() { + return bitRate; + } + + public void setBitRate(BitRate bitRate) { + this.bitRate = bitRate; + } + + public SamplingRate getSamplingRate() { + return samplingRate; + } + + public void setSamplingRate(SamplingRate samplingRate) { + this.samplingRate = samplingRate; + } +} diff --git a/src/main/java/com/mediamanager/repository/TrackRepository.java b/src/main/java/com/mediamanager/repository/TrackRepository.java new file mode 100644 index 0000000..47dfff8 --- /dev/null +++ b/src/main/java/com/mediamanager/repository/TrackRepository.java @@ -0,0 +1,100 @@ +package com.mediamanager.repository; + +import com.mediamanager.model.Track; +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 TrackRepository { + private static final Logger logger = LogManager.getLogger(TrackRepository.class); + + private final EntityManagerFactory entityManagerFactory; + + public TrackRepository(EntityManagerFactory entityManagerFactory) { + this.entityManagerFactory = entityManagerFactory; + } + + public Track save(Track track) { + logger.debug("Saving Track: {}", track.getTitle()); + EntityManager em = entityManagerFactory.createEntityManager(); + em.getTransaction().begin(); + try { + em.persist(track); + em.getTransaction().commit(); + logger.debug("Track has been saved successfully"); + return track; + } catch (Exception e) { + em.getTransaction().rollback(); + logger.error("Error while saving Track: {}", e.getMessage()); + throw e; + } finally { + if (em.isOpen()) em.close(); + } + } + + public List findAll() { + logger.debug("Finding All Track"); + EntityManager em = entityManagerFactory.createEntityManager(); + try{ + return em.createQuery("select t from Track t", Track.class).getResultList(); + }finally { + if (em.isOpen()) em.close(); + } + } + + public Optional findById(Integer id) { + logger.debug("Finding Track with id: {}", id); + EntityManager em = entityManagerFactory.createEntityManager(); + try{ + Track track = em.find(Track.class, id); + return Optional.ofNullable(track); + }finally { + if (em.isOpen()) em.close(); + } + } + + public Track update(Track track) { + logger.debug("Updating Track: {}", track.getTitle()); + EntityManager em = entityManagerFactory.createEntityManager(); + em.getTransaction().begin(); + try { + Track updated = em.merge(track); + em.getTransaction().commit(); + logger.debug("Track has been updated successfully"); + return updated; + } catch (Exception e) { + em.getTransaction().rollback(); + logger.error("Error while updating Track: {}", e.getMessage()); + throw e; + } finally { + if (em.isOpen()) em.close(); + } + } + + public boolean deleteById(Integer id){ + logger.debug("Deleting Track with id: {}", id); + EntityManager em = entityManagerFactory.createEntityManager(); + em.getTransaction().begin(); + try{ + Track track = em.find(Track.class, id); + if (track == null) { + em.getTransaction().rollback(); + return false; + } + em.remove(track); + em.getTransaction().commit(); + logger.debug("Track has been deleted successfully"); + return true; + } catch (Exception e) { + em.getTransaction().rollback(); + logger.error("Error while deleting Track: {}", e.getMessage()); + throw e; + } finally { + if (em.isOpen()) em.close(); + } + } +} diff --git a/src/main/java/com/mediamanager/service/delegate/DelegateActionManager.java b/src/main/java/com/mediamanager/service/delegate/DelegateActionManager.java index a849a5d..11c3354 100644 --- a/src/main/java/com/mediamanager/service/delegate/DelegateActionManager.java +++ b/src/main/java/com/mediamanager/service/delegate/DelegateActionManager.java @@ -12,8 +12,10 @@ import com.mediamanager.service.albumtype.AlbumTypeService; import com.mediamanager.service.bitdepth.BitDepthService; import com.mediamanager.service.bitrate.BitRateService; import com.mediamanager.service.composer.ComposerService; + import com.mediamanager.repository.GenreRepository; import com.mediamanager.service.artist.ArtistService; +import com.mediamanager.service.track.TrackService; import com.mediamanager.service.delegate.annotation.Action; import com.mediamanager.service.disc.DiscService; @@ -106,6 +108,10 @@ public class DelegateActionManager { DiscService discService = new DiscService(discRepository, albumRepository); serviceLocator.register(DiscService.class, discService); + TrackRepository trackRepository = new TrackRepository(entityManagerFactory); + TrackService trackService = new TrackService(trackRepository, discRepository, composerRepository, bitDepthRepository, bitRateRepository, samplingRateRepository); + serviceLocator.register(TrackService.class, trackService); + serviceLocator.logRegisteredServices(); logger.info("Services initialized successfully"); diff --git a/src/main/java/com/mediamanager/service/delegate/handler/track/CreateTrackHandler.java b/src/main/java/com/mediamanager/service/delegate/handler/track/CreateTrackHandler.java new file mode 100644 index 0000000..12aaf6f --- /dev/null +++ b/src/main/java/com/mediamanager/service/delegate/handler/track/CreateTrackHandler.java @@ -0,0 +1,61 @@ +package com.mediamanager.service.delegate.handler.track; + +import com.google.protobuf.ByteString; +import com.google.protobuf.InvalidProtocolBufferException; +import com.mediamanager.mapper.TrackMapper; +import com.mediamanager.model.Track; +import com.mediamanager.protocol.TransportProtocol; +import com.mediamanager.protocol.messages.TrackMessages; +import com.mediamanager.service.delegate.ActionHandler; +import com.mediamanager.service.delegate.annotation.Action; +import com.mediamanager.service.track.TrackService; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +@Action("track.create") +public class CreateTrackHandler implements ActionHandler { + private static final Logger logger = LogManager.getLogger(CreateTrackHandler.class); + private final TrackService trackService; + + public CreateTrackHandler(TrackService trackService) { + this.trackService = trackService; + } + + @Override + public TransportProtocol.Response.Builder handle(ByteString requestPayload) throws InvalidProtocolBufferException { + try{ + TrackMessages.CreateTrackRequest createRequest = + TrackMessages.CreateTrackRequest.parseFrom(requestPayload); + + Track track = trackService.createTrack( + createRequest.getTrackNumber(), + createRequest.getTitle(), + createRequest.hasDuration() ? createRequest.getDuration().getValue() : null, + createRequest.getFilepath(), + createRequest.getFkDiscId() > 0 ? createRequest.getFkDiscId() : null, + createRequest.hasFkComposerId() ? createRequest.getFkComposerId().getValue() : null, + createRequest.hasFkBitdepthId() ? createRequest.getFkBitdepthId().getValue() : null, + createRequest.hasFkBitrateId() ? createRequest.getFkBitrateId().getValue() : null, + createRequest.hasFkSamplingrateId() ? createRequest.getFkSamplingrateId().getValue() : null + ); + + TrackMessages.Track trackProto = TrackMapper.toProtobuf(track); + TrackMessages.CreateTrackResponse createTrackResponse = TrackMessages.CreateTrackResponse.newBuilder() + .setTrack(trackProto) + .build(); + return TransportProtocol.Response.newBuilder() + .setPayload(createTrackResponse.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 track", e); + return TransportProtocol.Response.newBuilder() + .setStatusCode(500) + .setPayload(ByteString.copyFromUtf8("Error: " + e.getMessage())); + } + } +} diff --git a/src/main/java/com/mediamanager/service/delegate/handler/track/DeleteTrackHandler.java b/src/main/java/com/mediamanager/service/delegate/handler/track/DeleteTrackHandler.java new file mode 100644 index 0000000..b967783 --- /dev/null +++ b/src/main/java/com/mediamanager/service/delegate/handler/track/DeleteTrackHandler.java @@ -0,0 +1,62 @@ +package com.mediamanager.service.delegate.handler.track; + +import com.google.protobuf.ByteString; +import com.google.protobuf.InvalidProtocolBufferException; +import com.mediamanager.protocol.TransportProtocol; +import com.mediamanager.protocol.messages.TrackMessages; +import com.mediamanager.service.delegate.ActionHandler; +import com.mediamanager.service.delegate.annotation.Action; +import com.mediamanager.service.track.TrackService; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +@Action("track.delete") +public class DeleteTrackHandler implements ActionHandler { + private static final Logger logger = LogManager.getLogger(DeleteTrackHandler.class); + + private final TrackService trackService; + + public DeleteTrackHandler(TrackService trackService) { + this.trackService = trackService; + } + + @Override + public TransportProtocol.Response.Builder handle(ByteString requestPayload) + throws InvalidProtocolBufferException { + + try { + TrackMessages.DeleteTrackRequest deleteRequest = + TrackMessages.DeleteTrackRequest.parseFrom(requestPayload); + int id = deleteRequest.getId(); + boolean success = trackService.deleteTrack(id); + TrackMessages.DeleteTrackResponse deleteResponse; + if (success) { + deleteResponse = TrackMessages.DeleteTrackResponse.newBuilder() + .setSuccess(true) + .setMessage("Track deleted successfully") + .build(); + return TransportProtocol.Response.newBuilder() + .setPayload(deleteResponse.toByteString()); + } else { + deleteResponse = TrackMessages.DeleteTrackResponse.newBuilder() + .setSuccess(false) + .setMessage("Track not found") + .build(); + + return TransportProtocol.Response.newBuilder() + .setStatusCode(404) + .setPayload(deleteResponse.toByteString()); + } + } catch (Exception e) { + logger.error("Error deleting track", e); + TrackMessages.DeleteTrackResponse deleteResponse = + TrackMessages.DeleteTrackResponse.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/track/GetTrackByIdHandler.java b/src/main/java/com/mediamanager/service/delegate/handler/track/GetTrackByIdHandler.java new file mode 100644 index 0000000..400e4a6 --- /dev/null +++ b/src/main/java/com/mediamanager/service/delegate/handler/track/GetTrackByIdHandler.java @@ -0,0 +1,56 @@ +package com.mediamanager.service.delegate.handler.track; + +import com.google.protobuf.ByteString; +import com.google.protobuf.InvalidProtocolBufferException; +import com.mediamanager.mapper.TrackMapper; +import com.mediamanager.model.Track; +import com.mediamanager.protocol.TransportProtocol; +import com.mediamanager.protocol.messages.TrackMessages; +import com.mediamanager.service.delegate.ActionHandler; +import com.mediamanager.service.delegate.annotation.Action; +import com.mediamanager.service.track.TrackService; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.util.Optional; + +@Action(value = "track.getById") +public class GetTrackByIdHandler implements ActionHandler { + private static final Logger logger = LogManager.getLogger(GetTrackByIdHandler.class); + private final TrackService trackService; + + public GetTrackByIdHandler(TrackService trackService) { + this.trackService = trackService; + } + + @Override + public TransportProtocol.Response.Builder handle(ByteString requestPayload) + throws InvalidProtocolBufferException{ + + try{ + TrackMessages.GetTrackByIdRequest getByIdRequest = + TrackMessages.GetTrackByIdRequest.parseFrom(requestPayload); + int id = getByIdRequest.getId(); + + Optional trackOpt = trackService.getTrackById(id); + + if (trackOpt.isEmpty()){ + logger.warn("Track not found with ID: {}", id); + return TransportProtocol.Response.newBuilder() + .setStatusCode(404) + .setPayload(ByteString.copyFromUtf8("Track not found")); + } + TrackMessages.Track trackProto = TrackMapper.toProtobuf(trackOpt.get()); + TrackMessages.GetTrackByIdResponse getByIdResponse = TrackMessages.GetTrackByIdResponse.newBuilder() + .setTrack(trackProto) + .build(); + return TransportProtocol.Response.newBuilder() + .setPayload(getByIdResponse.toByteString()); + } catch (Exception e) { + logger.error("Error getting track 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/track/GetTrackHandler.java b/src/main/java/com/mediamanager/service/delegate/handler/track/GetTrackHandler.java new file mode 100644 index 0000000..254eea1 --- /dev/null +++ b/src/main/java/com/mediamanager/service/delegate/handler/track/GetTrackHandler.java @@ -0,0 +1,47 @@ +package com.mediamanager.service.delegate.handler.track; + +import com.google.protobuf.ByteString; +import com.google.protobuf.InvalidProtocolBufferException; +import com.mediamanager.mapper.TrackMapper; +import com.mediamanager.model.Track; +import com.mediamanager.protocol.TransportProtocol; +import com.mediamanager.protocol.messages.TrackMessages; +import com.mediamanager.service.delegate.ActionHandler; +import com.mediamanager.service.delegate.annotation.Action; +import com.mediamanager.service.track.TrackService; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.util.List; + +@Action("track.getAll") +public class GetTrackHandler implements ActionHandler { + private static final Logger logger = LogManager.getLogger(GetTrackHandler.class); + + private final TrackService trackService; + + public GetTrackHandler(TrackService trackService){this.trackService = trackService;} + + @Override + public TransportProtocol.Response.Builder handle(ByteString requestPayload) throws InvalidProtocolBufferException { + try{ + List tracks = trackService.getAllTracks(); + TrackMessages.GetTracksResponse.Builder responseBuilder = TrackMessages.GetTracksResponse.newBuilder(); + + for (Track track : tracks) { + TrackMessages.Track trackProto = TrackMapper.toProtobuf(track); + responseBuilder.addTracks(trackProto); + } + TrackMessages.GetTracksResponse getTracksResponse = responseBuilder.build(); + + return TransportProtocol.Response.newBuilder() + .setPayload(getTracksResponse.toByteString()); + + }catch (Exception e){ + logger.error("Error getting tracks", e); + return TransportProtocol.Response.newBuilder() + .setStatusCode(500) + .setPayload(ByteString.copyFromUtf8("Error: " + e.getMessage())); + } + } +} diff --git a/src/main/java/com/mediamanager/service/delegate/handler/track/UpdateTrackHandler.java b/src/main/java/com/mediamanager/service/delegate/handler/track/UpdateTrackHandler.java new file mode 100644 index 0000000..19e5ee9 --- /dev/null +++ b/src/main/java/com/mediamanager/service/delegate/handler/track/UpdateTrackHandler.java @@ -0,0 +1,86 @@ +package com.mediamanager.service.delegate.handler.track; + +import com.google.protobuf.ByteString; +import com.google.protobuf.InvalidProtocolBufferException; +import com.mediamanager.mapper.TrackMapper; +import com.mediamanager.model.Track; +import com.mediamanager.protocol.TransportProtocol; +import com.mediamanager.protocol.messages.TrackMessages; +import com.mediamanager.service.delegate.ActionHandler; +import com.mediamanager.service.delegate.annotation.Action; +import com.mediamanager.service.track.TrackService; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.util.Optional; + +@Action("track.update") +public class UpdateTrackHandler implements ActionHandler { + private static final Logger logger = LogManager.getLogger(UpdateTrackHandler.class); + private final TrackService trackService; + + public UpdateTrackHandler(TrackService trackService) { + this.trackService = trackService; + } + + @Override + public TransportProtocol.Response.Builder handle(ByteString requestPayload) + throws InvalidProtocolBufferException { + try { + TrackMessages.UpdateTrackRequest updateRequest = + TrackMessages.UpdateTrackRequest.parseFrom(requestPayload); + + int id = updateRequest.getId(); + Integer trackNumber = updateRequest.hasTrackNumber() ? updateRequest.getTrackNumber().getValue() : null; + String title = updateRequest.getTitle(); + Integer duration = updateRequest.hasDuration() ? updateRequest.getDuration().getValue() : null; + String filepath = updateRequest.getFilepath(); + Integer discId = updateRequest.hasFkDiscId() ? updateRequest.getFkDiscId().getValue() : null; + Integer composerId = updateRequest.hasFkComposerId() ? updateRequest.getFkComposerId().getValue() : null; + Integer bitDepthId = updateRequest.hasFkBitdepthId() ? updateRequest.getFkBitdepthId().getValue() : null; + Integer bitRateId = updateRequest.hasFkBitrateId() ? updateRequest.getFkBitrateId().getValue() : null; + Integer samplingRateId = updateRequest.hasFkSamplingrateId() ? updateRequest.getFkSamplingrateId().getValue() : null; + + Optional trackOpt = trackService.updateTrack( + id, + trackNumber, + title, + duration, + filepath, + discId, + composerId, + bitDepthId, + bitRateId, + samplingRateId + ); + + if (trackOpt.isEmpty()) { + logger.warn("Track not found with ID: {}", id); + return TransportProtocol.Response.newBuilder() + .setStatusCode(404) + .setPayload(ByteString.copyFromUtf8("Track not found")); + } + + TrackMessages.Track trackProto = TrackMapper.toProtobuf(trackOpt.get()); + + TrackMessages.UpdateTrackResponse updateResponse = + TrackMessages.UpdateTrackResponse.newBuilder() + .setTrack(trackProto) + .build(); + + return TransportProtocol.Response.newBuilder() + .setPayload(updateResponse.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 updating track", e); + return TransportProtocol.Response.newBuilder() + .setStatusCode(500) + .setPayload(ByteString.copyFromUtf8("Error: " + e.getMessage())); + } + } +} diff --git a/src/main/java/com/mediamanager/service/track/TrackService.java b/src/main/java/com/mediamanager/service/track/TrackService.java new file mode 100644 index 0000000..a045b44 --- /dev/null +++ b/src/main/java/com/mediamanager/service/track/TrackService.java @@ -0,0 +1,213 @@ +package com.mediamanager.service.track; + +import com.mediamanager.model.*; +import com.mediamanager.repository.*; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.util.List; +import java.util.Optional; + +public class TrackService { + private static final Logger logger = LogManager.getLogger(TrackService.class); + private final TrackRepository repository; + private final DiscRepository discRepository; + private final ComposerRepository composerRepository; + private final BitDepthRepository bitDepthRepository; + private final BitRateRepository bitRateRepository; + private final SamplingRateRepository samplingRateRepository; + + public TrackService(TrackRepository repository, + DiscRepository discRepository, + ComposerRepository composerRepository, + BitDepthRepository bitDepthRepository, + BitRateRepository bitRateRepository, + SamplingRateRepository samplingRateRepository) { + this.repository = repository; + this.discRepository = discRepository; + this.composerRepository = composerRepository; + this.bitDepthRepository = bitDepthRepository; + this.bitRateRepository = bitRateRepository; + this.samplingRateRepository = samplingRateRepository; + } + + public Track createTrack(Integer trackNumber, String title, Integer duration, + String filepath, Integer discId, Integer composerId, + Integer bitDepthId, Integer bitRateId, Integer samplingRateId) { + logger.debug("Creating track with title: {}", title); + + if (trackNumber == null) { + throw new IllegalArgumentException("Track number cannot be null"); + } + if (title == null || title.isEmpty()) { + throw new IllegalArgumentException("Title cannot be null or empty"); + } + if (filepath == null || filepath.isEmpty()) { + throw new IllegalArgumentException("Filepath cannot be null or empty"); + } + if (discId == null) { + throw new IllegalArgumentException("Disc ID cannot be null"); + } + + Track track = new Track(); + track.setTrackNumber(trackNumber); + track.setTitle(title); + track.setDuration(duration); + track.setFilepath(filepath); + + // Set Disc (required) + Optional disc = discRepository.findById(discId); + if (disc.isEmpty()) { + throw new IllegalArgumentException("Disc not found with id: " + discId); + } + track.setDisc(disc.get()); + + // Set Composer (optional) + if (composerId != null) { + Optional composer = composerRepository.findById(composerId); + if (composer.isEmpty()) { + throw new IllegalArgumentException("Composer not found with id: " + composerId); + } + track.setComposer(composer.get()); + } + + // Set BitDepth (optional) + if (bitDepthId != null) { + Optional bitDepth = bitDepthRepository.findById(bitDepthId); + if (bitDepth.isEmpty()) { + throw new IllegalArgumentException("BitDepth not found with id: " + bitDepthId); + } + track.setBitDepth(bitDepth.get()); + } + + // Set BitRate (optional) + if (bitRateId != null) { + Optional bitRate = bitRateRepository.findById(bitRateId); + if (bitRate.isEmpty()) { + throw new IllegalArgumentException("BitRate not found with id: " + bitRateId); + } + track.setBitRate(bitRate.get()); + } + + // Set SamplingRate (optional) + if (samplingRateId != null) { + Optional samplingRate = samplingRateRepository.findById(samplingRateId); + if (samplingRate.isEmpty()) { + throw new IllegalArgumentException("SamplingRate not found with id: " + samplingRateId); + } + track.setSamplingRate(samplingRate.get()); + } + + return repository.save(track); + } + + public List getAllTracks() { + logger.info("Getting all tracks"); + return repository.findAll(); + } + + public Optional getTrackById(Integer id) { + if (id == null) { + throw new IllegalArgumentException("ID cannot be null"); + } + logger.info("Getting track by id: {}", id); + return repository.findById(id); + } + + public Optional updateTrack(Integer id, Integer trackNumber, String title, + Integer duration, String filepath, Integer discId, + Integer composerId, Integer bitDepthId, + Integer bitRateId, Integer samplingRateId) { + if (id == null) { + throw new IllegalArgumentException("ID cannot be null"); + } + if (trackNumber == null) { + throw new IllegalArgumentException("Track number cannot be null"); + } + if (title == null || title.isEmpty()) { + throw new IllegalArgumentException("Title cannot be null or empty"); + } + if (filepath == null || filepath.isEmpty()) { + throw new IllegalArgumentException("Filepath cannot be null or empty"); + } + if (discId == null) { + throw new IllegalArgumentException("Disc ID cannot be null"); + } + + logger.info("Updating track with id: {}", id); + + Optional existingTrack = repository.findById(id); + if (existingTrack.isEmpty()) { + logger.warn("Track not found with id: {}", id); + return Optional.empty(); + } + + Track track = existingTrack.get(); + track.setTrackNumber(trackNumber); + track.setTitle(title); + track.setDuration(duration); + track.setFilepath(filepath); + + // Update Disc (required) + Optional disc = discRepository.findById(discId); + if (disc.isEmpty()) { + throw new IllegalArgumentException("Disc not found with id: " + discId); + } + track.setDisc(disc.get()); + + // Update Composer (optional) + if (composerId != null) { + Optional composer = composerRepository.findById(composerId); + if (composer.isEmpty()) { + throw new IllegalArgumentException("Composer not found with id: " + composerId); + } + track.setComposer(composer.get()); + } else { + track.setComposer(null); + } + + // Update BitDepth (optional) + if (bitDepthId != null) { + Optional bitDepth = bitDepthRepository.findById(bitDepthId); + if (bitDepth.isEmpty()) { + throw new IllegalArgumentException("BitDepth not found with id: " + bitDepthId); + } + track.setBitDepth(bitDepth.get()); + } else { + track.setBitDepth(null); + } + + // Update BitRate (optional) + if (bitRateId != null) { + Optional bitRate = bitRateRepository.findById(bitRateId); + if (bitRate.isEmpty()) { + throw new IllegalArgumentException("BitRate not found with id: " + bitRateId); + } + track.setBitRate(bitRate.get()); + } else { + track.setBitRate(null); + } + + // Update SamplingRate (optional) + if (samplingRateId != null) { + Optional samplingRate = samplingRateRepository.findById(samplingRateId); + if (samplingRate.isEmpty()) { + throw new IllegalArgumentException("SamplingRate not found with id: " + samplingRateId); + } + track.setSamplingRate(samplingRate.get()); + } else { + track.setSamplingRate(null); + } + + Track updatedTrack = repository.update(track); + return Optional.of(updatedTrack); + } + + public boolean deleteTrack(Integer id) { + if (id == null) { + throw new IllegalArgumentException("Track id cannot be null"); + } + logger.info("Deleting track: {}", id); + return repository.deleteById(id); + } +} diff --git a/src/main/proto/track.proto b/src/main/proto/track.proto new file mode 100644 index 0000000..750562a --- /dev/null +++ b/src/main/proto/track.proto @@ -0,0 +1,81 @@ +syntax = "proto3"; + +import "google/protobuf/wrappers.proto"; + +option java_package = "com.mediamanager.protocol.messages"; +option java_outer_classname = "TrackMessages"; + +package mediamanager.messages; + +message Track{ + int32 id = 1; + int32 track_number = 2; + string title = 3; + int32 duration = 4; + string filepath = 5; + + int32 fk_disc_id = 6; + int32 fk_composer_id = 7; + int32 fk_bitdepth_id = 8; + int32 fk_bitrate_id = 9; + int32 fk_samplingrate_id = 10; +} + +message CreateTrackRequest { + int32 track_number = 1; + string title = 2; + google.protobuf.Int32Value duration = 3; + string filepath = 4; + + int32 fk_disc_id = 5; + google.protobuf.Int32Value fk_composer_id = 6; + google.protobuf.Int32Value fk_bitdepth_id = 7; + google.protobuf.Int32Value fk_bitrate_id = 8; + google.protobuf.Int32Value fk_samplingrate_id = 9; +} + +message CreateTrackResponse { + Track track = 1; +} + +message GetTracksRequest { +} + +message GetTracksResponse { + repeated Track tracks = 1; +} + +message GetTrackByIdRequest { + int32 id = 1; +} + +message GetTrackByIdResponse { + Track track = 1; +} + +message UpdateTrackRequest { + int32 id = 1; + google.protobuf.Int32Value track_number = 2; + string title = 3; + google.protobuf.Int32Value duration = 4; + string filepath = 5; + + google.protobuf.Int32Value fk_disc_id = 6; + google.protobuf.Int32Value fk_composer_id = 7; + google.protobuf.Int32Value fk_bitdepth_id = 8; + google.protobuf.Int32Value fk_bitrate_id = 9; + google.protobuf.Int32Value fk_samplingrate_id = 10; +} + +message UpdateTrackResponse { + Track track = 1; +} + +message DeleteTrackRequest { + int32 id = 1; +} + +message DeleteTrackResponse { + bool success = 1; + string message = 2; +} \ No newline at end of file