Compare commits

..
Author SHA1 Message Date
Gustavo Henrique Santos Souza de Miranda fd71114426 Fix extra closing brace in CreateDiscHandler
Remove duplicate closing brace at end of CreateDiscHandler.java
  that was causing a syntax error.
2025-12-08 20:55:45 -03:00
Gustavo Henrique Miranda 2e0a39a455 Merge pull request #26 from gmbrax/develop
Develop
2025-12-08 20:51:38 -03:00
Gustavo Henrique Miranda eebe142b8c Merge branch 'feature/Implement-track-management' into develop 2025-12-08 20:51:21 -03:00
Gustavo Henrique Miranda 4073c53b3d Merge pull request #25 from gmbrax/feature/Implement-disc-management
Implement Disc entity with complete CRUD operations
2025-12-08 20:49:08 -03:00
Gustavo Henrique Santos Souza de Miranda 8208b58b34 Implement Track entity with complete CRUD operations
Add full Track implementation following the established pattern from Disc and Album entities.

  Components added:
  - Track entity model with relationships to Disc, Composer, BitDepth, BitRate, and SamplingRate
  - TrackRepository for data access layer with full CRUD operations
  - TrackService with business logic and validation
  - TrackMapper for protobuf/entity conversion
  - track.proto with all protobuf message definitions
  - Five action handlers: Create, GetAll, GetById, Update, Delete
  - TrackService registration in DelegateActionManager

  The Track entity supports:
  - Required fields: trackNumber, title, filepath, discId
  - Optional fields: duration, composerId, bitDepthId, bitRateId, samplingRateId
  - Full transaction management and error handling
  - Proper validation and logging throughout all layers
2025-12-08 20:43:08 -03:00
12 changed files with 936 additions and 1 deletions
@@ -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;
}
}
@@ -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;
}
}
@@ -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<Track> 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<Track> 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();
}
}
}
@@ -12,8 +12,10 @@ import com.mediamanager.service.albumtype.AlbumTypeService;
import com.mediamanager.service.bitdepth.BitDepthService; import com.mediamanager.service.bitdepth.BitDepthService;
import com.mediamanager.service.bitrate.BitRateService; import com.mediamanager.service.bitrate.BitRateService;
import com.mediamanager.service.composer.ComposerService; import com.mediamanager.service.composer.ComposerService;
import com.mediamanager.repository.GenreRepository; import com.mediamanager.repository.GenreRepository;
import com.mediamanager.service.artist.ArtistService; import com.mediamanager.service.artist.ArtistService;
import com.mediamanager.service.track.TrackService;
import com.mediamanager.service.delegate.annotation.Action; import com.mediamanager.service.delegate.annotation.Action;
import com.mediamanager.service.disc.DiscService; import com.mediamanager.service.disc.DiscService;
@@ -106,6 +108,10 @@ public class DelegateActionManager {
DiscService discService = new DiscService(discRepository, albumRepository); DiscService discService = new DiscService(discRepository, albumRepository);
serviceLocator.register(DiscService.class, discService); 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(); serviceLocator.logRegisteredServices();
logger.info("Services initialized successfully"); logger.info("Services initialized successfully");
@@ -58,4 +58,4 @@ public class CreateDiscHandler implements ActionHandler {
} }
} }
} }
}
@@ -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()));
}
}
}
@@ -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());
}
}
}
@@ -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<Track> 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()));
}
}
}
@@ -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<Track> 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()));
}
}
}
@@ -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<Track> 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()));
}
}
}
@@ -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> 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> 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> 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> 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> 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<Track> getAllTracks() {
logger.info("Getting all tracks");
return repository.findAll();
}
public Optional<Track> 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<Track> 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<Track> 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> 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> 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> 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> 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> 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);
}
}
+81
View File
@@ -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;
}