diff --git a/.gitignore b/.gitignore
index 5074d96..db764ec 100644
--- a/.gitignore
+++ b/.gitignore
@@ -39,8 +39,18 @@ build/
.DS_Store
### Application Specific ###
-application-local.properties
+config-local.properties
*.db
pipes/
*.log
/.idea/
+
+ Configuration files with sensitive credentials
+# These files contain database passwords and API keys and should never be committed
+src/main/resources/config.properties
+src/main/resources/application.properties
+
+# Allow example configuration files to be committed
+!src/main/resources/*.properties.example
+src/scripts/*
+local-repo/
\ No newline at end of file
diff --git a/README.md b/README.md
index baf75eb..56207a1 100644
--- a/README.md
+++ b/README.md
@@ -34,7 +34,7 @@ MediaManager-Core/
│ │ ├── util/ # Utility classes
│ │ └── MediaManagerApplication.java
│ └── resources/
-│ ├── application.properties # App configuration
+│ ├── config.properties # App configuration
│ ├── log4j2.xml # Logging configuration
│ └── META-INF/
│ └── persistence.xml # JPA configuration
@@ -55,7 +55,7 @@ GRANT ALL PRIVILEGES ON DATABASE mediamanager TO mediamanager;
### 2. Configuration
-Edit `src/main/resources/application.properties` and update the database credentials:
+Edit `src/main/resources/config.properties` and update the database credentials:
```properties
db.url=jdbc:postgresql://localhost:5432/mediamanager
@@ -90,7 +90,7 @@ The application creates named pipes for inter-process communication. Default con
- Pipe name: `mediamanager-pipe`
- Buffer size: 8192 bytes
-You can modify these settings in `application.properties`.
+You can modify these settings in `config.properties`.
## Logging
@@ -116,8 +116,8 @@ mvn test
## Dependencies
-- PostgreSQL Driver: 42.7.3
-- Hibernate ORM: 6.4.4.Final
+- PostgreSQL Driver: 42.7.5
+- Hibernate ORM: 7.1.7.Final
- HikariCP: 5.1.0
- Log4j 2: 2.23.1
- Jackson: 2.16.1
diff --git a/pom.xml b/pom.xml
index 9a87f4d..8846994 100644
--- a/pom.xml
+++ b/pom.xml
@@ -13,7 +13,7 @@
17
UTF-8
7.1.7.Final
- 42.7.5
+ 42.7.7
5.1.0
2.23.1
5.10.2
@@ -35,6 +35,12 @@
${hibernate.version}
+
+ org.hibernate.orm
+ hibernate-community-dialects
+ ${hibernate.version}
+
+
com.zaxxer
@@ -55,7 +61,7 @@
org.apache.logging.log4j
- log4j-slf4j2-impl
+ log4j-slf4j-impl
${log4j.version}
@@ -78,9 +84,32 @@
${junit.version}
test
+
+ com.google.protobuf
+ protobuf-java
+ 4.32.0
+
+
+ org.xerial
+ sqlite-jdbc
+ 3.44.1.0
+
+
+ org.reflections
+ reflections
+ 0.10.2
+
+
+
+ kr.motd.maven
+ os-maven-plugin
+ 1.7.1
+
+
+
org.apache.maven.plugins
@@ -91,11 +120,75 @@
17
+
org.apache.maven.plugins
maven-surefire-plugin
3.2.5
+
+
+
+ org.xolstice.maven.plugins
+ protobuf-maven-plugin
+ 0.6.1
+
+ /usr/bin/protoc
+ ${project.basedir}/src/main/proto
+ ${project.build.directory}/generated-sources/protobuf/java
+ false
+
+
+
+
+ compile
+
+
+
+
+
+
+
+ org.codehaus.mojo
+ build-helper-maven-plugin
+ 3.5.0
+
+
+ add-source
+ generate-sources
+
+ add-source
+
+
+
+ ${project.build.directory}/generated-sources/protobuf/java
+
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-shade-plugin
+ 3.5.1
+
+
+ package
+
+ shade
+
+
+
+
+ com.mediamanager.MediaManagerApplication
+
+
+
+
+
+
diff --git a/src/main/java/com/mediamanager/MediaManagerApplication.java b/src/main/java/com/mediamanager/MediaManagerApplication.java
index d3030da..22834fb 100644
--- a/src/main/java/com/mediamanager/MediaManagerApplication.java
+++ b/src/main/java/com/mediamanager/MediaManagerApplication.java
@@ -1,5 +1,8 @@
package com.mediamanager;
+import com.mediamanager.service.database.DatabaseManager;
+import com.mediamanager.service.delegate.DelegateActionManager;
+import com.mediamanager.service.ipc.IPCManager;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@@ -7,9 +10,25 @@ import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
+import com.mediamanager.service.database.SqliteDatabaseManager;
+
public class MediaManagerApplication {
private static final Logger logger = LogManager.getLogger(MediaManagerApplication.class);
private static Properties config;
+ private static DatabaseManager databaseManager;
+ private static DelegateActionManager actionManager;
+ private static IPCManager ipcManager;
+
+ public enum ApplicationMode {
+ LOCAL("local"),
+ SERVER("server");
+
+ private final String value;
+
+ ApplicationMode(String value) {
+ this.value = value;
+ }
+ }
public static void main(String[] args) {
logger.info("Starting MediaManager Core Application...");
@@ -17,19 +36,85 @@ public class MediaManagerApplication {
try {
// Load configuration
loadConfiguration();
+ String runTypeString = config.getProperty("runtype","local");
+ ApplicationMode mode = null;
+
+ for (ApplicationMode am : ApplicationMode.values()) {
+ if (am.value.equalsIgnoreCase(runTypeString)) {
+ mode = am;
+ break;
+ }
+ }
+ if (mode == null) {
+ logger.error("Invalid run type: {}", runTypeString);
+ throw new Exception("Invalid run type: " + runTypeString);
+ }
+ logger.info("Run type: {}", mode);
+ switch (mode) {
+ case LOCAL:
+ logger.info("Starting local database...");
+ databaseManager = new SqliteDatabaseManager(config);
+ break;
+ case SERVER:
+ throw new Exception("Server mode not yet implemented");
+ default:
+ }
+ databaseManager.init();
+ actionManager = new DelegateActionManager(databaseManager.getEntityManagerFactory());
+ actionManager.start();
+ ipcManager = new IPCManager(config,actionManager);
+ ipcManager.init();
- // TODO: Initialize database connection
- // TODO: Initialize IPC server with named pipes
// TODO: Start application services
logger.info("MediaManager Core started successfully");
- logger.info("IPC Pipe: {}", config.getProperty("ipc.pipe.path") + "/" + config.getProperty("ipc.pipe.name"));
+ logger.info("IPC Socket: {}", ipcManager.getSocketPath().toAbsolutePath().toString());
// Keep application running
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
+
logger.info("Shutting down MediaManager Core...");
- // TODO: Cleanup resources
+
+
+ if (databaseManager != null) {
+ databaseManager.close();
+ }
+
+ if (ipcManager != null) {
+ try {
+ ipcManager.close();
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ if (actionManager != null) {
+ actionManager.stop();
+ }
+
+ logger.info("MediaManager Core shutdown successfully");
+ logger.info("Goodbye!");
+
+
+ // Give Log4j2 time to write all pending messages before shutting down
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ }
+
+ // Now shutdown Log4j2
+ org.apache.logging.log4j.LogManager.shutdown();
}));
+ logger.info("Application is running");
+ logger.info("Press Ctrl+C to exit");
+ Thread.currentThread().join();
+
+ } catch (InterruptedException e) {
+
+ logger.info("Application interrupted, initiating shutdown...");
+
+ Thread.currentThread().interrupt();
} catch (Exception e) {
logger.error("Failed to start MediaManager Core", e);
@@ -39,10 +124,9 @@ public class MediaManagerApplication {
private static void loadConfiguration() throws IOException {
config = new Properties();
- try (InputStream input = MediaManagerApplication.class.getClassLoader()
- .getResourceAsStream("application.properties")) {
+ try (InputStream input = MediaManagerApplication.class.getClassLoader().getResourceAsStream("config.properties")) {
if (input == null) {
- throw new IOException("Unable to find application.properties");
+ throw new IOException("Unable to find config.properties");
}
config.load(input);
logger.info("Configuration loaded successfully");
@@ -52,4 +136,4 @@ public class MediaManagerApplication {
public static Properties getConfig() {
return config;
}
-}
+}
\ No newline at end of file
diff --git a/src/main/java/com/mediamanager/mapper/AlbumArtMapper.java b/src/main/java/com/mediamanager/mapper/AlbumArtMapper.java
new file mode 100644
index 0000000..1bdf834
--- /dev/null
+++ b/src/main/java/com/mediamanager/mapper/AlbumArtMapper.java
@@ -0,0 +1,35 @@
+package com.mediamanager.mapper;
+
+import com.mediamanager.model.AlbumArt;
+import com.mediamanager.protocol.messages.AlbumArtMessages;
+
+public class AlbumArtMapper {
+ public static AlbumArtMessages.AlbumArt toProtobuf(AlbumArt entity) {
+ if (entity == null) {
+ return null;
+ }
+ String filepath = entity.getFilepath();
+ if (filepath == null || filepath.isEmpty()) {
+ throw new IllegalArgumentException("Filepath cannot be null or empty");
+ }
+ AlbumArtMessages.AlbumArt.Builder builder = AlbumArtMessages.AlbumArt.newBuilder()
+ .setFilepath(filepath);
+ Integer id = entity.getId();
+ if (id != null) {
+ builder.setId(id);
+ }
+ return builder.build();
+ }
+
+ public static AlbumArt toEntity(AlbumArtMessages.AlbumArt protobuf) {
+ if (protobuf == null) {
+ return null;
+ }
+ AlbumArt entity = new AlbumArt();
+ if (protobuf.getId() >0) {
+ entity.setId(protobuf.getId());
+ }
+ entity.setFilepath(protobuf.getFilepath());
+ return entity;
+ }
+}
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/mapper/AlbumHasGenreMapper.java b/src/main/java/com/mediamanager/mapper/AlbumHasGenreMapper.java
new file mode 100644
index 0000000..43c34f3
--- /dev/null
+++ b/src/main/java/com/mediamanager/mapper/AlbumHasGenreMapper.java
@@ -0,0 +1,47 @@
+package com.mediamanager.mapper;
+
+import com.mediamanager.model.AlbumHasGenre;
+import com.mediamanager.protocol.messages.AlbumHasGenreMessages;
+
+public class AlbumHasGenreMapper {
+ public static AlbumHasGenreMessages.AlbumHasGenre toProtobuf(AlbumHasGenre entity) {
+ if (entity == null) {
+ return null;
+ }
+
+ AlbumHasGenreMessages.AlbumHasGenre.Builder builder = AlbumHasGenreMessages.AlbumHasGenre.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 Genre foreign key
+ if (entity.getGenre() != null && entity.getGenre().getId() != null) {
+ builder.setFkGenreId(entity.getGenre().getId());
+ }
+
+ return builder.build();
+ }
+
+ public static AlbumHasGenre toEntity(AlbumHasGenreMessages.AlbumHasGenre protobuf) {
+ if (protobuf == null) {
+ return null;
+ }
+
+ AlbumHasGenre entity = new AlbumHasGenre();
+
+ if (protobuf.getId() > 0) {
+ entity.setId(protobuf.getId());
+ }
+
+ // Note: Foreign key relationships (Album, Genre) are handled in the service layer
+
+ return entity;
+ }
+}
diff --git a/src/main/java/com/mediamanager/mapper/AlbumMapper.java b/src/main/java/com/mediamanager/mapper/AlbumMapper.java
new file mode 100644
index 0000000..57ff6bd
--- /dev/null
+++ b/src/main/java/com/mediamanager/mapper/AlbumMapper.java
@@ -0,0 +1,110 @@
+package com.mediamanager.mapper;
+
+import com.mediamanager.model.Album;
+import com.mediamanager.protocol.messages.AlbumMessages;
+
+import java.time.Instant;
+import java.time.ZoneId;
+
+public class AlbumMapper {
+ public static AlbumMessages.Album toProtobuf(Album entity) {
+ if (entity == null) {
+ return null;
+ }
+
+ String name = entity.getName();
+ if (name == null || name.isEmpty()) {
+ throw new IllegalArgumentException("Name cannot be null or empty");
+ }
+
+ AlbumMessages.Album.Builder builder = AlbumMessages.Album.newBuilder()
+ .setName(name);
+
+ Integer id = entity.getId();
+ if (id != null) {
+ builder.setId(id);
+ }
+
+ Integer year = entity.getYear();
+ if (year != null) {
+ builder.setYear(year);
+ }
+
+ Integer numberOfDiscs = entity.getNumberOfDiscs();
+ if (numberOfDiscs != null) {
+ builder.setNumberOfDiscs(numberOfDiscs);
+ }
+
+ String code = entity.getCode();
+ if (code != null) {
+ builder.setCode(code);
+ }
+
+ Boolean isCompilation = entity.getIsCompilation();
+ if (isCompilation != null) {
+ builder.setIsCompilation(isCompilation);
+ }
+
+ // Map AlbumType foreign key
+ if (entity.getAlbumType() != null && entity.getAlbumType().getId() != null) {
+ builder.setFkAlbumtypeId(entity.getAlbumType().getId());
+ }
+
+ // Map AlbumArt foreign key
+ if (entity.getAlbumArt() != null && entity.getAlbumArt().getId() != null) {
+ builder.setFkAlbumartId(entity.getAlbumArt().getId());
+ }
+
+ // Map timestamps
+ if (entity.getCreatedAt() != null) {
+ long createdAtEpoch = entity.getCreatedAt()
+ .atZone(ZoneId.systemDefault())
+ .toInstant()
+ .toEpochMilli();
+ builder.setCreatedAt(createdAtEpoch);
+ }
+
+ if (entity.getUpdatedAt() != null) {
+ long updatedAtEpoch = entity.getUpdatedAt()
+ .atZone(ZoneId.systemDefault())
+ .toInstant()
+ .toEpochMilli();
+ builder.setUpdatedAt(updatedAtEpoch);
+ }
+
+ return builder.build();
+ }
+
+ public static Album toEntity(AlbumMessages.Album protobuf) {
+ if (protobuf == null) {
+ return null;
+ }
+
+ Album entity = new Album();
+
+ if (protobuf.getId() > 0) {
+ entity.setId(protobuf.getId());
+ }
+
+ entity.setName(protobuf.getName());
+
+ if (protobuf.getYear() > 0) {
+ entity.setYear(protobuf.getYear());
+ }
+
+ if (protobuf.getNumberOfDiscs() > 0) {
+ entity.setNumberOfDiscs(protobuf.getNumberOfDiscs());
+ }
+
+ if (!protobuf.getCode().isEmpty()) {
+ entity.setCode(protobuf.getCode());
+ }
+
+ entity.setIsCompilation(protobuf.getIsCompilation());
+
+ // Note: Foreign key relationships (AlbumType, AlbumArt) are handled in the service layer
+ // Timestamps are managed by JPA @PrePersist and @PreUpdate
+
+ return entity;
+ }
+}
diff --git a/src/main/java/com/mediamanager/mapper/AlbumTypeMapper.java b/src/main/java/com/mediamanager/mapper/AlbumTypeMapper.java
new file mode 100644
index 0000000..2bdfbe1
--- /dev/null
+++ b/src/main/java/com/mediamanager/mapper/AlbumTypeMapper.java
@@ -0,0 +1,35 @@
+package com.mediamanager.mapper;
+
+import com.mediamanager.model.AlbumType;
+import com.mediamanager.protocol.messages.AlbumTypeMessages;
+
+public class AlbumTypeMapper {
+ public static AlbumTypeMessages.AlbumType toProtobuf(AlbumType entity) {
+ if (entity == null) {
+ return null;
+ }
+ String value = entity.getValue();
+ if (value == null || value.isEmpty()) {
+ throw new IllegalArgumentException("Value cannot be null or empty");
+ }
+ AlbumTypeMessages.AlbumType.Builder builder = AlbumTypeMessages.AlbumType.newBuilder()
+ .setValue(value);
+ Integer id = entity.getId();
+ if (id != null) {
+ builder.setId(id);
+ }
+ return builder.build();
+ }
+
+ public static AlbumType toEntity(AlbumTypeMessages.AlbumType protobuf) {
+ if (protobuf == null) {
+ return null;
+ }
+ AlbumType entity = new AlbumType();
+ if (protobuf.getId() >0) {
+ entity.setId(protobuf.getId());
+ }
+ entity.setValue(protobuf.getValue());
+ return entity;
+ }
+}
diff --git a/src/main/java/com/mediamanager/mapper/ArtistMapper.java b/src/main/java/com/mediamanager/mapper/ArtistMapper.java
new file mode 100644
index 0000000..29f2ce9
--- /dev/null
+++ b/src/main/java/com/mediamanager/mapper/ArtistMapper.java
@@ -0,0 +1,41 @@
+package com.mediamanager.mapper;
+
+import com.mediamanager.model.Artist;
+import com.mediamanager.protocol.messages.ArtistMessages;
+
+
+public class ArtistMapper {
+ public static ArtistMessages.Artist toProtobuf(Artist entity){
+ if (entity == null) {
+ return null;
+ }
+
+ String name = entity.getName();
+ if (name == null) {
+ throw new IllegalArgumentException("Artist name cannot be null");
+ }
+
+ ArtistMessages.Artist.Builder builder = ArtistMessages.Artist.newBuilder()
+ .setName(name);
+
+ // Only set ID when it's present and valid (> 0). Avoids NPE for null IDs.
+ Integer id = entity.getId();
+ if (id != null && id > 0) {
+ builder.setId(id);
+ }
+
+ return builder.build();
+ }
+ public static Artist toEntity(ArtistMessages.Artist protobuf) {
+ if (protobuf == null) {
+ return null;
+ }
+ Artist entity = new Artist();
+
+ if (protobuf.getId() > 0) {
+ entity.setId(protobuf.getId());
+ }
+ entity.setName(protobuf.getName());
+ return entity;
+ }
+}
diff --git a/src/main/java/com/mediamanager/mapper/BitDepthMapper.java b/src/main/java/com/mediamanager/mapper/BitDepthMapper.java
new file mode 100644
index 0000000..873629c
--- /dev/null
+++ b/src/main/java/com/mediamanager/mapper/BitDepthMapper.java
@@ -0,0 +1,39 @@
+package com.mediamanager.mapper;
+
+import com.mediamanager.model.BitDepth;
+import com.mediamanager.protocol.messages.BitDepthMessages;
+
+public class BitDepthMapper {
+ public static BitDepthMessages.BitDepth toProtobuf(BitDepth entity) {
+ if (entity == null){
+ return null;
+ }
+
+ String value = entity.getValue();
+ if (value == null) {
+ throw new IllegalArgumentException("Bit depth value cannot be null");
+ }
+ BitDepthMessages.BitDepth.Builder builder = BitDepthMessages.BitDepth.newBuilder()
+ .setValue(value);
+
+ Integer id = entity.getId();
+ if (id != null && id > 0) {
+ builder.setId(id);
+ }
+
+ return builder.build();
+ }
+
+ public static BitDepth toEntity(BitDepthMessages.BitDepth protobuf) {
+ if (protobuf == null) {
+ return null;
+ }
+ BitDepth entity = new BitDepth();
+
+ if (protobuf.getId() > 0) {
+ entity.setId(protobuf.getId());
+ }
+ entity.setValue(protobuf.getValue());
+ return entity;
+ }
+}
diff --git a/src/main/java/com/mediamanager/mapper/BitRateMapper.java b/src/main/java/com/mediamanager/mapper/BitRateMapper.java
new file mode 100644
index 0000000..b6e5c5c
--- /dev/null
+++ b/src/main/java/com/mediamanager/mapper/BitRateMapper.java
@@ -0,0 +1,39 @@
+package com.mediamanager.mapper;
+
+import com.mediamanager.model.BitRate;
+import com.mediamanager.protocol.messages.BitRateMessages;
+
+public class BitRateMapper {
+ public static BitRateMessages.BitRate toProtobuf(BitRate entity) {
+ if (entity == null) {
+ return null;
+ }
+
+ String value = entity.getValue();
+ if (value == null) {
+ throw new IllegalArgumentException("Bit rate value cannot be null");
+ }
+
+ BitRateMessages.BitRate.Builder builder = BitRateMessages.BitRate.newBuilder()
+ .setValue(value);
+
+ Integer id = entity.getId();
+ if (id != null && id > 0) {
+ builder.setId(id);
+ }
+ return builder.build();
+ }
+
+ public static BitRate toEntity(BitRateMessages.BitRate protobuf) {
+ if (protobuf == null) {
+ return null;
+ }
+ BitRate entity = new BitRate();
+
+ if (protobuf.getId() > 0) {
+ entity.setId(protobuf.getId());
+ }
+ entity.setValue(protobuf.getValue());
+ return entity;
+ }
+}
diff --git a/src/main/java/com/mediamanager/mapper/ComposerMapper.java b/src/main/java/com/mediamanager/mapper/ComposerMapper.java
new file mode 100644
index 0000000..cf783b5
--- /dev/null
+++ b/src/main/java/com/mediamanager/mapper/ComposerMapper.java
@@ -0,0 +1,38 @@
+package com.mediamanager.mapper;
+
+import com.mediamanager.model.Composer;
+import com.mediamanager.protocol.messages.ComposerMessages;
+
+public class ComposerMapper {
+ public static ComposerMessages.Composer toProtobuf(Composer entity) {
+ if (entity == null) {
+ return null;
+ }
+ ComposerMessages.Composer.Builder builder = ComposerMessages.Composer.newBuilder()
+ .setName(entity.getName());
+
+ Integer id = entity.getId();
+ if (id != null && id > 0) {
+ builder.setId(id);
+ }
+
+ return builder.build();
+
+ }
+
+ public static Composer toEntity(ComposerMessages.Composer protobuf) {
+ if (protobuf == null) {
+ return null;
+ }
+
+ Composer entity = new Composer();
+
+ if (protobuf.getId() > 0) {
+ entity.setId(protobuf.getId());
+ }
+
+ entity.setName(protobuf.getName());
+
+ return entity;
+ }
+}
diff --git a/src/main/java/com/mediamanager/mapper/GenreMapper.java b/src/main/java/com/mediamanager/mapper/GenreMapper.java
new file mode 100644
index 0000000..331e67c
--- /dev/null
+++ b/src/main/java/com/mediamanager/mapper/GenreMapper.java
@@ -0,0 +1,40 @@
+package com.mediamanager.mapper;
+
+import com.mediamanager.model.Genre;
+import com.mediamanager.protocol.messages.GenreMessages;
+
+public class GenreMapper {
+ public static GenreMessages.Genre toProtobuf(Genre entity) {
+ if (entity == null) {
+ return null;
+ }
+
+ GenreMessages.Genre.Builder builder = GenreMessages.Genre.newBuilder()
+ .setName(entity.getName());
+
+ // Only set ID when it's present and valid (> 0). Avoids NPE for null IDs.
+ Integer id = entity.getId();
+ if (id != null && id > 0) {
+ builder.setId(id);
+ }
+
+ return builder.build();
+ }
+ public static Genre toEntity(GenreMessages.Genre protobuf) {
+ if (protobuf == null) {
+ return null;
+ }
+
+ Genre entity = new Genre();
+
+ // Só seta ID se for > 0 (protobuf default é 0)
+ if (protobuf.getId() > 0) {
+ entity.setId(protobuf.getId());
+ }
+
+ entity.setName(protobuf.getName());
+
+ return entity;
+ }
+}
+
diff --git a/src/main/java/com/mediamanager/mapper/SamplingRateMapper.java b/src/main/java/com/mediamanager/mapper/SamplingRateMapper.java
new file mode 100644
index 0000000..d1701cd
--- /dev/null
+++ b/src/main/java/com/mediamanager/mapper/SamplingRateMapper.java
@@ -0,0 +1,35 @@
+package com.mediamanager.mapper;
+
+import com.mediamanager.model.SamplingRate;
+import com.mediamanager.protocol.messages.SamplingRateMessages;
+
+public class SamplingRateMapper {
+ public static SamplingRateMessages.SamplingRate toProtobuf(SamplingRate entity) {
+ if (entity == null) {
+ return null;
+ }
+ String value = entity.getValue();
+ if (value == null || value.isEmpty()) {
+ throw new IllegalArgumentException("Value cannot be null or empty");
+ }
+ SamplingRateMessages.SamplingRate.Builder builder = SamplingRateMessages.SamplingRate.newBuilder()
+ .setValue(value);
+ Integer id = entity.getId();
+ if (id != null) {
+ builder.setId(id);
+ }
+ return builder.build();
+ }
+
+ public static SamplingRate toEntity(SamplingRateMessages.SamplingRate protobuf) {
+ if (protobuf == null) {
+ return null;
+ }
+ SamplingRate entity = new SamplingRate();
+ if (protobuf.getId() >0) {
+ entity.setId(protobuf.getId());
+ }
+ entity.setValue(protobuf.getValue());
+ return entity;
+ }
+}
diff --git a/src/main/java/com/mediamanager/model/Album.java b/src/main/java/com/mediamanager/model/Album.java
new file mode 100644
index 0000000..ca4bab5
--- /dev/null
+++ b/src/main/java/com/mediamanager/model/Album.java
@@ -0,0 +1,229 @@
+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")
+public class Album {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Integer id;
+
+ @Column(nullable = false)
+ private String name;
+
+ @Column
+ private Integer year;
+
+ @Column(name = "number_of_discs")
+ private Integer numberOfDiscs;
+
+ @Column
+ private String code;
+
+ @Column(name = "is_compilation")
+ private Boolean isCompilation;
+
+ @ManyToOne(fetch = FetchType.LAZY)
+ @JoinColumn(name = "fk_albumtype_id")
+ private AlbumType albumType;
+
+ @ManyToOne(fetch = FetchType.LAZY)
+ @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<>();
+
+ // Relacionamento ManyToMany com Genre através da tabela de junção
+ @OneToMany(mappedBy = "album", cascade = CascadeType.ALL, orphanRemoval = true)
+ private List albumGenres = new ArrayList<>(); // ← ADICIONE ESSA LINHA
+
+ @Column(name = "created_at", nullable = false, updatable = false)
+ private LocalDateTime createdAt;
+
+ @Column(name = "updated_at")
+ private LocalDateTime updatedAt;
+
+ @PrePersist
+ protected void onCreate() {
+ this.createdAt = LocalDateTime.now();
+ this.updatedAt = LocalDateTime.now();
+ }
+
+ @PreUpdate
+ protected void onUpdate() {
+ this.updatedAt = LocalDateTime.now();
+ }
+
+ 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() != 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());
+ }
+
+ // ========== ADICIONE ESSES MÉTODOS PARA GENRE ==========
+
+ // Métodos helper para Genre (ManyToMany)
+ public void addGenre(Genre genre) {
+ AlbumHasGenre albumHasGenre = new AlbumHasGenre();
+ albumHasGenre.setAlbum(this);
+ albumHasGenre.setGenre(genre);
+ albumGenres.add(albumHasGenre);
+ }
+
+ public void removeGenre(Genre genre) {
+ if (genre == null) {
+ return;
+ }
+ albumGenres.removeIf(ag ->
+ ag.getGenre() != null &&
+ ag.getGenre().getId() != null &&
+ ag.getGenre().getId().equals(genre.getId())
+ );
+ }
+
+ // Método conveniente para pegar só os gêneros
+ public List getGenres() {
+ return albumGenres.stream()
+ .map(AlbumHasGenre::getGenre)
+ .collect(Collectors.toList());
+ }
+
+ // ========== FIM DOS MÉTODOS DE GENRE ==========
+
+ // Getters and Setters
+ public Integer getId() {
+ return id;
+ }
+
+ public void setId(Integer id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public Integer getYear() {
+ return year;
+ }
+
+ public void setYear(Integer year) {
+ this.year = year;
+ }
+
+ public Integer getNumberOfDiscs() {
+ return numberOfDiscs;
+ }
+
+ public void setNumberOfDiscs(Integer numberOfDiscs) {
+ this.numberOfDiscs = numberOfDiscs;
+ }
+
+ public String getCode() {
+ return code;
+ }
+
+ public void setCode(String code) {
+ this.code = code;
+ }
+
+ public Boolean getIsCompilation() {
+ return isCompilation;
+ }
+
+ public void setIsCompilation(Boolean isCompilation) {
+ this.isCompilation = isCompilation;
+ }
+
+ public AlbumType getAlbumType() {
+ return albumType;
+ }
+
+ public void setAlbumType(AlbumType albumType) {
+ this.albumType = albumType;
+ }
+
+ public AlbumArt getAlbumArt() {
+ return albumArt;
+ }
+
+ public void setAlbumArt(AlbumArt albumArt) {
+ this.albumArt = albumArt;
+ }
+
+ public List getAlbumArtists() {
+ return albumArtists;
+ }
+
+ public void setAlbumArtists(List albumArtists) {
+ this.albumArtists = albumArtists;
+ }
+
+ // ========== ADICIONE ESSES GETTERS/SETTERS ==========
+
+ public List getAlbumGenres() {
+ return albumGenres;
+ }
+
+ public void setAlbumGenres(List albumGenres) {
+ this.albumGenres = albumGenres;
+ }
+
+ // ========== FIM DOS GETTERS/SETTERS DE GENRE ==========
+
+ public LocalDateTime getCreatedAt() {
+ return createdAt;
+ }
+
+ public void setCreatedAt(LocalDateTime createdAt) {
+ this.createdAt = createdAt;
+ }
+
+ public LocalDateTime getUpdatedAt() {
+ return updatedAt;
+ }
+
+ public void setUpdatedAt(LocalDateTime updatedAt) {
+ this.updatedAt = updatedAt;
+ }
+
+ @Override
+ public String toString() {
+ return "Album{" +
+ "id=" + id +
+ ", name='" + name + '\'' +
+ ", year=" + year +
+ '}';
+ }
+}
diff --git a/src/main/java/com/mediamanager/model/AlbumArt.java b/src/main/java/com/mediamanager/model/AlbumArt.java
new file mode 100644
index 0000000..10bc72a
--- /dev/null
+++ b/src/main/java/com/mediamanager/model/AlbumArt.java
@@ -0,0 +1,33 @@
+package com.mediamanager.model;
+
+
+import jakarta.persistence.*;
+
+@Entity
+@Table(name = "albumArt")
+public class AlbumArt {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Integer id;
+
+ @Column(nullable = false)
+ private String filepath;
+
+
+ public Integer getId() {
+ return id;
+ }
+
+ public void setId(Integer id) {
+ this.id = id;
+ }
+
+ public String getFilepath() {
+ return filepath;
+ }
+
+ public void setFilepath(String filepath) {
+ this.filepath = filepath;
+ }
+}
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/model/AlbumHasGenre.java b/src/main/java/com/mediamanager/model/AlbumHasGenre.java
new file mode 100644
index 0000000..c380a89
--- /dev/null
+++ b/src/main/java/com/mediamanager/model/AlbumHasGenre.java
@@ -0,0 +1,56 @@
+package com.mediamanager.model;
+
+import jakarta.persistence.*;
+
+@Entity
+@Table(name = "albumshasgenre")
+public class AlbumHasGenre {
+
+ @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_genre_id", nullable = false)
+ private Genre genre;
+
+ public AlbumHasGenre() {}
+
+ // 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 Genre getGenre() {
+ return genre;
+ }
+
+ public void setGenre(Genre genre) {
+ this.genre = genre;
+ }
+
+ @Override
+ public String toString() {
+ return "AlbumHasGenre{" +
+ "id=" + id +
+ ", albumId=" + (album != null ? album.getId() : null) +
+ ", genreId=" + (genre != null ? genre.getId() : null) +
+ '}';
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/mediamanager/model/AlbumType.java b/src/main/java/com/mediamanager/model/AlbumType.java
new file mode 100644
index 0000000..ac5fad7
--- /dev/null
+++ b/src/main/java/com/mediamanager/model/AlbumType.java
@@ -0,0 +1,31 @@
+package com.mediamanager.model;
+
+import jakarta.persistence.*;
+
+@Entity
+@Table(name = "albumtype")
+public class AlbumType {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Integer id;
+
+ @Column(nullable = false)
+ private String value;
+
+ public Integer getId() {
+ return id;
+ }
+
+ public void setId(Integer id) {
+ this.id = id;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ public void setValue(String value) {
+ this.value = value;
+ }
+}
diff --git a/src/main/java/com/mediamanager/model/Artist.java b/src/main/java/com/mediamanager/model/Artist.java
new file mode 100644
index 0000000..22fe490
--- /dev/null
+++ b/src/main/java/com/mediamanager/model/Artist.java
@@ -0,0 +1,27 @@
+package com.mediamanager.model;
+
+import jakarta.persistence.*;
+
+@Entity
+@Table(name = "artist")
+public class Artist {
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Integer id;
+
+ @Column(nullable = false)
+ private String name;
+
+ public Integer getId() {
+ return id;
+ }
+ public void setId(Integer id) {
+ this.id = id;
+ }
+ public String getName() {
+ return name;
+ }
+ public void setName(String name) {
+ this.name = name;
+ }
+}
diff --git a/src/main/java/com/mediamanager/model/BitDepth.java b/src/main/java/com/mediamanager/model/BitDepth.java
new file mode 100644
index 0000000..3b80217
--- /dev/null
+++ b/src/main/java/com/mediamanager/model/BitDepth.java
@@ -0,0 +1,32 @@
+package com.mediamanager.model;
+
+import jakarta.persistence.*;
+
+@Entity
+@Table(name = "bit_depth")
+public class BitDepth {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Integer id;
+
+ @Column(nullable = false)
+ private String value;
+
+ public Integer getId() {
+ return id;
+ }
+
+ public void setId(Integer id) {
+ this.id = id;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ public void setValue(String value) {
+ this.value = value;
+ }
+}
+
diff --git a/src/main/java/com/mediamanager/model/BitRate.java b/src/main/java/com/mediamanager/model/BitRate.java
new file mode 100644
index 0000000..c3f6fa2
--- /dev/null
+++ b/src/main/java/com/mediamanager/model/BitRate.java
@@ -0,0 +1,31 @@
+package com.mediamanager.model;
+
+import jakarta.persistence.*;
+
+@Entity
+@Table(name = "bit_rate")
+public class BitRate {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Integer id;
+
+ @Column(nullable = false)
+ private String value;
+
+ public Integer getId() {
+ return id;
+ }
+
+ public void setId(Integer id) {
+ this.id = id;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ public void setValue(String value) {
+ this.value = value;
+ }
+}
diff --git a/src/main/java/com/mediamanager/model/Composer.java b/src/main/java/com/mediamanager/model/Composer.java
new file mode 100644
index 0000000..965bf6f
--- /dev/null
+++ b/src/main/java/com/mediamanager/model/Composer.java
@@ -0,0 +1,31 @@
+package com.mediamanager.model;
+
+
+import jakarta.persistence.*;
+
+@Entity
+@Table(name = "composer")
+public class Composer {
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Integer id;
+
+ @Column(nullable = false)
+ private String name;
+
+ public Integer getId() {
+ return id;
+ }
+
+ public void setId(Integer id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+}
diff --git a/src/main/java/com/mediamanager/model/Genre.java b/src/main/java/com/mediamanager/model/Genre.java
new file mode 100644
index 0000000..b2a736b
--- /dev/null
+++ b/src/main/java/com/mediamanager/model/Genre.java
@@ -0,0 +1,30 @@
+package com.mediamanager.model;
+
+import jakarta.persistence.*;
+
+@Entity
+@Table(name = "genre")
+public class Genre {
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Integer id;
+
+ @Column(nullable = false)
+ private String name;
+
+ public Integer getId() {
+ return id;
+ }
+
+ public void setId(Integer id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+}
diff --git a/src/main/java/com/mediamanager/model/Media.java b/src/main/java/com/mediamanager/model/Media.java
deleted file mode 100644
index 99a455d..0000000
--- a/src/main/java/com/mediamanager/model/Media.java
+++ /dev/null
@@ -1,128 +0,0 @@
-package com.mediamanager.model;
-
-import jakarta.persistence.*;
-import java.time.LocalDateTime;
-
-@Entity
-@Table(name = "media")
-public class Media {
-
- @Id
- @GeneratedValue(strategy = GenerationType.IDENTITY)
- private Long id;
-
- @Column(nullable = false)
- private String title;
-
- @Column(nullable = false, unique = true)
- private String filePath;
-
- @Enumerated(EnumType.STRING)
- @Column(nullable = false)
- private MediaType type;
-
- @Column
- private Long fileSize;
-
- @Column
- private String mimeType;
-
- @Column(name = "created_at", nullable = false, updatable = false)
- private LocalDateTime createdAt;
-
- @Column(name = "updated_at")
- private LocalDateTime updatedAt;
-
- @PrePersist
- protected void onCreate() {
- createdAt = LocalDateTime.now();
- updatedAt = LocalDateTime.now();
- }
-
- @PreUpdate
- protected void onUpdate() {
- updatedAt = LocalDateTime.now();
- }
-
- // Constructors
- public Media() {}
-
- public Media(String title, String filePath, MediaType type) {
- this.title = title;
- this.filePath = filePath;
- this.type = type;
- }
-
- // Getters and Setters
- public Long getId() {
- return id;
- }
-
- public void setId(Long id) {
- this.id = id;
- }
-
- public String getTitle() {
- return title;
- }
-
- public void setTitle(String title) {
- this.title = title;
- }
-
- public String getFilePath() {
- return filePath;
- }
-
- public void setFilePath(String filePath) {
- this.filePath = filePath;
- }
-
- public MediaType getType() {
- return type;
- }
-
- public void setType(MediaType type) {
- this.type = type;
- }
-
- public Long getFileSize() {
- return fileSize;
- }
-
- public void setFileSize(Long fileSize) {
- this.fileSize = fileSize;
- }
-
- public String getMimeType() {
- return mimeType;
- }
-
- public void setMimeType(String mimeType) {
- this.mimeType = mimeType;
- }
-
- public LocalDateTime getCreatedAt() {
- return createdAt;
- }
-
- public void setCreatedAt(LocalDateTime createdAt) {
- this.createdAt = createdAt;
- }
-
- public LocalDateTime getUpdatedAt() {
- return updatedAt;
- }
-
- public void setUpdatedAt(LocalDateTime updatedAt) {
- this.updatedAt = updatedAt;
- }
-
- public enum MediaType {
- VIDEO,
- AUDIO,
- IMAGE,
- DOCUMENT,
- OTHER
- }
-}
diff --git a/src/main/java/com/mediamanager/model/SamplingRate.java b/src/main/java/com/mediamanager/model/SamplingRate.java
new file mode 100644
index 0000000..e090226
--- /dev/null
+++ b/src/main/java/com/mediamanager/model/SamplingRate.java
@@ -0,0 +1,30 @@
+package com.mediamanager.model;
+
+import jakarta.persistence.*;
+
+@Entity
+@Table(name = "sampling_rate")
+public class SamplingRate {
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Integer id;
+
+ @Column(nullable = false)
+ private String value;
+
+ public Integer getId() {
+ return id;
+ }
+
+ public void setId(Integer id) {
+ this.id = id;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ public void setValue(String value) {
+ this.value = value;
+ }
+}
diff --git a/src/main/java/com/mediamanager/repository/AlbumArtRepository.java b/src/main/java/com/mediamanager/repository/AlbumArtRepository.java
new file mode 100644
index 0000000..cb5034c
--- /dev/null
+++ b/src/main/java/com/mediamanager/repository/AlbumArtRepository.java
@@ -0,0 +1,103 @@
+package com.mediamanager.repository;
+
+
+import com.mediamanager.model.AlbumArt;
+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 AlbumArtRepository {
+ private static final Logger logger = LogManager.getLogger(AlbumArtRepository.class);
+
+ private final EntityManagerFactory entityManagerFactory;
+
+ public AlbumArtRepository(EntityManagerFactory entityManagerFactory) {
+ this.entityManagerFactory = entityManagerFactory;
+ }
+
+ public AlbumArt save(AlbumArt albumArt) {
+ logger.debug("Saving AlbumArt: {}", albumArt.getFilepath());
+ EntityManager em = entityManagerFactory.createEntityManager();
+ em.getTransaction().begin();
+ try {
+ em.persist(albumArt);
+ em.getTransaction().commit();
+ logger.debug("AlbumArt has been saved successfully");
+ return albumArt;
+ } catch (Exception e) {
+ em.getTransaction().rollback();
+ logger.error("Error while saving AlbumArt: {}", e.getMessage());
+ throw e;
+ } finally {
+ if (em.isOpen()) em.close();
+ }
+ }
+
+ public List findAll() {
+ logger.debug("Finding All AlbumArt");
+ EntityManager em = entityManagerFactory.createEntityManager();
+ try{
+ return em.createQuery("select a from AlbumArt a", AlbumArt.class).getResultList();
+ }finally {
+ if (em.isOpen()) em.close();
+ }
+ }
+
+ public Optional findById(Integer id) {
+ logger.debug("Finding AlbumArt with id: {}", id);
+ EntityManager em = entityManagerFactory.createEntityManager();
+ try{
+ AlbumArt albumArt = em.find(AlbumArt.class, id);
+ return Optional.ofNullable(albumArt);
+ }finally {
+ if (em.isOpen()) em.close();
+ }
+ }
+
+ public AlbumArt update(AlbumArt albumArt) {
+ logger.debug("Updating AlbumArt: {}", albumArt.getFilepath());
+ EntityManager em = entityManagerFactory.createEntityManager();
+ em.getTransaction().begin();
+ try {
+ AlbumArt updated = em.merge(albumArt);
+ em.getTransaction().commit();
+ logger.debug("AlbumArt has been updated successfully");
+ return updated;
+ } catch (Exception e) {
+ em.getTransaction().rollback();
+ logger.error("Error while updating AlbumArt: {}", e.getMessage());
+ throw e;
+ } finally {
+ if (em.isOpen()) em.close();
+ }
+ }
+
+ public boolean deleteById(Integer id){
+ logger.debug("Deleting AlbumArt with id: {}", id);
+ EntityManager em = entityManagerFactory.createEntityManager();
+ em.getTransaction().begin();
+ try{
+ AlbumArt albumArt = em.find(AlbumArt.class, id);
+ if (albumArt == null) {
+ em.getTransaction().rollback();
+ return false;
+ }
+ em.remove(albumArt);
+ em.getTransaction().commit();
+ logger.debug("AlbumArt has been deleted successfully");
+ return true;
+ } catch (Exception e) {
+ em.getTransaction().rollback();
+ logger.error("Error while deleting AlbumArt: {}", e.getMessage());
+ throw e;
+ } finally {
+ if (em.isOpen()) em.close();
+ }
+ }
+
+}
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/repository/AlbumHasGenreRepository.java b/src/main/java/com/mediamanager/repository/AlbumHasGenreRepository.java
new file mode 100644
index 0000000..d842224
--- /dev/null
+++ b/src/main/java/com/mediamanager/repository/AlbumHasGenreRepository.java
@@ -0,0 +1,85 @@
+package com.mediamanager.repository;
+
+
+import com.mediamanager.model.AlbumHasGenre;
+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 AlbumHasGenreRepository {
+ private static final Logger logger = LogManager.getLogger(AlbumHasGenreRepository.class);
+
+ private final EntityManagerFactory entityManagerFactory;
+
+ public AlbumHasGenreRepository(EntityManagerFactory entityManagerFactory) {
+ this.entityManagerFactory = entityManagerFactory;
+ }
+
+ public AlbumHasGenre save(AlbumHasGenre albumHasGenre) {
+ logger.debug("Saving AlbumHasGenre: {}", albumHasGenre);
+ EntityManager em = entityManagerFactory.createEntityManager();
+ em.getTransaction().begin();
+ try {
+ em.persist(albumHasGenre);
+ em.getTransaction().commit();
+ logger.debug("AlbumHasGenre has been saved successfully");
+ return albumHasGenre;
+ } catch (Exception e) {
+ em.getTransaction().rollback();
+ logger.error("Error while saving AlbumHasGenre: {}", e.getMessage());
+ throw e;
+ } finally {
+ if (em.isOpen()) em.close();
+ }
+ }
+
+ public List findAll() {
+ logger.debug("Finding All AlbumHasGenre");
+ EntityManager em = entityManagerFactory.createEntityManager();
+ try{
+ return em.createQuery("select a from AlbumHasGenre a", AlbumHasGenre.class).getResultList();
+ }finally {
+ if (em.isOpen()) em.close();
+ }
+ }
+
+ public Optional findById(Integer id) {
+ logger.debug("Finding AlbumHasGenre with id: {}", id);
+ EntityManager em = entityManagerFactory.createEntityManager();
+ try{
+ AlbumHasGenre albumHasGenre = em.find(AlbumHasGenre.class, id);
+ return Optional.ofNullable(albumHasGenre);
+ }finally {
+ if (em.isOpen()) em.close();
+ }
+ }
+
+ public boolean deleteById(Integer id){
+ logger.debug("Deleting AlbumHasGenre with id: {}", id);
+ EntityManager em = entityManagerFactory.createEntityManager();
+ em.getTransaction().begin();
+ try{
+ AlbumHasGenre albumHasGenre = em.find(AlbumHasGenre.class, id);
+ if (albumHasGenre == null) {
+ em.getTransaction().rollback();
+ return false;
+ }
+ em.remove(albumHasGenre);
+ em.getTransaction().commit();
+ logger.debug("AlbumHasGenre has been deleted successfully");
+ return true;
+ } catch (Exception e) {
+ em.getTransaction().rollback();
+ logger.error("Error while deleting AlbumHasGenre: {}", e.getMessage());
+ throw e;
+ } finally {
+ if (em.isOpen()) em.close();
+ }
+ }
+
+}
diff --git a/src/main/java/com/mediamanager/repository/AlbumRepository.java b/src/main/java/com/mediamanager/repository/AlbumRepository.java
new file mode 100644
index 0000000..f744222
--- /dev/null
+++ b/src/main/java/com/mediamanager/repository/AlbumRepository.java
@@ -0,0 +1,103 @@
+package com.mediamanager.repository;
+
+
+import com.mediamanager.model.Album;
+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 AlbumRepository {
+ private static final Logger logger = LogManager.getLogger(AlbumRepository.class);
+
+ private final EntityManagerFactory entityManagerFactory;
+
+ public AlbumRepository(EntityManagerFactory entityManagerFactory) {
+ this.entityManagerFactory = entityManagerFactory;
+ }
+
+ public Album save(Album album) {
+ logger.debug("Saving Album: {}", album.getName());
+ EntityManager em = entityManagerFactory.createEntityManager();
+ em.getTransaction().begin();
+ try {
+ em.persist(album);
+ em.getTransaction().commit();
+ logger.debug("Album has been saved successfully");
+ return album;
+ } catch (Exception e) {
+ em.getTransaction().rollback();
+ logger.error("Error while saving Album: {}", e.getMessage());
+ throw e;
+ } finally {
+ if (em.isOpen()) em.close();
+ }
+ }
+
+ public List findAll() {
+ logger.debug("Finding All Album");
+ EntityManager em = entityManagerFactory.createEntityManager();
+ try{
+ return em.createQuery("select a from Album a", Album.class).getResultList();
+ }finally {
+ if (em.isOpen()) em.close();
+ }
+ }
+
+ public Optional findById(Integer id) {
+ logger.debug("Finding Album with id: {}", id);
+ EntityManager em = entityManagerFactory.createEntityManager();
+ try{
+ Album album = em.find(Album.class, id);
+ return Optional.ofNullable(album);
+ }finally {
+ if (em.isOpen()) em.close();
+ }
+ }
+
+ public Album update(Album album) {
+ logger.debug("Updating Album: {}", album.getName());
+ EntityManager em = entityManagerFactory.createEntityManager();
+ em.getTransaction().begin();
+ try {
+ Album updated = em.merge(album);
+ em.getTransaction().commit();
+ logger.debug("Album has been updated successfully");
+ return updated;
+ } catch (Exception e) {
+ em.getTransaction().rollback();
+ logger.error("Error while updating Album: {}", e.getMessage());
+ throw e;
+ } finally {
+ if (em.isOpen()) em.close();
+ }
+ }
+
+ public boolean deleteById(Integer id){
+ logger.debug("Deleting Album with id: {}", id);
+ EntityManager em = entityManagerFactory.createEntityManager();
+ em.getTransaction().begin();
+ try{
+ Album album = em.find(Album.class, id);
+ if (album == null) {
+ em.getTransaction().rollback();
+ return false;
+ }
+ em.remove(album);
+ em.getTransaction().commit();
+ logger.debug("Album has been deleted successfully");
+ return true;
+ } catch (Exception e) {
+ em.getTransaction().rollback();
+ logger.error("Error while deleting Album: {}", e.getMessage());
+ throw e;
+ } finally {
+ if (em.isOpen()) em.close();
+ }
+ }
+
+}
diff --git a/src/main/java/com/mediamanager/repository/AlbumTypeRepository.java b/src/main/java/com/mediamanager/repository/AlbumTypeRepository.java
new file mode 100644
index 0000000..f359e38
--- /dev/null
+++ b/src/main/java/com/mediamanager/repository/AlbumTypeRepository.java
@@ -0,0 +1,103 @@
+package com.mediamanager.repository;
+
+
+import com.mediamanager.model.AlbumType;
+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 AlbumTypeRepository {
+ private static final Logger logger = LogManager.getLogger(AlbumTypeRepository.class);
+
+ private final EntityManagerFactory entityManagerFactory;
+
+ public AlbumTypeRepository(EntityManagerFactory entityManagerFactory) {
+ this.entityManagerFactory = entityManagerFactory;
+ }
+
+ public AlbumType save(AlbumType albumType) {
+ logger.debug("Saving AlbumType: {}", albumType.getValue());
+ EntityManager em = entityManagerFactory.createEntityManager();
+ em.getTransaction().begin();
+ try {
+ em.persist(albumType);
+ em.getTransaction().commit();
+ logger.debug("AlbumType has been saved successfully");
+ return albumType;
+ } catch (Exception e) {
+ em.getTransaction().rollback();
+ logger.error("Error while saving AlbumType: {}", e.getMessage());
+ throw e;
+ } finally {
+ if (em.isOpen()) em.close();
+ }
+ }
+
+ public List findAll() {
+ logger.debug("Finding All AlbumType");
+ EntityManager em = entityManagerFactory.createEntityManager();
+ try{
+ return em.createQuery("select a from AlbumType a", AlbumType.class).getResultList();
+ }finally {
+ if (em.isOpen()) em.close();
+ }
+ }
+
+ public Optional findById(Integer id) {
+ logger.debug("Finding AlbumType with id: {}", id);
+ EntityManager em = entityManagerFactory.createEntityManager();
+ try{
+ AlbumType albumType = em.find(AlbumType.class, id);
+ return Optional.ofNullable(albumType);
+ }finally {
+ if (em.isOpen()) em.close();
+ }
+ }
+
+ public AlbumType update(AlbumType albumType) {
+ logger.debug("Updating AlbumType: {}", albumType.getValue());
+ EntityManager em = entityManagerFactory.createEntityManager();
+ em.getTransaction().begin();
+ try {
+ AlbumType updated = em.merge(albumType);
+ em.getTransaction().commit();
+ logger.debug("AlbumType has been updated successfully");
+ return updated;
+ } catch (Exception e) {
+ em.getTransaction().rollback();
+ logger.error("Error while updating AlbumType: {}", e.getMessage());
+ throw e;
+ } finally {
+ if (em.isOpen()) em.close();
+ }
+ }
+
+ public boolean deleteById(Integer id){
+ logger.debug("Deleting AlbumType with id: {}", id);
+ EntityManager em = entityManagerFactory.createEntityManager();
+ em.getTransaction().begin();
+ try{
+ AlbumType albumType = em.find(AlbumType.class, id);
+ if (albumType == null) {
+ em.getTransaction().rollback();
+ return false;
+ }
+ em.remove(albumType);
+ em.getTransaction().commit();
+ logger.debug("AlbumType has been deleted successfully");
+ return true;
+ } catch (Exception e) {
+ em.getTransaction().rollback();
+ logger.error("Error while deleting AlbumType: {}", e.getMessage());
+ throw e;
+ } finally {
+ if (em.isOpen()) em.close();
+ }
+ }
+
+}
diff --git a/src/main/java/com/mediamanager/repository/ArtistRepository.java b/src/main/java/com/mediamanager/repository/ArtistRepository.java
new file mode 100644
index 0000000..60d0b9d
--- /dev/null
+++ b/src/main/java/com/mediamanager/repository/ArtistRepository.java
@@ -0,0 +1,104 @@
+package com.mediamanager.repository;
+import com.mediamanager.model.Artist;
+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 ArtistRepository {
+ private static final Logger logger = LogManager.getLogger(ArtistRepository.class);
+
+ private final EntityManagerFactory entityManagerFactory;
+
+ public ArtistRepository(EntityManagerFactory entityManagerFactory) {
+ this.entityManagerFactory = entityManagerFactory;
+ }
+
+ public Artist save(Artist artist){
+ logger.debug("Saving Artist: {}", artist.getName());
+ EntityManager em = entityManagerFactory.createEntityManager();
+ em.getTransaction().begin();
+ try {
+ em.persist(artist);
+ em.getTransaction().commit();
+ logger.debug("Artist saved with ID: {}", artist.getId());
+ return artist;
+ } catch (Exception e) {
+ em.getTransaction().rollback();
+ logger.error("Error saving Artist", e);
+ throw e;
+ } finally {
+ if (em.isOpen()) em.close();
+ }
+ }
+
+ public List findAll(){
+ logger.debug("Finding all Artists");
+ EntityManager em = entityManagerFactory.createEntityManager();
+ try {
+ return em
+ .createQuery("SELECT a FROM Artist a ORDER BY a.name", Artist.class)
+ .getResultList();
+ } finally {
+ if (em.isOpen()) em.close();
+ }
+ }
+
+ public Optional findById(Integer id){
+ logger.debug("Finding artist by ID: {}", id);
+ EntityManager em = entityManagerFactory.createEntityManager();
+ try {
+ Artist artist = em.find(Artist.class, id);
+ return Optional.ofNullable(artist);
+ } finally {
+ if (em.isOpen()) em.close();
+ }
+
+ }
+
+ public Artist update(Artist artist){
+ logger.debug("Updating artist ID: {}", artist.getId());
+ EntityManager em = entityManagerFactory.createEntityManager();
+ em.getTransaction().begin();
+ try {
+ Artist updated = em.merge(artist);
+ em.getTransaction().commit();
+ logger.debug("Artist updated successfully");
+ return updated;
+ } catch (Exception e) {
+ em.getTransaction().rollback();
+ logger.error("Error updating artist", e);
+ throw e;
+ } finally {
+ if (em.isOpen()) em.close();
+ }
+ }
+
+ public boolean deleteById(Integer id){
+ logger.debug("Deleting Artist by ID: {}", id);
+ EntityManager em = entityManagerFactory.createEntityManager();
+ em.getTransaction().begin();
+ try {
+ Artist artist = em.find(Artist.class, id);
+ if (artist == null) {
+ em.getTransaction().rollback();
+ return false;
+ }
+ em.remove(artist);
+ em.getTransaction().commit();
+ logger.debug("Artist deleted successfully");
+ return true;
+ } catch (Exception e) {
+ em.getTransaction().rollback();
+ logger.error("Error deleting artist", e);
+ throw e;
+ } finally {
+ if (em.isOpen()) em.close();
+ }
+ }
+ }
+
+
diff --git a/src/main/java/com/mediamanager/repository/BitDepthRepository.java b/src/main/java/com/mediamanager/repository/BitDepthRepository.java
new file mode 100644
index 0000000..24b9dc9
--- /dev/null
+++ b/src/main/java/com/mediamanager/repository/BitDepthRepository.java
@@ -0,0 +1,100 @@
+package com.mediamanager.repository;
+
+import com.mediamanager.model.BitDepth;
+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 BitDepthRepository {
+ private static final Logger logger = LogManager.getLogger(BitDepthRepository.class);
+
+ private final EntityManagerFactory entityManagerFactory;
+
+ public BitDepthRepository(EntityManagerFactory entityManagerFactory) {
+ this.entityManagerFactory = entityManagerFactory;
+ }
+
+ public BitDepth save(BitDepth bitDepth) {
+ logger.debug("Saving BitDepth: {}", bitDepth.getValue());
+ EntityManager em = entityManagerFactory.createEntityManager();
+ em.getTransaction().begin();
+ try {
+ em.persist(bitDepth);
+ em.getTransaction().commit();
+ logger.debug("BitDepth saved with ID: {}", bitDepth.getId());
+ return bitDepth;
+ } catch (Exception e) {
+ em.getTransaction().rollback();
+ logger.error("Error saving BitDepth", e);
+ throw e;
+ } finally {
+ if (em.isOpen()) em.close();
+ }
+ }
+
+ public List findAll(){
+ logger.debug("Finding all BitDepths");
+ EntityManager em = entityManagerFactory.createEntityManager();
+ try{
+ return em.createQuery("SELECT b FROM BitDepth b ORDER BY b.value", BitDepth.class).getResultList();
+ }finally {
+ if (em.isOpen()) em.close();
+ }
+ }
+
+ public Optional findById(Integer id){
+ logger.debug("Finding BitDepth by ID: {}", id);
+ EntityManager em = entityManagerFactory.createEntityManager();
+ try{
+ BitDepth bitDepth = em.find(BitDepth.class, id);
+ return Optional.ofNullable(bitDepth);
+ }finally {
+ if (em.isOpen()) em.close();
+ }
+ }
+
+ public BitDepth update(BitDepth bitDepth){
+ logger.debug("Updating BitDepth ID: {}", bitDepth.getId());
+ EntityManager em = entityManagerFactory.createEntityManager();
+ em.getTransaction().begin();
+ try{
+ BitDepth updated = em.merge(bitDepth);
+ em.getTransaction().commit();
+ logger.debug("BitDepth updated successfully");
+ return updated;
+ }catch (Exception e){
+ em.getTransaction().rollback();
+ logger.error("Error updating BitDepth", e);
+ throw e;
+ }finally {
+ if (em.isOpen()) em.close();
+ }
+ }
+
+ public boolean deleteById(Integer id){
+ logger.debug("Deleting BitDepth by ID: {}", id);
+ EntityManager em = entityManagerFactory.createEntityManager();
+ em.getTransaction().begin();
+ try{
+ BitDepth bitDepth = em.find(BitDepth.class, id);
+ if (bitDepth == null) {
+ em.getTransaction().rollback();
+ return false;
+ }
+ em.remove(bitDepth);
+ em.getTransaction().commit();
+ logger.debug("BitDepth deleted successfully");
+ return true;
+ } catch (Exception e) {
+ em.getTransaction().rollback();
+ logger.error("Error deleting BitDepth", e);
+ throw e;
+ }finally {
+ if (em.isOpen()) em.close();
+ }
+ }
+}
diff --git a/src/main/java/com/mediamanager/repository/BitRateRepository.java b/src/main/java/com/mediamanager/repository/BitRateRepository.java
new file mode 100644
index 0000000..42c5343
--- /dev/null
+++ b/src/main/java/com/mediamanager/repository/BitRateRepository.java
@@ -0,0 +1,101 @@
+package com.mediamanager.repository;
+
+import com.mediamanager.model.BitRate;
+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 BitRateRepository {
+ private static final Logger logger = LogManager.getLogger(BitRateRepository.class);
+
+ private final EntityManagerFactory entityManagerFactory;
+
+ public BitRateRepository(EntityManagerFactory entityManagerFactory) {
+ this.entityManagerFactory = entityManagerFactory;
+ }
+
+ public BitRate save(BitRate bitRate) {
+ logger.debug("Saving BitRate: {}", bitRate.getValue());
+ EntityManager em = entityManagerFactory.createEntityManager();
+ em.getTransaction().begin();
+ try {
+ em.persist(bitRate);
+ em.getTransaction().commit();
+ logger.debug("BitRate saved with ID: {}", bitRate.getId());
+ return bitRate;
+ } catch (Exception e) {
+ em.getTransaction().rollback();
+ logger.error("Error saving BitRate", e);
+ throw e;
+ } finally {
+ if (em.isOpen()) em.close();
+ }
+ }
+
+ public List findAll(){
+ logger.debug("Finding all BitRates");
+ EntityManager em = entityManagerFactory.createEntityManager();
+ try{
+ return em.createQuery("SELECT b FROM BitRate b ORDER BY b.value", BitRate.class).getResultList();
+ }finally {
+ if (em.isOpen()) em.close();
+ }
+ }
+
+ public Optional findById(Integer id){
+ logger.debug("Finding BitRate by ID: {}", id);
+ EntityManager em = entityManagerFactory.createEntityManager();
+ try{
+ BitRate bitRate = em.find(BitRate.class, id);
+ return Optional.ofNullable(bitRate);
+ } finally {
+ if (em.isOpen()) em.close();
+ }
+ }
+
+ public BitRate update(BitRate bitRate){
+ logger.debug("Updating BitRate ID: {}", bitRate.getId());
+ EntityManager em = entityManagerFactory.createEntityManager();
+ em.getTransaction().begin();
+ try{
+ BitRate updated = em.merge(bitRate);
+ em.getTransaction().commit();
+ logger.debug("BitRate updated with ID: {}", bitRate.getId());
+ return updated;
+ } catch (Exception e) {
+ em.getTransaction().rollback();
+ logger.error("Error updating BitRate", e);
+ throw e;
+ } finally {
+ if (em.isOpen()) em.close();
+ }
+ }
+
+ public boolean deleteById(Integer id){
+ logger.debug("Deleting BitRate by ID: {}", id);
+ EntityManager em = entityManagerFactory.createEntityManager();
+ em.getTransaction().begin();
+ try{
+ BitRate bitRate = em.find(BitRate.class, id);
+ if (bitRate == null) {
+ em.getTransaction().rollback();
+ return false;
+ }
+ em.remove(bitRate);
+ em.getTransaction().commit();
+ logger.debug("BitRate deleted successfully");
+ return true;
+ } catch (Exception e) {
+ em.getTransaction().rollback();
+ logger.error("Error deleting BitRate", e);
+ throw e;
+ } finally {
+ if (em.isOpen()) em.close();
+ }
+
+ }
+}
diff --git a/src/main/java/com/mediamanager/repository/ComposerRepository.java b/src/main/java/com/mediamanager/repository/ComposerRepository.java
new file mode 100644
index 0000000..6e1a2aa
--- /dev/null
+++ b/src/main/java/com/mediamanager/repository/ComposerRepository.java
@@ -0,0 +1,102 @@
+package com.mediamanager.repository;
+
+import com.mediamanager.model.Composer;
+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 ComposerRepository {
+ private static final Logger logger = LogManager.getLogger(ComposerRepository.class);
+
+ private final EntityManagerFactory entityManagerFactory;
+
+ public ComposerRepository(EntityManagerFactory entityManagerFactory) {
+ this.entityManagerFactory = entityManagerFactory;
+ }
+
+ public Composer save(Composer composer) {
+ logger.debug("Saving composer: {}", composer.getName());
+ EntityManager em = entityManagerFactory.createEntityManager();
+ em.getTransaction().begin();
+ try{
+ //ToDo: Add Id Validation
+ //ToDo: Add to all Repositories
+ em.persist(composer);
+ em.getTransaction().commit();
+ logger.debug("Composer saved with IS: {}", composer.getId());
+ return composer;
+ } catch (Exception e) {
+ em.getTransaction().rollback();
+ logger.error("Error saving composer", e);
+ throw e;
+ }finally {
+ if (em.isOpen()) em.close();
+ }
+ }
+
+ public List findAll(){
+ logger.debug("Finding all composers");
+ EntityManager em = entityManagerFactory.createEntityManager();
+ try{
+ return em.createQuery("SELECT c FROM Composer c ORDER BY c.name", Composer.class).getResultList();
+ } finally {
+ if (em.isOpen()) em.close();
+ }
+ }
+
+ public Optional findById(Integer id){
+ logger.debug("Finding composer by ID: {}", id);
+ EntityManager em = entityManagerFactory.createEntityManager();
+ try{
+ Composer composer = em.find(Composer.class, id);
+ return Optional.ofNullable(composer);
+ } finally {
+ if (em.isOpen()) em.close();
+ }
+ }
+
+ public Composer update(Composer composer){
+ logger.debug("Updating composer ID: {}", composer.getId());
+ EntityManager em = entityManagerFactory.createEntityManager();
+ em.getTransaction().begin();
+ try{
+ Composer updated = em.merge(composer);
+ em.getTransaction().commit();
+ logger.debug("Composer updated successfully");
+ return updated;
+ } catch (Exception e) {
+ em.getTransaction().rollback();
+ logger.error("Error updating composer", e);
+ throw e;
+ } finally {
+ if (em.isOpen()) em.close();
+ }
+ }
+
+ public boolean deleteById(Integer id){
+ logger.debug("Deleting composer by ID: {}", id);
+ EntityManager em = entityManagerFactory.createEntityManager();
+ em.getTransaction().begin();
+ try{
+ Composer composer = em.find(Composer.class, id);
+ if (composer == null) {
+ em.getTransaction().rollback();
+ return false;
+ }
+ em.remove(composer);
+ em.getTransaction().commit();
+ logger.debug("Composer deleted successfully");
+ return true;
+ } catch (Exception e) {
+ em.getTransaction().rollback();
+ logger.error("Error deleting composer", e);
+ throw e;
+ }finally {
+ if (em.isOpen()) em.close();
+ }
+ }
+}
diff --git a/src/main/java/com/mediamanager/repository/GenreRepository.java b/src/main/java/com/mediamanager/repository/GenreRepository.java
new file mode 100644
index 0000000..73e9be9
--- /dev/null
+++ b/src/main/java/com/mediamanager/repository/GenreRepository.java
@@ -0,0 +1,121 @@
+package com.mediamanager.repository;
+
+import com.mediamanager.model.Genre;
+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;
+
+/**
+ * Repository para acesso a dados de Genre
+ * Encapsula todas as operações de banco de dados
+ */
+public class GenreRepository {
+ private static final Logger logger = LogManager.getLogger(GenreRepository.class);
+
+ private final EntityManagerFactory entityManagerFactory;
+
+ public GenreRepository(EntityManagerFactory entityManagerFactory) {
+ this.entityManagerFactory = entityManagerFactory;
+ }
+
+ /**
+ * Salva um novo genre
+ */
+ public Genre save(Genre genre) {
+ logger.debug("Saving genre: {}", genre.getName());
+ EntityManager em = entityManagerFactory.createEntityManager();
+ em.getTransaction().begin();
+ try {
+ em.persist(genre);
+ em.getTransaction().commit();
+ logger.debug("Genre saved with ID: {}", genre.getId());
+ return genre;
+ } catch (Exception e) {
+ em.getTransaction().rollback();
+ logger.error("Error saving genre", e);
+ throw e;
+ } finally {
+ if (em.isOpen()) em.close();
+ }
+ }
+
+ /**
+ * Busca todos os genres
+ */
+ public List findAll() {
+ logger.debug("Finding all genres");
+ EntityManager em = entityManagerFactory.createEntityManager();
+ try {
+ return em
+ .createQuery("SELECT g FROM Genre g ORDER BY g.name", Genre.class)
+ .getResultList();
+ } finally {
+ if (em.isOpen()) em.close();
+ }
+ }
+
+ /**
+ * Busca genre por ID
+ */
+ public Optional findById(Integer id) {
+ logger.debug("Finding genre by ID: {}", id);
+ EntityManager em = entityManagerFactory.createEntityManager();
+ try {
+ Genre genre = em.find(Genre.class, id);
+ return Optional.ofNullable(genre);
+ } finally {
+ if (em.isOpen()) em.close();
+ }
+ }
+
+ /**
+ * Atualiza um genre existente
+ */
+ public Genre update(Genre genre) {
+ logger.debug("Updating genre ID: {}", genre.getId());
+ EntityManager em = entityManagerFactory.createEntityManager();
+ em.getTransaction().begin();
+ try {
+ Genre updated = em.merge(genre);
+ em.getTransaction().commit();
+ logger.debug("Genre updated successfully");
+ return updated;
+ } catch (Exception e) {
+ em.getTransaction().rollback();
+ logger.error("Error updating genre", e);
+ throw e;
+ } finally {
+ if (em.isOpen()) em.close();
+ }
+ }
+
+ /**
+ * Deleta um genre por ID
+ */
+ public boolean deleteById(Integer id) {
+ logger.debug("Deleting genre by ID: {}", id);
+ EntityManager em = entityManagerFactory.createEntityManager();
+ em.getTransaction().begin();
+ try {
+ Genre genre = em.find(Genre.class, id);
+ if (genre == null) {
+ em.getTransaction().rollback();
+ return false;
+ }
+ em.remove(genre);
+ em.getTransaction().commit();
+ logger.debug("Genre deleted successfully");
+ return true;
+ } catch (Exception e) {
+ em.getTransaction().rollback();
+ logger.error("Error deleting genre", e);
+ throw e;
+ } finally {
+ if (em.isOpen()) em.close();
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/mediamanager/repository/SamplingRateRepository.java b/src/main/java/com/mediamanager/repository/SamplingRateRepository.java
new file mode 100644
index 0000000..4d2fd82
--- /dev/null
+++ b/src/main/java/com/mediamanager/repository/SamplingRateRepository.java
@@ -0,0 +1,103 @@
+package com.mediamanager.repository;
+
+
+import com.mediamanager.model.SamplingRate;
+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 SamplingRateRepository {
+ private static final Logger logger = LogManager.getLogger(SamplingRateRepository.class);
+
+ private final EntityManagerFactory entityManagerFactory;
+
+ public SamplingRateRepository(EntityManagerFactory entityManagerFactory) {
+ this.entityManagerFactory = entityManagerFactory;
+ }
+
+ public SamplingRate save(SamplingRate samplingRate) {
+ logger.debug("Saving SamplingRate: {}", samplingRate.getValue());
+ EntityManager em = entityManagerFactory.createEntityManager();
+ em.getTransaction().begin();
+ try {
+ em.persist(samplingRate);
+ em.getTransaction().commit();
+ logger.debug("SamplingRate has been saved successfully");
+ return samplingRate;
+ } catch (Exception e) {
+ em.getTransaction().rollback();
+ logger.error("Error while saving SamplingRate: {}", e.getMessage());
+ throw e;
+ } finally {
+ if (em.isOpen()) em.close();
+ }
+ }
+
+ public List findAll() {
+ logger.debug("Finding All SamplingRate");
+ EntityManager em = entityManagerFactory.createEntityManager();
+ try{
+ return em.createQuery("select s from SamplingRate s", SamplingRate.class).getResultList();
+ }finally {
+ if (em.isOpen()) em.close();
+ }
+ }
+
+ public Optional findById(Integer id) {
+ logger.debug("Finding SamplingRate with id: {}", id);
+ EntityManager em = entityManagerFactory.createEntityManager();
+ try{
+ SamplingRate samplingRate = em.find(SamplingRate.class, id);
+ return Optional.ofNullable(samplingRate);
+ }finally {
+ if (em.isOpen()) em.close();
+ }
+ }
+
+ public SamplingRate update(SamplingRate samplingRate) {
+ logger.debug("Updating SamplingRate: {}", samplingRate.getValue());
+ EntityManager em = entityManagerFactory.createEntityManager();
+ em.getTransaction().begin();
+ try {
+ SamplingRate updated = em.merge(samplingRate);
+ em.getTransaction().commit();
+ logger.debug("SamplingRate has been updated successfully");
+ return updated;
+ } catch (Exception e) {
+ em.getTransaction().rollback();
+ logger.error("Error while updating SamplingRate: {}", e.getMessage());
+ throw e;
+ } finally {
+ if (em.isOpen()) em.close();
+ }
+ }
+
+ public boolean deleteById(Integer id){
+ logger.debug("Deleting SamplingRate with id: {}", id);
+ EntityManager em = entityManagerFactory.createEntityManager();
+ em.getTransaction().begin();
+ try{
+ SamplingRate samplingRate = em.find(SamplingRate.class, id);
+ if (samplingRate == null) {
+ em.getTransaction().rollback();
+ return false;
+ }
+ em.remove(samplingRate);
+ em.getTransaction().commit();
+ logger.debug("SamplingRate has been deleted successfully");
+ return true;
+ } catch (Exception e) {
+ em.getTransaction().rollback();
+ logger.error("Error while deleting SamplingRate: {}", e.getMessage());
+ throw e;
+ } finally {
+ if (em.isOpen()) em.close();
+ }
+ }
+
+}
diff --git a/src/main/java/com/mediamanager/service/album/AlbumService.java b/src/main/java/com/mediamanager/service/album/AlbumService.java
new file mode 100644
index 0000000..bf41a46
--- /dev/null
+++ b/src/main/java/com/mediamanager/service/album/AlbumService.java
@@ -0,0 +1,153 @@
+package com.mediamanager.service.album;
+
+import com.mediamanager.model.Album;
+import com.mediamanager.model.AlbumArt;
+import com.mediamanager.model.AlbumType;
+import com.mediamanager.repository.AlbumRepository;
+import com.mediamanager.repository.AlbumArtRepository;
+import com.mediamanager.repository.AlbumTypeRepository;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import java.util.List;
+import java.util.Optional;
+
+public class AlbumService {
+ private static final Logger logger = LogManager.getLogger(AlbumService.class);
+ private final AlbumRepository repository;
+ private final AlbumTypeRepository albumTypeRepository;
+ private final AlbumArtRepository albumArtRepository;
+
+ public AlbumService(AlbumRepository repository, AlbumTypeRepository albumTypeRepository, AlbumArtRepository albumArtRepository) {
+ this.repository = repository;
+ this.albumTypeRepository = albumTypeRepository;
+ this.albumArtRepository = albumArtRepository;
+ }
+
+ public Album createAlbum(String name, Integer year, Integer numberOfDiscs, String code, Boolean isCompilation, Integer albumTypeId, Integer albumArtId) {
+ logger.debug("Creating album:{}", name);
+ if (name == null || name.trim().isEmpty()) {
+ throw new IllegalArgumentException("Album name cannot be null or empty");
+ }
+
+ Album album = new Album();
+ album.setName(name);
+ album.setYear(year);
+ album.setNumberOfDiscs(numberOfDiscs);
+ album.setCode(code);
+ album.setIsCompilation(isCompilation);
+
+ // Set 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());
+ }
+
+ // Set 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());
+ }
+
+ return repository.save(album);
+ }
+
+ public List getAllAlbums() {
+ logger.info("Getting all albums");
+ return repository.findAll();
+ }
+
+ public Optional getAlbumById(Integer id) {
+ if (id == null) {
+ throw new IllegalArgumentException("ID cannot be null");
+ }
+ logger.info("Getting album by id:{}", id);
+ return repository.findById(id);
+ }
+
+ 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);
+ 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);
+ return Optional.empty();
+ }
+
+ Album album = existingAlbum.get();
+ album.setName(name);
+ album.setCode(code);
+ album.setIsCompilation(isCompilation);
+
+ // Atualiza year SOMENTE se o campo foi fornecido
+ if (updateYear) {
+ album.setYear(year);
+ }
+
+ // 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);
+ }
+
+ public boolean deleteAlbum(Integer id) {
+ if (id == null) {
+ throw new IllegalArgumentException("Album id cannot be null");
+ }
+ logger.info("Deleting album:{}", id);
+ return repository.deleteById(id);
+ }
+
+}
diff --git a/src/main/java/com/mediamanager/service/albumart/AlbumArtService.java b/src/main/java/com/mediamanager/service/albumart/AlbumArtService.java
new file mode 100644
index 0000000..6ef9a27
--- /dev/null
+++ b/src/main/java/com/mediamanager/service/albumart/AlbumArtService.java
@@ -0,0 +1,69 @@
+package com.mediamanager.service.albumart;
+
+import com.mediamanager.model.AlbumArt;
+import com.mediamanager.repository.AlbumArtRepository;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import java.util.List;
+import java.util.Optional;
+
+public class AlbumArtService {
+ private static final Logger logger = LogManager.getLogger(AlbumArtService.class);
+ private final AlbumArtRepository repository;
+
+ public AlbumArtService(AlbumArtRepository repository) {
+ this.repository = repository;
+ }
+
+ public AlbumArt createAlbumArt(String filepath) {
+ logger.debug("Creating album art:{}", filepath);
+ if (filepath == null || filepath.trim().isEmpty()) {
+ throw new IllegalArgumentException("AlbumArt filepath cannot be null or empty");
+ }
+ AlbumArt albumArt = new AlbumArt();
+ albumArt.setFilepath(filepath);
+ return repository.save(albumArt);
+ }
+
+ public List getAllAlbumArts() {
+ logger.info("Getting all album arts");
+ return repository.findAll();
+ }
+
+ public Optional getAlbumArtById(Integer id) {
+ if (id == null) {
+ throw new IllegalArgumentException("ID cannot be null");
+ }
+ logger.info("Getting album art by id:{}", id);
+ return repository.findById(id);
+ }
+
+ public Optional updateAlbumArt(Integer id, String filepath) {
+ if (id == null) {
+ throw new IllegalArgumentException("ID cannot be null");
+ }
+ logger.info("Updating album art:{}", filepath);
+ if (filepath == null || filepath.trim().isEmpty()) {
+ throw new IllegalArgumentException("AlbumArt filepath cannot be null or empty");
+ }
+ Optional existingAlbumArt = repository.findById(id);
+ if(existingAlbumArt.isEmpty()) {
+ logger.warn("Album art not found with id:{}", id);
+ return Optional.empty();
+ }
+ AlbumArt albumArt = existingAlbumArt.get();
+ albumArt.setFilepath(filepath);
+ AlbumArt updatedAlbumArt = repository.update(albumArt);
+ return Optional.of(updatedAlbumArt);
+ }
+
+ public boolean deleteAlbumArt(Integer id) {
+ if (id == null) {
+ throw new IllegalArgumentException("Album art id cannot be null");
+ }
+ logger.info("Deleting album art:{}", id);
+ return repository.deleteById(id);
+ }
+
+}
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/albumhasgenre/AlbumHasGenreService.java b/src/main/java/com/mediamanager/service/albumhasgenre/AlbumHasGenreService.java
new file mode 100644
index 0000000..d75c5e8
--- /dev/null
+++ b/src/main/java/com/mediamanager/service/albumhasgenre/AlbumHasGenreService.java
@@ -0,0 +1,77 @@
+package com.mediamanager.service.albumhasgenre;
+
+import com.mediamanager.model.Album;
+import com.mediamanager.model.AlbumHasGenre;
+import com.mediamanager.model.Genre;
+import com.mediamanager.repository.AlbumHasGenreRepository;
+import com.mediamanager.repository.AlbumRepository;
+import com.mediamanager.repository.GenreRepository;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import java.util.List;
+import java.util.Optional;
+
+public class AlbumHasGenreService {
+ private static final Logger logger = LogManager.getLogger(AlbumHasGenreService.class);
+ private final AlbumHasGenreRepository repository;
+ private final AlbumRepository albumRepository;
+ private final GenreRepository genreRepository;
+
+ public AlbumHasGenreService(AlbumHasGenreRepository repository, AlbumRepository albumRepository, GenreRepository genreRepository) {
+ this.repository = repository;
+ this.albumRepository = albumRepository;
+ this.genreRepository = genreRepository;
+ }
+
+ public AlbumHasGenre createAlbumHasGenre(Integer albumId, Integer genreId) {
+ logger.debug("Creating album has genre relationship - albumId:{}, genreId:{}", albumId, genreId);
+
+ if (albumId == null || albumId <= 0) {
+ throw new IllegalArgumentException("Album ID cannot be null or invalid");
+ }
+ if (genreId == null || genreId <= 0) {
+ throw new IllegalArgumentException("Genre 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 Genre exists
+ Optional genre = genreRepository.findById(genreId);
+ if (genre.isEmpty()) {
+ throw new IllegalArgumentException("Genre not found with id: " + genreId);
+ }
+
+ AlbumHasGenre albumHasGenre = new AlbumHasGenre();
+ albumHasGenre.setAlbum(album.get());
+ albumHasGenre.setGenre(genre.get());
+
+ return repository.save(albumHasGenre);
+ }
+
+ public List getAllAlbumHasGenres() {
+ logger.info("Getting all album has genre relationships");
+ return repository.findAll();
+ }
+
+ public Optional getAlbumHasGenreById(Integer id) {
+ if (id == null) {
+ throw new IllegalArgumentException("ID cannot be null");
+ }
+ logger.info("Getting album has genre by id:{}", id);
+ return repository.findById(id);
+ }
+
+ public boolean deleteAlbumHasGenre(Integer id) {
+ if (id == null) {
+ throw new IllegalArgumentException("Album has genre id cannot be null");
+ }
+ logger.info("Deleting album has genre:{}", id);
+ return repository.deleteById(id);
+ }
+
+}
diff --git a/src/main/java/com/mediamanager/service/albumtype/AlbumTypeService.java b/src/main/java/com/mediamanager/service/albumtype/AlbumTypeService.java
new file mode 100644
index 0000000..3caf669
--- /dev/null
+++ b/src/main/java/com/mediamanager/service/albumtype/AlbumTypeService.java
@@ -0,0 +1,69 @@
+package com.mediamanager.service.albumtype;
+
+import com.mediamanager.model.AlbumType;
+import com.mediamanager.repository.AlbumTypeRepository;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import java.util.List;
+import java.util.Optional;
+
+public class AlbumTypeService {
+ private static final Logger logger = LogManager.getLogger(AlbumTypeService.class);
+ private final AlbumTypeRepository repository;
+
+ public AlbumTypeService(AlbumTypeRepository repository) {
+ this.repository = repository;
+ }
+
+ public AlbumType createAlbumType(String value) {
+ logger.debug("Creating album type:{}", value);
+ if (value == null || value.trim().isEmpty()) {
+ throw new IllegalArgumentException("AlbumType value cannot be null or empty");
+ }
+ AlbumType albumType = new AlbumType();
+ albumType.setValue(value);
+ return repository.save(albumType);
+ }
+
+ public List getAllAlbumTypes() {
+ logger.info("Getting all album types");
+ return repository.findAll();
+ }
+
+ public Optional getAlbumTypeById(Integer id) {
+ if (id == null) {
+ throw new IllegalArgumentException("ID cannot be null");
+ }
+ logger.info("Getting album type by id:{}", id);
+ return repository.findById(id);
+ }
+
+ public Optional updateAlbumType(Integer id, String value) {
+ if (id == null) {
+ throw new IllegalArgumentException("ID cannot be null");
+ }
+ logger.info("Updating album type:{}", value);
+ if (value == null || value.trim().isEmpty()) {
+ throw new IllegalArgumentException("AlbumType value cannot be null or empty");
+ }
+ Optional existingAlbumType = repository.findById(id);
+ if(existingAlbumType.isEmpty()) {
+ logger.warn("Album type not found with id:{}", id);
+ return Optional.empty();
+ }
+ AlbumType albumType = existingAlbumType.get();
+ albumType.setValue(value);
+ AlbumType updatedAlbumType = repository.update(albumType);
+ return Optional.of(updatedAlbumType);
+ }
+
+ public boolean deleteAlbumType(Integer id) {
+ if (id == null) {
+ throw new IllegalArgumentException("Album type id cannot be null");
+ }
+ logger.info("Deleting album type:{}", id);
+ return repository.deleteById(id);
+ }
+
+}
diff --git a/src/main/java/com/mediamanager/service/artist/ArtistService.java b/src/main/java/com/mediamanager/service/artist/ArtistService.java
new file mode 100644
index 0000000..4686030
--- /dev/null
+++ b/src/main/java/com/mediamanager/service/artist/ArtistService.java
@@ -0,0 +1,65 @@
+package com.mediamanager.service.artist;
+
+import com.mediamanager.model.Artist;
+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 ArtistService {
+ private static final Logger logger = LogManager.getLogger(ArtistService.class);
+ private final ArtistRepository artistRepository;
+
+ public ArtistService(ArtistRepository artistRepository) {
+ this.artistRepository = artistRepository;
+ }
+
+ public Artist createArtist(String name){
+ logger.info("Creating artist: {}", name);
+ if (name == null || name.trim().isEmpty()) {
+ throw new IllegalArgumentException("Artist name cannot be empty");
+ }
+ Artist artist = new Artist();
+ artist.setName(name.trim());
+ return artistRepository.save(artist);
+ }
+
+ public List getAllArtists(){
+ logger.info("Getting all artists");
+ return artistRepository.findAll();
+ }
+
+ public Optional getArtistById(Integer id){
+ logger.info("Getting artist by ID: {}", id);
+ return artistRepository.findById(id);
+ }
+
+ public Optional updateArtist(Integer id, String name){
+ logger.info("Updating artist ID {}: {}", id, name);
+
+ if (name == null || name.trim().isEmpty()) {
+ throw new IllegalArgumentException("Artist name cannot be empty");
+ }
+
+ Optional existingArtist = artistRepository.findById(id);
+
+ if(existingArtist.isEmpty()){
+ logger.warn("Artist not found with ID: {}", id);
+ return Optional.empty();
+ }
+ Artist artist = existingArtist.get();
+ artist.setName(name.trim());
+ Artist updatedArtist = artistRepository.update(artist);
+ return Optional.of(updatedArtist);
+ }
+
+ public boolean deleteArtist(Integer id){
+ logger.info("Deleting artist ID: {}", id);
+ return artistRepository.deleteById(id);
+ }
+
+
+
+}
diff --git a/src/main/java/com/mediamanager/service/bitdepth/BitDepthService.java b/src/main/java/com/mediamanager/service/bitdepth/BitDepthService.java
new file mode 100644
index 0000000..495e5d0
--- /dev/null
+++ b/src/main/java/com/mediamanager/service/bitdepth/BitDepthService.java
@@ -0,0 +1,61 @@
+package com.mediamanager.service.bitdepth;
+
+import com.mediamanager.model.BitDepth;
+import com.mediamanager.repository.BitDepthRepository;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import java.util.List;
+import java.util.Optional;
+
+public class BitDepthService {
+ private static final Logger logger = LogManager.getLogger(BitDepthService.class);
+ private final BitDepthRepository bitDepthRepository;
+
+ public BitDepthService(BitDepthRepository bitDepthRepository) {
+ this.bitDepthRepository = bitDepthRepository;
+ }
+ public BitDepth createBitDepth(String value){
+ logger.info("Creating bit-depth: {}", value);
+ if (value == null || value.trim().isEmpty()) {
+ throw new IllegalArgumentException("Bit-depth value cannot be empty");
+ }
+ BitDepth bitDepth = new BitDepth();
+ bitDepth.setValue(value.trim());
+ return bitDepthRepository.save(bitDepth);
+
+ }
+
+ public List getAllBitDepths(){
+ logger.info("Getting all bit-depths");
+ return bitDepthRepository.findAll();
+ }
+
+ public Optional getBitDepthById(Integer id){
+ logger.info("Getting bit-depth by ID: {}", id);
+ return bitDepthRepository.findById(id);
+ }
+
+ public Optional updateBitDepth(Integer id, String value){
+ logger.info("Updating bit-depth ID {}: {}", id, value);
+
+ if (value == null || value.trim().isEmpty()) {
+ throw new IllegalArgumentException("Bit-depth value cannot be empty");
+ }
+ Optional existingBitDepth = bitDepthRepository.findById(id);
+ if(existingBitDepth.isEmpty()){
+ logger.warn("Bit-depth not found with ID: {}", id);
+ return Optional.empty();
+ }
+ BitDepth bitDepth = existingBitDepth.get();
+ bitDepth.setValue(value.trim());
+ BitDepth updatedBitDepth = bitDepthRepository.update(bitDepth);
+ return Optional.of(updatedBitDepth);
+
+ }
+
+ public boolean deleteBitDepth(Integer id){
+ logger.info("Deleting bit-depth ID: {}", id);
+ return bitDepthRepository.deleteById(id);
+ }
+}
diff --git a/src/main/java/com/mediamanager/service/bitrate/BitRateService.java b/src/main/java/com/mediamanager/service/bitrate/BitRateService.java
new file mode 100644
index 0000000..57e32db
--- /dev/null
+++ b/src/main/java/com/mediamanager/service/bitrate/BitRateService.java
@@ -0,0 +1,65 @@
+package com.mediamanager.service.bitrate;
+
+
+import com.mediamanager.model.BitRate;
+import com.mediamanager.repository.BitRateRepository;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import java.util.List;
+import java.util.Optional;
+
+public class BitRateService {
+ private static final Logger logger = LogManager.getLogger(BitRateService.class);
+ private final BitRateRepository bitRateRepository;
+
+ public BitRateService(BitRateRepository bitRateRepository) {
+ this.bitRateRepository = bitRateRepository;
+ }
+
+ public BitRate createBitRate(String value){
+ logger.info("Creating bit-rate: {}",value);
+ if (value == null || value.trim().isEmpty()) {
+ throw new IllegalArgumentException("Bit-rate value cannot be empty");
+ }
+ BitRate bitRate = new BitRate();
+ bitRate.setValue(value.trim());
+ return bitRateRepository.save(bitRate);
+ }
+
+ public List getAllBitRates(){
+ logger.info("Getting all bit-rates");
+ return bitRateRepository.findAll();
+ }
+
+ public Optional getBitRateById(Integer id){
+ logger.info("Getting bit-rate by ID: {}", id);
+ return bitRateRepository.findById(id);
+ }
+
+ public Optional updateBitRate(Integer id, String value){
+ logger.info("Updating bit-rate ID {}: {}", id, value);
+
+ if (value == null || value.trim().isEmpty()) {
+ throw new IllegalArgumentException("Bit-rate value cannot be empty");
+ }
+
+ Optional existingBitRate = bitRateRepository.findById(id);
+
+ if(existingBitRate.isEmpty()) {
+ logger.warn("Bit-rate not found with ID: {}", id);
+ return Optional.empty();
+ }
+ BitRate bitRate = existingBitRate.get();
+ bitRate.setValue(value.trim());
+
+ BitRate updatedBitRate = bitRateRepository.update(bitRate);
+ return Optional.of(updatedBitRate);
+ }
+
+ public boolean deleteBitRate(Integer id){
+ logger.info("Deleting bit-rate ID: {}", id);
+ return bitRateRepository.deleteById(id);
+ }
+
+}
diff --git a/src/main/java/com/mediamanager/service/composer/ComposerService.java b/src/main/java/com/mediamanager/service/composer/ComposerService.java
new file mode 100644
index 0000000..4f2e5e7
--- /dev/null
+++ b/src/main/java/com/mediamanager/service/composer/ComposerService.java
@@ -0,0 +1,70 @@
+package com.mediamanager.service.composer;
+
+import com.mediamanager.model.Composer;
+import com.mediamanager.repository.ComposerRepository;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import java.util.List;
+import java.util.Optional;
+
+public class ComposerService {
+ private static final Logger logger = LogManager.getLogger(ComposerService.class);
+
+ private final ComposerRepository composerRepository;
+
+ public ComposerService(ComposerRepository composerRepository) {
+ this.composerRepository = composerRepository;
+ }
+
+ public Composer createComposer(String name) {
+ logger.info("Creating composer: {}", name);
+ if(name == null || name.trim().isEmpty()) {
+ throw new IllegalArgumentException("Composer name cannot be empty");
+ }
+ Composer composer = new Composer();
+ composer.setName(name.trim());
+ return composerRepository.save(composer);
+
+
+ }
+
+ public List getAllComposers() {
+ logger.info("Getting all composers");
+ return composerRepository.findAll();
+ }
+
+ public Optional getComposerById(Integer id) {
+ logger.info("Getting composer by ID: {}", id);
+ return composerRepository.findById(id);
+ }
+
+ public Optional updateComposer(Integer id, String name) {
+ logger.info("Updating composer ID {}: {}", id, name);
+
+ if(name == null || name.trim().isEmpty()) {
+ throw new IllegalArgumentException("Composer name cannot be empty");
+ }
+
+ Optional existingComposer = composerRepository.findById(id);
+
+ if(existingComposer.isEmpty()) {
+ logger.warn("Composer not found with ID: {}", id);
+ return Optional.empty();
+ }
+
+ Composer composer = existingComposer.get();
+ composer.setName(name.trim());
+
+ Composer updated = composerRepository.update(composer);
+ return Optional.of(updated);
+
+ }
+
+ public boolean deleteComposer(Integer id) {
+ logger.info("Deleting composer ID: {}", id);
+ return composerRepository.deleteById(id);
+ }
+
+
+}
diff --git a/src/main/java/com/mediamanager/service/database/DatabaseManager.java b/src/main/java/com/mediamanager/service/database/DatabaseManager.java
new file mode 100644
index 0000000..13188a0
--- /dev/null
+++ b/src/main/java/com/mediamanager/service/database/DatabaseManager.java
@@ -0,0 +1,142 @@
+package com.mediamanager.service.database;
+
+import jakarta.persistence.EntityManagerFactory;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.hibernate.cfg.Configuration;
+import org.reflections.Reflections;
+import org.reflections.scanners.Scanners;
+import jakarta.persistence.Entity;
+import java.util.Set;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.Properties;
+
+
+public abstract class DatabaseManager {
+ protected final Properties configuration;
+ protected Connection connection;
+ protected String connectionUrl;
+ protected EntityManagerFactory entityManagerFactory;
+ protected static final Logger logger = LogManager.getLogger(DatabaseManager.class);
+
+ public DatabaseManager(Properties config) {
+ this.configuration = config;
+ logger.debug("DatabaseManager created with configuration:");
+ }
+
+ public abstract void init() throws Exception;
+
+ protected abstract Connection createConnection() throws Exception;
+
+ protected void performSanityChecks() throws SQLException {
+ logger.debug("Performing sanity checks...");
+ try (Statement stmt = connection.createStatement()) {
+ stmt.execute("SELECT 1");
+
+ }
+ String databaseProductName = connection.getMetaData().getDatabaseProductName();
+ String databaseProductVersion = connection.getMetaData().getDatabaseProductVersion();
+ logger.info("Connected to database: {} v{}", databaseProductName, databaseProductVersion);
+ }
+
+ public Connection getConnection() {
+ return connection;
+ }
+
+ public void close() {
+ if (entityManagerFactory != null && entityManagerFactory.isOpen()) {
+ try {
+ entityManagerFactory.close();
+ logger.info("EntityManagerFactory closed");
+ } catch (Exception e) {
+ logger.error("Error closing EntityManagerFactory: {}", e.getMessage());
+ }
+ }
+ if (connection != null) {
+ try {
+ logger.info("Closing database connection...");
+ connection.close();
+ logger.info("Database connection closed successfully");
+ } catch (SQLException e) {
+ logger.error("Error closing database connection: {}", e.getMessage());
+ }
+ } else {
+ logger.debug("No database connection to close");
+ }
+ }
+
+ protected boolean testConnection() {
+ try (Statement stmt = connection.createStatement()) {
+ stmt.execute("SELECT 1");
+ return true;
+ } catch (SQLException e) {
+ logger.error("Connection test failed", e);
+ return false;
+ }
+ }
+ protected void initializeHibernate() {
+ logger.info("Initializing Hibernate ORM...");
+
+ Configuration hibernateConfig = new Configuration();
+
+
+ String dialect = configuration.getProperty("hibernate.dialect");
+ String hbm2ddl = configuration.getProperty("hibernate.hbm2ddl.auto");
+ String driver = configuration.getProperty("database.driver");
+
+ if (dialect == null || dialect.isEmpty()) {
+ throw new IllegalStateException("hibernate.dialect property is required but not configured");
+ }
+ if (driver == null || driver.isEmpty()) {
+ throw new IllegalStateException("database.driver property is required but not configured");
+ }
+ if (connectionUrl == null || connectionUrl.isEmpty()) {
+ throw new IllegalStateException("connectionUrl must be set before initializing Hibernate");
+ }
+
+
+ hibernateConfig.setProperty("hibernate.connection.url", connectionUrl);
+ hibernateConfig.setProperty("hibernate.connection.driver_class", driver);
+ hibernateConfig.setProperty("hibernate.dialect", dialect);
+ hibernateConfig.setProperty("hibernate.hbm2ddl.auto", hbm2ddl);
+ hibernateConfig.setProperty("hibernate.show_sql",
+ configuration.getProperty("hibernate.show_sql", "false"));
+ hibernateConfig.setProperty("hibernate.format_sql",
+ configuration.getProperty("hibernate.format_sql", "true"));
+
+ logger.info("Scanning for entities in package: com.mediamanager.model");
+
+ Set> entityClasses;
+ try {
+ Reflections reflections = new Reflections("com.mediamanager.model", Scanners.TypesAnnotated);
+ entityClasses = reflections.getTypesAnnotatedWith(Entity.class);
+ } catch (Exception e) {
+ logger.error("Failed to scan for entities: {}", e.getMessage());
+ throw new RuntimeException("Entity scanning failed", e);
+ }
+
+ logger.info("Found {} entities", entityClasses.size());
+ if (entityClasses.isEmpty()) {
+ logger.warn("No @Entity classes found in package com.mediamanager.model - is this expected?");
+ }
+ for (Class> entityClass : entityClasses) {
+ logger.debug("Registering entity: {}", entityClass.getSimpleName());
+ hibernateConfig.addAnnotatedClass(entityClass);
+ }
+
+ try {
+ entityManagerFactory = hibernateConfig.buildSessionFactory().unwrap(EntityManagerFactory.class);
+ } catch (Exception e) {
+ logger.error("Failed to initialize Hibernate: {}", e.getMessage());
+ throw new RuntimeException("Hibernate initialization failed", e);
+ }
+
+ logger.info("Hibernate ORM initialized successfully");
+ }
+
+ public EntityManagerFactory getEntityManagerFactory() {
+ return entityManagerFactory;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/mediamanager/service/database/SqliteDatabaseManager.java b/src/main/java/com/mediamanager/service/database/SqliteDatabaseManager.java
new file mode 100644
index 0000000..dc98c91
--- /dev/null
+++ b/src/main/java/com/mediamanager/service/database/SqliteDatabaseManager.java
@@ -0,0 +1,99 @@
+package com.mediamanager.service.database;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.Properties;
+
+public class SqliteDatabaseManager extends DatabaseManager {
+ private static final Logger logger = LogManager.getLogger(SqliteDatabaseManager.class);
+
+
+
+
+ public SqliteDatabaseManager(Properties config) {
+ super(config);
+ }
+
+ @Override
+ public void init() throws Exception {
+
+ logger.info("Initializing SQLite database...");
+ String dataDir = configuration.getProperty("database.dir",
+ System.getProperty("user.home") + "/.mediamanager/db");
+ String dbFilename = configuration.getProperty("database.filename", "mediamanager.db");
+ String driverClassName = configuration.getProperty("database.driver", "org.sqlite.JDBC");
+ try {
+ Class.forName(driverClassName);
+ }catch(ClassNotFoundException e) {
+ logger.error("Failed to load SQLite driver", e);
+ throw e;
+ }
+ Path dataPath = Paths.get(dataDir);
+ if (!Files.exists(dataPath)) {
+ Files.createDirectories(dataPath);
+ logger.debug("Created database directory: {}", dataDir);
+ }
+ Path dbFile = dataPath.resolve(dbFilename);
+ this.connectionUrl = "jdbc:sqlite:" + dbFile.toAbsolutePath().toString();
+ logger.info("Database file path: {}", dbFile);
+ logger.info("Connection URL: {}", this.connectionUrl);
+ initializeHibernate();
+ this.connection = createConnection();
+ configurePerformancePragmas();
+ performSanityChecks();
+ ensureSchemaExists();
+ logger.info("SQLite database initialized successfully");
+
+
+ }
+
+ @Override
+ protected Connection createConnection() throws Exception {
+ try {
+ // O driver org.xerial.sqlite-jdbc é carregado automaticamente aqui
+ Connection conn = DriverManager.getConnection(this.connectionUrl);
+ logger.debug("Got connection to SQLite file");
+ return conn;
+ } catch (SQLException e) {
+ logger.error("Failed to create SQLite connection", e);
+ throw new Exception("SQLite connection failed: " + e.getMessage(), e);
+ }
+ }
+
+
+ private void configurePerformancePragmas() throws SQLException {
+ try (Statement stmt = connection.createStatement()) {
+
+ stmt.execute("PRAGMA journal_mode=WAL;");
+
+
+ stmt.execute("PRAGMA foreign_keys=ON;");
+
+
+ stmt.execute("PRAGMA synchronous=NORMAL;");
+
+ stmt.execute("PRAGMA busy_timeout=5000;");
+
+ logger.debug("SQLite performance PRAGMAs applied (WAL, Synchronous, ForeignKeys).");
+ }
+ }
+
+ private void ensureSchemaExists() throws SQLException {
+
+ }
+
+ @Override
+ public void close() {
+
+ super.close();
+ logger.info("SQLite resources released.");
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/mediamanager/service/delegate/ActionHandler.java b/src/main/java/com/mediamanager/service/delegate/ActionHandler.java
new file mode 100644
index 0000000..27228fc
--- /dev/null
+++ b/src/main/java/com/mediamanager/service/delegate/ActionHandler.java
@@ -0,0 +1,11 @@
+package com.mediamanager.service.delegate;
+
+import com.google.protobuf.ByteString;
+import com.google.protobuf.InvalidProtocolBufferException;
+import com.mediamanager.protocol.TransportProtocol;
+
+@FunctionalInterface
+public interface ActionHandler {
+ TransportProtocol.Response.Builder handle(ByteString requestPayload) throws InvalidProtocolBufferException;
+}
+
diff --git a/src/main/java/com/mediamanager/service/delegate/DelegateActionManager.java b/src/main/java/com/mediamanager/service/delegate/DelegateActionManager.java
new file mode 100644
index 0000000..1f1cb81
--- /dev/null
+++ b/src/main/java/com/mediamanager/service/delegate/DelegateActionManager.java
@@ -0,0 +1,253 @@
+package com.mediamanager.service.delegate;
+
+import com.google.protobuf.ByteString;
+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.albumhasgenre.AlbumHasGenreService;
+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.delegate.annotation.Action;
+
+import com.mediamanager.service.genre.GenreService;
+import com.mediamanager.service.samplingrate.SamplingRateService;
+import jakarta.persistence.EntityManagerFactory;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.reflections.Reflections;
+import org.reflections.scanners.Scanners;
+import java.lang.reflect.Constructor;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+public class DelegateActionManager {
+ private static final Logger logger = LogManager.getLogger(DelegateActionManager.class);
+
+ private final Map handlerRegistry;
+ private final ServiceLocator serviceLocator;
+ private final EntityManagerFactory entityManagerFactory;
+
+
+ public DelegateActionManager(EntityManagerFactory entityManagerFactory) {
+ this.entityManagerFactory = entityManagerFactory;
+ this.serviceLocator = new ServiceLocator();
+
+ initializeServices();
+
+
+ logger.debug("DelegateActionManager created");
+ this.handlerRegistry = new HashMap<>();
+ autoRegisterHandlers();
+
+ }
+
+ private void initializeServices() {
+ logger.info("Initializing services...");
+
+
+ GenreRepository genreRepository = new GenreRepository(entityManagerFactory);
+ GenreService genreService = new GenreService(genreRepository);
+
+
+ serviceLocator.register(GenreService.class, genreService);
+
+ ArtistRepository artistRepository = new ArtistRepository(entityManagerFactory);
+ ArtistService artistService = new ArtistService(artistRepository);
+
+ serviceLocator.register(ArtistService.class, artistService);
+
+ ComposerRepository composerRepository = new ComposerRepository(entityManagerFactory);
+ ComposerService composerService = new ComposerService(composerRepository);
+ serviceLocator.register(ComposerService.class, composerService);
+
+ BitDepthRepository bitDepthRepository = new BitDepthRepository(entityManagerFactory);
+ BitDepthService bitDepthService = new BitDepthService(bitDepthRepository);
+ serviceLocator.register(BitDepthService.class, bitDepthService);
+
+ BitRateRepository bitRateRepository = new BitRateRepository(entityManagerFactory);
+ BitRateService bitRateService = new BitRateService(bitRateRepository);
+ serviceLocator.register(BitRateService.class, bitRateService);
+
+ SamplingRateRepository samplingRateRepository = new SamplingRateRepository(entityManagerFactory);
+ SamplingRateService samplingRateService = new SamplingRateService(samplingRateRepository);
+ serviceLocator.register(SamplingRateService.class, samplingRateService);
+
+ AlbumArtRepository albumArtRepository = new AlbumArtRepository(entityManagerFactory);
+ AlbumArtService albumArtService = new AlbumArtService(albumArtRepository);
+ serviceLocator.register(AlbumArtService.class, albumArtService);
+
+ AlbumTypeRepository albumTypeRepository = new AlbumTypeRepository(entityManagerFactory);
+ AlbumTypeService albumTypeService = new AlbumTypeService(albumTypeRepository);
+ serviceLocator.register(AlbumTypeService.class, albumTypeService);
+
+ AlbumRepository albumRepository = new AlbumRepository(entityManagerFactory);
+ 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);
+
+ AlbumHasGenreRepository albumHasGenreRepository = new AlbumHasGenreRepository(entityManagerFactory);
+ AlbumHasGenreService albumHasGenreService = new AlbumHasGenreService(albumHasGenreRepository, albumRepository, genreRepository);
+ serviceLocator.register(AlbumHasGenreService.class, albumHasGenreService);
+
+ serviceLocator.logRegisteredServices();
+
+ logger.info("Services initialized successfully");
+ }
+
+
+
+ public void start(){
+ logger.info("DelegateActionManager started");
+ }
+
+ public void stop(){
+ logger.info("DelegateActionManager stopped");
+ }
+
+ @SuppressWarnings("unchecked")
+ private ActionHandler instantiateHandler(Class> clazz) throws Exception {
+ if(!ActionHandler.class.isAssignableFrom(clazz)){
+ throw new IllegalArgumentException(
+ clazz.getName() + " is annotated with @Action but does not implement ActionHandler");
+
+ }
+ logger.debug("Attempting to instantiate handler: {}", clazz.getSimpleName());
+
+
+ Constructor>[] constructors = clazz.getDeclaredConstructors();
+
+
+ // Sort constructors by parameter count (descending) to prefer DI constructors
+ java.util.Arrays.sort(constructors, (c1, c2) ->
+ Integer.compare(c2.getParameterCount(), c1.getParameterCount()));
+
+ for (Constructor> constructor : constructors) {
+
+ Class>[] paramTypes = constructor.getParameterTypes();
+
+
+ Object[] params = new Object[paramTypes.length];
+ boolean allDependenciesResolved = true;
+
+ for (int i = 0; i < paramTypes.length; i++) {
+
+ Object service = serviceLocator.get(paramTypes[i]);
+
+ if (service == null) {
+
+ allDependenciesResolved = false;
+ logger.debug("Cannot resolve dependency {} for {}",
+ paramTypes[i].getSimpleName(),
+ clazz.getSimpleName());
+ break; // Para de tentar esse construtor
+ }
+
+
+ params[i] = service;
+ }
+
+
+ if (allDependenciesResolved) {
+ logger.debug("Using constructor with {} params for {}",
+ paramTypes.length, clazz.getSimpleName());
+ return (ActionHandler) constructor.newInstance(params);
+ }
+ }
+
+
+ throw new IllegalStateException(
+ String.format(
+ "Cannot instantiate handler %s. No suitable constructor found. " +
+ "Make sure all required services are registered in ServiceLocator.",
+ clazz.getName()
+ )
+ );
+ }
+
+ private void autoRegisterHandlers() {
+ logger.info("Starting auto-registration of handlers...");
+ Reflections reflections = new Reflections(
+ "com.mediamanager.service.delegate.handler",
+ Scanners.TypesAnnotated
+ );
+ Set> annotatedClasses = reflections.getTypesAnnotatedWith(Action.class);
+ logger.info("Found {} handler classes with @Action annotation", annotatedClasses.size());
+ int successCount = 0;
+ int failureCount = 0;
+ for (Class> handlerClass : annotatedClasses) {
+ try {
+
+ Action actionAnnotation = handlerClass.getAnnotation(Action.class);
+ String actionName = actionAnnotation.value();
+
+ logger.debug("Processing handler: {} for action '{}'",
+ handlerClass.getSimpleName(),
+ actionName);
+
+
+ ActionHandler handler = instantiateHandler(handlerClass);
+
+
+ handlerRegistry.put(actionName, handler);
+
+ logger.info("✓ Registered handler: '{}' -> {}",
+ actionName,
+ handlerClass.getSimpleName());
+ successCount++;
+
+ } catch (Exception e) {
+
+ logger.error("✗ Failed to register handler: {}",
+ handlerClass.getName(),
+ e);
+ failureCount++;
+ }
+ }
+
+
+ logger.info("Auto-registration complete: {} successful, {} failed, {} total",
+ successCount,
+ failureCount,
+ successCount + failureCount);
+
+ if (failureCount > 0) {
+ logger.warn("Some handlers failed to register. Check logs above for details.");
+ }
+ }
+
+ public TransportProtocol.Response ProcessedRequest(TransportProtocol.Request request){
+ String requestId = request.getRequestId();
+ logger.info("Processing request: {}", requestId);
+ String action = request.getHeadersMap().getOrDefault("action", "unknown");
+ ActionHandler handler = handlerRegistry.get(action);
+ TransportProtocol.Response.Builder responseBuilder;
+ if (handler == null) {
+ logger.warn("No handler found for action: {}", action);
+ responseBuilder = TransportProtocol.Response.newBuilder()
+ .setStatusCode(404) // 404 Not Found
+ .setPayload(ByteString.copyFromUtf8("Error: Action '" + action + "' not found."));
+ } else{
+ try {
+ logger.debug("Delegating action '{}' to handler...", action);
+ responseBuilder = handler.handle(request.getPayload());
+ }catch (Exception e) {
+ logger.error("Handler for action '{}' threw an exception:", action, e);
+ responseBuilder = TransportProtocol.Response.newBuilder()
+ .setStatusCode(500) // 500 Internal Server Error
+ .setPayload(ByteString.copyFromUtf8("Error: " + e.getMessage()));
+ }
+ }
+ return responseBuilder.setRequestId(requestId).build();
+ }
+}
diff --git a/src/main/java/com/mediamanager/service/delegate/ServiceLocator.java b/src/main/java/com/mediamanager/service/delegate/ServiceLocator.java
new file mode 100644
index 0000000..69886f4
--- /dev/null
+++ b/src/main/java/com/mediamanager/service/delegate/ServiceLocator.java
@@ -0,0 +1,45 @@
+package com.mediamanager.service.delegate;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class ServiceLocator {
+ private static final Logger logger = LogManager.getLogger(ServiceLocator.class);
+ private final Map, Object> services = new HashMap<>();
+
+ public void register(Class serviceClass, T serviceInstance) {
+ if (serviceInstance == null) {
+ throw new IllegalArgumentException("Service instance cannot be null");
+ }
+ services.put(serviceClass, serviceInstance);
+ logger.debug("Registered service: {} -> {}",
+ serviceClass.getSimpleName(),
+ serviceInstance.getClass().getSimpleName());
+ }
+
+ @SuppressWarnings("unchecked")
+ public T get(Class serviceClass) {
+ return (T) services.get(serviceClass);
+ }
+
+ public boolean has(Class> serviceClass) {
+ return services.containsKey(serviceClass);
+ }
+ public int size() {
+ return services.size();
+ }
+ public void logRegisteredServices() {
+ logger.info("Registered services: {}", services.size());
+
+
+ services.forEach((clazz, instance) ->
+ logger.info(" - {} -> {}",
+ clazz.getSimpleName(),
+ instance.getClass().getSimpleName())
+ );
+ }
+}
+
diff --git a/src/main/java/com/mediamanager/service/delegate/annotation/Action.java b/src/main/java/com/mediamanager/service/delegate/annotation/Action.java
new file mode 100644
index 0000000..cac0db7
--- /dev/null
+++ b/src/main/java/com/mediamanager/service/delegate/annotation/Action.java
@@ -0,0 +1,13 @@
+package com.mediamanager.service.delegate.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+public @interface Action {
+
+ String value();
+}
diff --git a/src/main/java/com/mediamanager/service/delegate/handler/CloseHandler.java b/src/main/java/com/mediamanager/service/delegate/handler/CloseHandler.java
new file mode 100644
index 0000000..9e9c658
--- /dev/null
+++ b/src/main/java/com/mediamanager/service/delegate/handler/CloseHandler.java
@@ -0,0 +1,34 @@
+package com.mediamanager.service.delegate.handler;
+
+import com.google.protobuf.ByteString;
+import com.google.protobuf.InvalidProtocolBufferException;
+import com.mediamanager.protocol.TestProtocol.CloseCommand;
+import com.mediamanager.protocol.TestProtocol.CloseResponse;
+import com.mediamanager.protocol.TransportProtocol;
+import com.mediamanager.service.delegate.ActionHandler;
+import com.mediamanager.service.delegate.annotation.Action;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+@Action("close")
+public class CloseHandler implements ActionHandler {
+ private static final Logger logger = LogManager.getLogger(CloseHandler.class);
+
+ @Override
+ public TransportProtocol.Response.Builder handle(ByteString requestPayload)
+ throws InvalidProtocolBufferException {
+
+ CloseCommand.parseFrom(requestPayload); // Valida
+
+ logger.info("Close command received - connection will close");
+
+ CloseResponse response = CloseResponse.newBuilder()
+ .setMessage("Connection closing. Goodbye!")
+ .build();
+
+ return TransportProtocol.Response.newBuilder()
+ .setPayload(ByteString.copyFrom(response.toByteArray()))
+ .setStatusCode(200)
+ .putHeaders("Connection", "close"); // ← Marca para fechar
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/mediamanager/service/delegate/handler/EchoHandler.java b/src/main/java/com/mediamanager/service/delegate/handler/EchoHandler.java
new file mode 100644
index 0000000..657c2e7
--- /dev/null
+++ b/src/main/java/com/mediamanager/service/delegate/handler/EchoHandler.java
@@ -0,0 +1,41 @@
+package com.mediamanager.service.delegate.handler;
+
+import com.google.protobuf.ByteString;
+import com.google.protobuf.InvalidProtocolBufferException;
+import com.mediamanager.protocol.TestProtocol.EchoCommand; // ← Import
+import com.mediamanager.protocol.TestProtocol.EchoResponse; // ← Import
+import com.mediamanager.protocol.TransportProtocol;
+import com.mediamanager.service.delegate.ActionHandler;
+import com.mediamanager.service.delegate.annotation.Action;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+@Action("echo")
+public class EchoHandler implements ActionHandler {
+ private static final Logger logger = LogManager.getLogger(EchoHandler.class);
+
+ @Override
+ public TransportProtocol.Response.Builder handle(ByteString requestPayload)
+ throws InvalidProtocolBufferException { // ← Pode lançar exceção
+
+ // 1. Parse Protobuf bytes → EchoCommand
+ EchoCommand command = EchoCommand.parseFrom(requestPayload);
+
+ logger.debug("Echo received: {}", command.getMessage());
+
+ // 2. Cria EchoResponse (Protobuf)
+ EchoResponse echoResponse = EchoResponse.newBuilder()
+ .setMessage(command.getMessage())
+ .setServerTimestamp(System.currentTimeMillis())
+ .build();
+
+ // 3. Serializa EchoResponse → bytes
+ ByteString responsePayload = ByteString.copyFrom(echoResponse.toByteArray());
+
+ // 4. Retorna Response
+ return TransportProtocol.Response.newBuilder()
+ .setPayload(responsePayload)
+ .setStatusCode(200);
+
+ }
+}
diff --git a/src/main/java/com/mediamanager/service/delegate/handler/HeartbeatHandler.java b/src/main/java/com/mediamanager/service/delegate/handler/HeartbeatHandler.java
new file mode 100644
index 0000000..d79270c
--- /dev/null
+++ b/src/main/java/com/mediamanager/service/delegate/handler/HeartbeatHandler.java
@@ -0,0 +1,38 @@
+package com.mediamanager.service.delegate.handler;
+
+import com.google.protobuf.ByteString;
+import com.google.protobuf.InvalidProtocolBufferException;
+import com.mediamanager.protocol.TestProtocol.HeartbeatCommand;
+import com.mediamanager.protocol.TestProtocol.HeartbeatResponse;
+import com.mediamanager.protocol.TransportProtocol;
+import com.mediamanager.service.delegate.ActionHandler;
+import com.mediamanager.service.delegate.annotation.Action;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+@Action("heartbeat")
+public class HeartbeatHandler implements ActionHandler {
+ private static final Logger logger = LogManager.getLogger(HeartbeatHandler.class);
+
+ @Override
+ public TransportProtocol.Response.Builder handle(ByteString requestPayload)
+ throws InvalidProtocolBufferException {
+
+ HeartbeatCommand command = HeartbeatCommand.parseFrom(requestPayload);
+
+ long serverTime = System.currentTimeMillis();
+
+ logger.debug("Heartbeat received. Client T1={}, Server T2={}",
+ command.getClientTimestamp(), serverTime);
+
+ HeartbeatResponse response = HeartbeatResponse.newBuilder()
+ .setClientTimestamp(command.getClientTimestamp()) // Echo T1
+ .setServerTimestamp(serverTime) // T2
+ .build();
+
+ return TransportProtocol.Response.newBuilder()
+ .setPayload(ByteString.copyFrom(response.toByteArray()))
+ .setStatusCode(200);
+
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/mediamanager/service/delegate/handler/album/CreateAlbumHandler.java b/src/main/java/com/mediamanager/service/delegate/handler/album/CreateAlbumHandler.java
new file mode 100644
index 0000000..a7c3d75
--- /dev/null
+++ b/src/main/java/com/mediamanager/service/delegate/handler/album/CreateAlbumHandler.java
@@ -0,0 +1,59 @@
+package com.mediamanager.service.delegate.handler.album;
+
+import com.google.protobuf.ByteString;
+import com.google.protobuf.InvalidProtocolBufferException;
+import com.mediamanager.mapper.AlbumMapper;
+import com.mediamanager.model.Album;
+import com.mediamanager.protocol.TransportProtocol;
+import com.mediamanager.protocol.messages.AlbumMessages;
+import com.mediamanager.service.delegate.ActionHandler;
+import com.mediamanager.service.delegate.annotation.Action;
+import com.mediamanager.service.album.AlbumService;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+@Action("album.create")
+public class CreateAlbumHandler implements ActionHandler {
+ private static final Logger logger = LogManager.getLogger(CreateAlbumHandler.class);
+ private final AlbumService albumService;
+
+ public CreateAlbumHandler(AlbumService albumService) {
+ this.albumService = albumService;
+ }
+
+ @Override
+ public TransportProtocol.Response.Builder handle(ByteString requestPayload) throws InvalidProtocolBufferException {
+ try{
+ AlbumMessages.CreateAlbumRequest createRequest =
+ AlbumMessages.CreateAlbumRequest.parseFrom(requestPayload);
+
+ Album album = albumService.createAlbum(
+ createRequest.getName(),
+ createRequest.getYear() > 0 ? createRequest.getYear() : null,
+ createRequest.getNumberOfDiscs() > 0 ? createRequest.getNumberOfDiscs() : null,
+ createRequest.getCode().isEmpty() ? null : createRequest.getCode(),
+ createRequest.getIsCompilation(),
+ createRequest.getFkAlbumtypeId() > 0 ? createRequest.getFkAlbumtypeId() : null,
+ createRequest.getFkAlbumartId() > 0 ? createRequest.getFkAlbumartId() : null
+ );
+
+ AlbumMessages.Album albumProto = AlbumMapper.toProtobuf(album);
+ AlbumMessages.CreateAlbumResponse createAlbumResponse = AlbumMessages.CreateAlbumResponse.newBuilder()
+ .setAlbum(albumProto)
+ .build();
+ return TransportProtocol.Response.newBuilder()
+ .setPayload(createAlbumResponse.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", e);
+ return TransportProtocol.Response.newBuilder()
+ .setStatusCode(500)
+ .setPayload(ByteString.copyFromUtf8("Error: " + e.getMessage()));
+ }
+ }
+}
diff --git a/src/main/java/com/mediamanager/service/delegate/handler/album/DeleteAlbumHandler.java b/src/main/java/com/mediamanager/service/delegate/handler/album/DeleteAlbumHandler.java
new file mode 100644
index 0000000..101325c
--- /dev/null
+++ b/src/main/java/com/mediamanager/service/delegate/handler/album/DeleteAlbumHandler.java
@@ -0,0 +1,62 @@
+package com.mediamanager.service.delegate.handler.album;
+
+import com.google.protobuf.ByteString;
+import com.google.protobuf.InvalidProtocolBufferException;
+import com.mediamanager.protocol.TransportProtocol;
+import com.mediamanager.protocol.messages.AlbumMessages;
+import com.mediamanager.service.delegate.ActionHandler;
+import com.mediamanager.service.delegate.annotation.Action;
+import com.mediamanager.service.album.AlbumService;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+@Action("album.delete")
+public class DeleteAlbumHandler implements ActionHandler {
+ private static final Logger logger = LogManager.getLogger(DeleteAlbumHandler.class);
+
+ private final AlbumService albumService;
+
+ public DeleteAlbumHandler(AlbumService albumService) {
+ this.albumService = albumService;
+ }
+
+ @Override
+ public TransportProtocol.Response.Builder handle(ByteString requestPayload)
+ throws InvalidProtocolBufferException {
+
+ try {
+ AlbumMessages.DeleteAlbumRequest deleteRequest =
+ AlbumMessages.DeleteAlbumRequest.parseFrom(requestPayload);
+ int id = deleteRequest.getId();
+ boolean success = albumService.deleteAlbum(id);
+ AlbumMessages.DeleteAlbumResponse deleteResponse;
+ if (success) {
+ deleteResponse = AlbumMessages.DeleteAlbumResponse.newBuilder()
+ .setSuccess(true)
+ .setMessage("Album deleted successfully")
+ .build();
+ return TransportProtocol.Response.newBuilder()
+ .setPayload(deleteResponse.toByteString());
+ } else {
+ deleteResponse = AlbumMessages.DeleteAlbumResponse.newBuilder()
+ .setSuccess(false)
+ .setMessage("Album not found")
+ .build();
+
+ return TransportProtocol.Response.newBuilder()
+ .setStatusCode(404)
+ .setPayload(deleteResponse.toByteString());
+ }
+ } catch (Exception e) {
+ logger.error("Error deleting album", e);
+ AlbumMessages.DeleteAlbumResponse deleteResponse =
+ AlbumMessages.DeleteAlbumResponse.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/album/GetAlbumByIdHandler.java b/src/main/java/com/mediamanager/service/delegate/handler/album/GetAlbumByIdHandler.java
new file mode 100644
index 0000000..97d2814
--- /dev/null
+++ b/src/main/java/com/mediamanager/service/delegate/handler/album/GetAlbumByIdHandler.java
@@ -0,0 +1,56 @@
+package com.mediamanager.service.delegate.handler.album;
+
+import com.google.protobuf.ByteString;
+import com.google.protobuf.InvalidProtocolBufferException;
+import com.mediamanager.mapper.AlbumMapper;
+import com.mediamanager.model.Album;
+import com.mediamanager.protocol.TransportProtocol;
+import com.mediamanager.protocol.messages.AlbumMessages;
+import com.mediamanager.service.delegate.ActionHandler;
+import com.mediamanager.service.delegate.annotation.Action;
+import com.mediamanager.service.album.AlbumService;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import java.util.Optional;
+
+@Action(value = "album.getById")
+public class GetAlbumByIdHandler implements ActionHandler {
+ private static final Logger logger = LogManager.getLogger(GetAlbumByIdHandler.class);
+ private final AlbumService albumService;
+
+ public GetAlbumByIdHandler(AlbumService albumService) {
+ this.albumService = albumService;
+ }
+
+ @Override
+ public TransportProtocol.Response.Builder handle(ByteString requestPayload)
+ throws InvalidProtocolBufferException{
+
+ try{
+ AlbumMessages.GetAlbumByIdRequest getByIdRequest =
+ AlbumMessages.GetAlbumByIdRequest.parseFrom(requestPayload);
+ int id = getByIdRequest.getId();
+
+ Optional albumOpt = albumService.getAlbumById(id);
+
+ if (albumOpt.isEmpty()){
+ logger.warn("Album not found with ID: {}", id);
+ return TransportProtocol.Response.newBuilder()
+ .setStatusCode(404)
+ .setPayload(ByteString.copyFromUtf8("Album not found"));
+ }
+ AlbumMessages.Album albumProto = AlbumMapper.toProtobuf(albumOpt.get());
+ AlbumMessages.GetAlbumByIdResponse getByIdResponse = AlbumMessages.GetAlbumByIdResponse.newBuilder()
+ .setAlbum(albumProto)
+ .build();
+ return TransportProtocol.Response.newBuilder()
+ .setPayload(getByIdResponse.toByteString());
+ } catch (Exception e) {
+ logger.error("Error getting album 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/album/GetAlbumHandler.java b/src/main/java/com/mediamanager/service/delegate/handler/album/GetAlbumHandler.java
new file mode 100644
index 0000000..9d388f3
--- /dev/null
+++ b/src/main/java/com/mediamanager/service/delegate/handler/album/GetAlbumHandler.java
@@ -0,0 +1,48 @@
+package com.mediamanager.service.delegate.handler.album;
+
+import com.google.protobuf.ByteString;
+import com.google.protobuf.InvalidProtocolBufferException;
+import com.mediamanager.mapper.AlbumMapper;
+import com.mediamanager.model.Album;
+import com.mediamanager.protocol.TransportProtocol;
+import com.mediamanager.protocol.messages.AlbumMessages;
+import com.mediamanager.service.delegate.ActionHandler;
+import com.mediamanager.service.delegate.annotation.Action;
+import com.mediamanager.service.album.AlbumService;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import java.util.List;
+
+
+@Action("album.getAll")
+public class GetAlbumHandler implements ActionHandler {
+ private static final Logger logger = LogManager.getLogger(GetAlbumHandler.class);
+
+ private final AlbumService albumService;
+
+ public GetAlbumHandler(AlbumService albumService){this.albumService = albumService;}
+
+ @Override
+ public TransportProtocol.Response.Builder handle(ByteString requestPayload) throws InvalidProtocolBufferException {
+ try{
+ List albums = albumService.getAllAlbums();
+ AlbumMessages.GetAlbumsResponse.Builder responseBuilder = AlbumMessages.GetAlbumsResponse.newBuilder();
+
+ for (Album album : albums) {
+ AlbumMessages.Album albumProto = AlbumMapper.toProtobuf(album);
+ responseBuilder.addAlbums(albumProto);
+ }
+ AlbumMessages.GetAlbumsResponse getAlbumsResponse = responseBuilder.build();
+
+ return TransportProtocol.Response.newBuilder()
+ .setPayload(getAlbumsResponse.toByteString());
+
+ }catch (Exception e){
+ logger.error("Error getting albums", e);
+ return TransportProtocol.Response.newBuilder()
+ .setStatusCode(500)
+ .setPayload(ByteString.copyFromUtf8("Error: " + e.getMessage()));
+ }
+ }
+}
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
new file mode 100644
index 0000000..d9f81b4
--- /dev/null
+++ b/src/main/java/com/mediamanager/service/delegate/handler/album/UpdateAlbumHandler.java
@@ -0,0 +1,96 @@
+package com.mediamanager.service.delegate.handler.album;
+
+import com.google.protobuf.ByteString;
+import com.google.protobuf.InvalidProtocolBufferException;
+import com.mediamanager.mapper.AlbumMapper;
+import com.mediamanager.model.Album;
+import com.mediamanager.protocol.TransportProtocol;
+import com.mediamanager.protocol.messages.AlbumMessages;
+import com.mediamanager.service.delegate.ActionHandler;
+import com.mediamanager.service.delegate.annotation.Action;
+import com.mediamanager.service.album.AlbumService;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import java.util.Optional;
+
+@Action("album.update")
+public class UpdateAlbumHandler implements ActionHandler {
+ private static final Logger logger = LogManager.getLogger(UpdateAlbumHandler.class);
+ private final AlbumService albumService;
+
+ public UpdateAlbumHandler(AlbumService albumService) {
+ this.albumService = albumService;
+ }
+
+ @Override
+ 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(),
+ year,
+ numberOfDiscs,
+ updateRequest.getCode().isEmpty() ? null : updateRequest.getCode(),
+ updateRequest.getIsCompilation(),
+ albumTypeId,
+ albumArtId,
+ updateRequest.hasYear(), // ← Novo!
+ updateRequest.hasNumberOfDiscs(), // ← Novo!
+ updateRequest.hasFkAlbumtypeId(), // ← Novo!
+ updateRequest.hasFkAlbumartId() // ← Novo!
+ );
+
+ if (albumOpt.isEmpty()) {
+ logger.warn("Album not found with ID: {}", id);
+ return TransportProtocol.Response.newBuilder()
+ .setStatusCode(404)
+ .setPayload(ByteString.copyFromUtf8("Album not found"));
+ }
+
+ AlbumMessages.Album albumProto = AlbumMapper.toProtobuf(albumOpt.get());
+
+ AlbumMessages.UpdateAlbumResponse updateResponse =
+ AlbumMessages.UpdateAlbumResponse.newBuilder()
+ .setAlbum(albumProto)
+ .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 album", e);
+ return TransportProtocol.Response.newBuilder()
+ .setStatusCode(500)
+ .setPayload(ByteString.copyFromUtf8("Error: " + e.getMessage()));
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/mediamanager/service/delegate/handler/albumart/CreateAlbumArtHandler.java b/src/main/java/com/mediamanager/service/delegate/handler/albumart/CreateAlbumArtHandler.java
new file mode 100644
index 0000000..2d9d3a1
--- /dev/null
+++ b/src/main/java/com/mediamanager/service/delegate/handler/albumart/CreateAlbumArtHandler.java
@@ -0,0 +1,49 @@
+package com.mediamanager.service.delegate.handler.albumart;
+
+import com.google.protobuf.ByteString;
+import com.google.protobuf.InvalidProtocolBufferException;
+import com.mediamanager.mapper.AlbumArtMapper;
+import com.mediamanager.model.AlbumArt;
+import com.mediamanager.protocol.TransportProtocol;
+import com.mediamanager.protocol.messages.AlbumArtMessages;
+import com.mediamanager.service.delegate.ActionHandler;
+import com.mediamanager.service.delegate.annotation.Action;
+import com.mediamanager.service.albumart.AlbumArtService;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+@Action("albumart.create")
+public class CreateAlbumArtHandler implements ActionHandler {
+ private static final Logger logger = LogManager.getLogger(CreateAlbumArtHandler.class);
+ private final AlbumArtService albumArtService;
+
+ public CreateAlbumArtHandler(AlbumArtService albumArtService) {
+ this.albumArtService = albumArtService;
+ }
+
+ @Override
+ public TransportProtocol.Response.Builder handle(ByteString requestPayload) throws InvalidProtocolBufferException {
+ try{
+ AlbumArtMessages.CreateAlbumArtRequest createRequest =
+ AlbumArtMessages.CreateAlbumArtRequest.parseFrom(requestPayload);
+ AlbumArt albumArt = albumArtService.createAlbumArt(createRequest.getFilepath());
+ AlbumArtMessages.AlbumArt albumArtProto = AlbumArtMapper.toProtobuf(albumArt);
+ AlbumArtMessages.CreateAlbumArtResponse createAlbumArtResponse = AlbumArtMessages.CreateAlbumArtResponse.newBuilder()
+ .setAlbumart(albumArtProto)
+ .build();
+ return TransportProtocol.Response.newBuilder()
+ .setPayload(createAlbumArtResponse.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 art", e);
+ return TransportProtocol.Response.newBuilder()
+ .setStatusCode(500)
+ .setPayload(ByteString.copyFromUtf8("Error: " + e.getMessage()));
+ }
+ }
+}
diff --git a/src/main/java/com/mediamanager/service/delegate/handler/albumart/DeleteAlbumArtHandler.java b/src/main/java/com/mediamanager/service/delegate/handler/albumart/DeleteAlbumArtHandler.java
new file mode 100644
index 0000000..bfe3c03
--- /dev/null
+++ b/src/main/java/com/mediamanager/service/delegate/handler/albumart/DeleteAlbumArtHandler.java
@@ -0,0 +1,62 @@
+package com.mediamanager.service.delegate.handler.albumart;
+
+import com.google.protobuf.ByteString;
+import com.google.protobuf.InvalidProtocolBufferException;
+import com.mediamanager.protocol.TransportProtocol;
+import com.mediamanager.protocol.messages.AlbumArtMessages;
+import com.mediamanager.service.delegate.ActionHandler;
+import com.mediamanager.service.delegate.annotation.Action;
+import com.mediamanager.service.albumart.AlbumArtService;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+@Action("albumart.delete")
+public class DeleteAlbumArtHandler implements ActionHandler {
+ private static final Logger logger = LogManager.getLogger(DeleteAlbumArtHandler.class);
+
+ private final AlbumArtService albumArtService;
+
+ public DeleteAlbumArtHandler(AlbumArtService albumArtService) {
+ this.albumArtService = albumArtService;
+ }
+
+ @Override
+ public TransportProtocol.Response.Builder handle(ByteString requestPayload)
+ throws InvalidProtocolBufferException {
+
+ try {
+ AlbumArtMessages.DeleteAlbumArtRequest deleteRequest =
+ AlbumArtMessages.DeleteAlbumArtRequest.parseFrom(requestPayload);
+ int id = deleteRequest.getId();
+ boolean success = albumArtService.deleteAlbumArt(id);
+ AlbumArtMessages.DeleteAlbumArtResponse deleteResponse;
+ if (success) {
+ deleteResponse = AlbumArtMessages.DeleteAlbumArtResponse.newBuilder()
+ .setSuccess(true)
+ .setMessage("Album art deleted successfully")
+ .build();
+ return TransportProtocol.Response.newBuilder()
+ .setPayload(deleteResponse.toByteString());
+ } else {
+ deleteResponse = AlbumArtMessages.DeleteAlbumArtResponse.newBuilder()
+ .setSuccess(false)
+ .setMessage("Album art not found")
+ .build();
+
+ return TransportProtocol.Response.newBuilder()
+ .setStatusCode(404)
+ .setPayload(deleteResponse.toByteString());
+ }
+ } catch (Exception e) {
+ logger.error("Error deleting album art", e);
+ AlbumArtMessages.DeleteAlbumArtResponse deleteResponse =
+ AlbumArtMessages.DeleteAlbumArtResponse.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/albumart/GetAlbumArtByIdHandler.java b/src/main/java/com/mediamanager/service/delegate/handler/albumart/GetAlbumArtByIdHandler.java
new file mode 100644
index 0000000..5aa8106
--- /dev/null
+++ b/src/main/java/com/mediamanager/service/delegate/handler/albumart/GetAlbumArtByIdHandler.java
@@ -0,0 +1,56 @@
+package com.mediamanager.service.delegate.handler.albumart;
+
+import com.google.protobuf.ByteString;
+import com.google.protobuf.InvalidProtocolBufferException;
+import com.mediamanager.mapper.AlbumArtMapper;
+import com.mediamanager.model.AlbumArt;
+import com.mediamanager.protocol.TransportProtocol;
+import com.mediamanager.protocol.messages.AlbumArtMessages;
+import com.mediamanager.service.delegate.ActionHandler;
+import com.mediamanager.service.delegate.annotation.Action;
+import com.mediamanager.service.albumart.AlbumArtService;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import java.util.Optional;
+
+@Action(value = "albumart.getById")
+public class GetAlbumArtByIdHandler implements ActionHandler {
+ private static final Logger logger = LogManager.getLogger(GetAlbumArtByIdHandler.class);
+ private final AlbumArtService albumArtService;
+
+ public GetAlbumArtByIdHandler(AlbumArtService albumArtService) {
+ this.albumArtService = albumArtService;
+ }
+
+ @Override
+ public TransportProtocol.Response.Builder handle(ByteString requestPayload)
+ throws InvalidProtocolBufferException{
+
+ try{
+ AlbumArtMessages.GetAlbumArtByIdRequest getByIdRequest =
+ AlbumArtMessages.GetAlbumArtByIdRequest.parseFrom(requestPayload);
+ int id = getByIdRequest.getId();
+
+ Optional albumArtOpt = albumArtService.getAlbumArtById(id);
+
+ if (albumArtOpt.isEmpty()){
+ logger.warn("AlbumArt not found with ID: {}", id);
+ return TransportProtocol.Response.newBuilder()
+ .setStatusCode(404)
+ .setPayload(ByteString.copyFromUtf8("AlbumArt not found"));
+ }
+ AlbumArtMessages.AlbumArt albumArtProto = AlbumArtMapper.toProtobuf(albumArtOpt.get());
+ AlbumArtMessages.GetAlbumArtByIdResponse getByIdResponse = AlbumArtMessages.GetAlbumArtByIdResponse.newBuilder()
+ .setAlbumart(albumArtProto)
+ .build();
+ return TransportProtocol.Response.newBuilder()
+ .setPayload(getByIdResponse.toByteString());
+ } catch (Exception e) {
+ logger.error("Error getting album art 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/albumart/GetAlbumArtHandler.java b/src/main/java/com/mediamanager/service/delegate/handler/albumart/GetAlbumArtHandler.java
new file mode 100644
index 0000000..de85cca
--- /dev/null
+++ b/src/main/java/com/mediamanager/service/delegate/handler/albumart/GetAlbumArtHandler.java
@@ -0,0 +1,48 @@
+package com.mediamanager.service.delegate.handler.albumart;
+
+import com.google.protobuf.ByteString;
+import com.google.protobuf.InvalidProtocolBufferException;
+import com.mediamanager.mapper.AlbumArtMapper;
+import com.mediamanager.model.AlbumArt;
+import com.mediamanager.protocol.TransportProtocol;
+import com.mediamanager.protocol.messages.AlbumArtMessages;
+import com.mediamanager.service.delegate.ActionHandler;
+import com.mediamanager.service.delegate.annotation.Action;
+import com.mediamanager.service.albumart.AlbumArtService;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import java.util.List;
+
+
+@Action("albumart.getAll")
+public class GetAlbumArtHandler implements ActionHandler {
+ private static final Logger logger = LogManager.getLogger(GetAlbumArtHandler.class);
+
+ private final AlbumArtService albumArtService;
+
+ public GetAlbumArtHandler(AlbumArtService albumArtService){this.albumArtService = albumArtService;}
+
+ @Override
+ public TransportProtocol.Response.Builder handle(ByteString requestPayload) throws InvalidProtocolBufferException {
+ try{
+ List albumArts = albumArtService.getAllAlbumArts();
+ AlbumArtMessages.GetAlbumArtsResponse.Builder responseBuilder = AlbumArtMessages.GetAlbumArtsResponse.newBuilder();
+
+ for (AlbumArt albumArt : albumArts) {
+ AlbumArtMessages.AlbumArt albumArtProto = AlbumArtMapper.toProtobuf(albumArt);
+ responseBuilder.addAlbumarts(albumArtProto);
+ }
+ AlbumArtMessages.GetAlbumArtsResponse getAlbumArtsResponse = responseBuilder.build();
+
+ return TransportProtocol.Response.newBuilder()
+ .setPayload(getAlbumArtsResponse.toByteString());
+
+ }catch (Exception e){
+ logger.error("Error getting album arts", e);
+ return TransportProtocol.Response.newBuilder()
+ .setStatusCode(500)
+ .setPayload(ByteString.copyFromUtf8("Error: " + e.getMessage()));
+ }
+ }
+}
diff --git a/src/main/java/com/mediamanager/service/delegate/handler/albumart/UpdateAlbumArtHandler.java b/src/main/java/com/mediamanager/service/delegate/handler/albumart/UpdateAlbumArtHandler.java
new file mode 100644
index 0000000..420d701
--- /dev/null
+++ b/src/main/java/com/mediamanager/service/delegate/handler/albumart/UpdateAlbumArtHandler.java
@@ -0,0 +1,65 @@
+package com.mediamanager.service.delegate.handler.albumart;
+
+import com.google.protobuf.ByteString;
+import com.google.protobuf.InvalidProtocolBufferException;
+import com.mediamanager.mapper.AlbumArtMapper;
+import com.mediamanager.model.AlbumArt;
+import com.mediamanager.protocol.TransportProtocol;
+import com.mediamanager.protocol.messages.AlbumArtMessages;
+import com.mediamanager.service.delegate.ActionHandler;
+import com.mediamanager.service.delegate.annotation.Action;
+import com.mediamanager.service.albumart.AlbumArtService;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import java.util.Optional;
+
+@Action("albumart.update")
+public class UpdateAlbumArtHandler implements ActionHandler {
+ private static final Logger logger = LogManager.getLogger(UpdateAlbumArtHandler.class);
+ private final AlbumArtService albumArtService;
+
+ public UpdateAlbumArtHandler(AlbumArtService albumArtService) {
+ this.albumArtService = albumArtService;
+ }
+
+ @Override
+ public TransportProtocol.Response.Builder handle(ByteString requestPayload) throws InvalidProtocolBufferException {
+ try{
+ AlbumArtMessages.UpdateAlbumArtRequest updateRequest =
+ AlbumArtMessages.UpdateAlbumArtRequest.parseFrom(requestPayload);
+
+ int id = updateRequest.getId();
+ String newFilepath = updateRequest.getFilepath();
+
+ Optional albumArtOpt = albumArtService.updateAlbumArt(id, newFilepath);
+
+ if(albumArtOpt.isEmpty()){
+ logger.warn("AlbumArt not found with ID: {}", id);
+ return TransportProtocol.Response.newBuilder()
+ .setStatusCode(404)
+ .setPayload(ByteString.copyFromUtf8("AlbumArt not found"));
+ }
+
+ AlbumArtMessages.AlbumArt albumArtProto = AlbumArtMapper.toProtobuf(albumArtOpt.get());
+
+ AlbumArtMessages.UpdateAlbumArtResponse updateResponse = AlbumArtMessages.UpdateAlbumArtResponse.newBuilder()
+ .setAlbumart(albumArtProto)
+ .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 album art", 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/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/java/com/mediamanager/service/delegate/handler/albumhasgenre/CreateAlbumHasGenreHandler.java b/src/main/java/com/mediamanager/service/delegate/handler/albumhasgenre/CreateAlbumHasGenreHandler.java
new file mode 100644
index 0000000..4577a46
--- /dev/null
+++ b/src/main/java/com/mediamanager/service/delegate/handler/albumhasgenre/CreateAlbumHasGenreHandler.java
@@ -0,0 +1,54 @@
+package com.mediamanager.service.delegate.handler.albumhasgenre;
+
+import com.google.protobuf.ByteString;
+import com.google.protobuf.InvalidProtocolBufferException;
+import com.mediamanager.mapper.AlbumHasGenreMapper;
+import com.mediamanager.model.AlbumHasGenre;
+import com.mediamanager.protocol.TransportProtocol;
+import com.mediamanager.protocol.messages.AlbumHasGenreMessages;
+import com.mediamanager.service.delegate.ActionHandler;
+import com.mediamanager.service.delegate.annotation.Action;
+import com.mediamanager.service.albumhasgenre.AlbumHasGenreService;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+@Action("albumhasgenre.create")
+public class CreateAlbumHasGenreHandler implements ActionHandler {
+ private static final Logger logger = LogManager.getLogger(CreateAlbumHasGenreHandler.class);
+ private final AlbumHasGenreService albumHasGenreService;
+
+ public CreateAlbumHasGenreHandler(AlbumHasGenreService albumHasGenreService) {
+ this.albumHasGenreService = albumHasGenreService;
+ }
+
+ @Override
+ public TransportProtocol.Response.Builder handle(ByteString requestPayload) throws InvalidProtocolBufferException {
+ try{
+ AlbumHasGenreMessages.CreateAlbumHasGenreRequest createRequest =
+ AlbumHasGenreMessages.CreateAlbumHasGenreRequest.parseFrom(requestPayload);
+
+ AlbumHasGenre albumHasGenre = albumHasGenreService.createAlbumHasGenre(
+ createRequest.getFkAlbumId() > 0 ? createRequest.getFkAlbumId() : null,
+ createRequest.getFkGenreId() > 0 ? createRequest.getFkGenreId() : null
+ );
+
+ AlbumHasGenreMessages.AlbumHasGenre albumHasGenreProto = AlbumHasGenreMapper.toProtobuf(albumHasGenre);
+ AlbumHasGenreMessages.CreateAlbumHasGenreResponse createAlbumHasGenreResponse = AlbumHasGenreMessages.CreateAlbumHasGenreResponse.newBuilder()
+ .setAlbumhasgenre(albumHasGenreProto)
+ .build();
+ return TransportProtocol.Response.newBuilder()
+ .setPayload(createAlbumHasGenreResponse.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 genre", e);
+ return TransportProtocol.Response.newBuilder()
+ .setStatusCode(500)
+ .setPayload(ByteString.copyFromUtf8("Error: " + e.getMessage()));
+ }
+ }
+}
diff --git a/src/main/java/com/mediamanager/service/delegate/handler/albumhasgenre/DeleteAlbumHasGenreHandler.java b/src/main/java/com/mediamanager/service/delegate/handler/albumhasgenre/DeleteAlbumHasGenreHandler.java
new file mode 100644
index 0000000..149cc4c
--- /dev/null
+++ b/src/main/java/com/mediamanager/service/delegate/handler/albumhasgenre/DeleteAlbumHasGenreHandler.java
@@ -0,0 +1,62 @@
+package com.mediamanager.service.delegate.handler.albumhasgenre;
+
+import com.google.protobuf.ByteString;
+import com.google.protobuf.InvalidProtocolBufferException;
+import com.mediamanager.protocol.TransportProtocol;
+import com.mediamanager.protocol.messages.AlbumHasGenreMessages;
+import com.mediamanager.service.delegate.ActionHandler;
+import com.mediamanager.service.delegate.annotation.Action;
+import com.mediamanager.service.albumhasgenre.AlbumHasGenreService;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+@Action("albumhasgenre.delete")
+public class DeleteAlbumHasGenreHandler implements ActionHandler {
+ private static final Logger logger = LogManager.getLogger(DeleteAlbumHasGenreHandler.class);
+
+ private final AlbumHasGenreService albumHasGenreService;
+
+ public DeleteAlbumHasGenreHandler(AlbumHasGenreService albumHasGenreService) {
+ this.albumHasGenreService = albumHasGenreService;
+ }
+
+ @Override
+ public TransportProtocol.Response.Builder handle(ByteString requestPayload)
+ throws InvalidProtocolBufferException {
+
+ try {
+ AlbumHasGenreMessages.DeleteAlbumHasGenreRequest deleteRequest =
+ AlbumHasGenreMessages.DeleteAlbumHasGenreRequest.parseFrom(requestPayload);
+ int id = deleteRequest.getId();
+ boolean success = albumHasGenreService.deleteAlbumHasGenre(id);
+ AlbumHasGenreMessages.DeleteAlbumHasGenreResponse deleteResponse;
+ if (success) {
+ deleteResponse = AlbumHasGenreMessages.DeleteAlbumHasGenreResponse.newBuilder()
+ .setSuccess(true)
+ .setMessage("Album has genre deleted successfully")
+ .build();
+ return TransportProtocol.Response.newBuilder()
+ .setPayload(deleteResponse.toByteString());
+ } else {
+ deleteResponse = AlbumHasGenreMessages.DeleteAlbumHasGenreResponse.newBuilder()
+ .setSuccess(false)
+ .setMessage("Album has genre not found")
+ .build();
+
+ return TransportProtocol.Response.newBuilder()
+ .setStatusCode(404)
+ .setPayload(deleteResponse.toByteString());
+ }
+ } catch (Exception e) {
+ logger.error("Error deleting album has genre", e);
+ AlbumHasGenreMessages.DeleteAlbumHasGenreResponse deleteResponse =
+ AlbumHasGenreMessages.DeleteAlbumHasGenreResponse.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/albumhasgenre/GetAlbumHasGenreByIdHandler.java b/src/main/java/com/mediamanager/service/delegate/handler/albumhasgenre/GetAlbumHasGenreByIdHandler.java
new file mode 100644
index 0000000..a6835c0
--- /dev/null
+++ b/src/main/java/com/mediamanager/service/delegate/handler/albumhasgenre/GetAlbumHasGenreByIdHandler.java
@@ -0,0 +1,56 @@
+package com.mediamanager.service.delegate.handler.albumhasgenre;
+
+import com.google.protobuf.ByteString;
+import com.google.protobuf.InvalidProtocolBufferException;
+import com.mediamanager.mapper.AlbumHasGenreMapper;
+import com.mediamanager.model.AlbumHasGenre;
+import com.mediamanager.protocol.TransportProtocol;
+import com.mediamanager.protocol.messages.AlbumHasGenreMessages;
+import com.mediamanager.service.delegate.ActionHandler;
+import com.mediamanager.service.delegate.annotation.Action;
+import com.mediamanager.service.albumhasgenre.AlbumHasGenreService;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import java.util.Optional;
+
+@Action(value = "albumhasgenre.getById")
+public class GetAlbumHasGenreByIdHandler implements ActionHandler {
+ private static final Logger logger = LogManager.getLogger(GetAlbumHasGenreByIdHandler.class);
+ private final AlbumHasGenreService albumHasGenreService;
+
+ public GetAlbumHasGenreByIdHandler(AlbumHasGenreService albumHasGenreService) {
+ this.albumHasGenreService = albumHasGenreService;
+ }
+
+ @Override
+ public TransportProtocol.Response.Builder handle(ByteString requestPayload)
+ throws InvalidProtocolBufferException{
+
+ try{
+ AlbumHasGenreMessages.GetAlbumHasGenreByIdRequest getByIdRequest =
+ AlbumHasGenreMessages.GetAlbumHasGenreByIdRequest.parseFrom(requestPayload);
+ int id = getByIdRequest.getId();
+
+ Optional albumHasGenreOpt = albumHasGenreService.getAlbumHasGenreById(id);
+
+ if (albumHasGenreOpt.isEmpty()){
+ logger.warn("AlbumHasGenre not found with ID: {}", id);
+ return TransportProtocol.Response.newBuilder()
+ .setStatusCode(404)
+ .setPayload(ByteString.copyFromUtf8("AlbumHasGenre not found"));
+ }
+ AlbumHasGenreMessages.AlbumHasGenre albumHasGenreProto = AlbumHasGenreMapper.toProtobuf(albumHasGenreOpt.get());
+ AlbumHasGenreMessages.GetAlbumHasGenreByIdResponse getByIdResponse = AlbumHasGenreMessages.GetAlbumHasGenreByIdResponse.newBuilder()
+ .setAlbumhasgenre(albumHasGenreProto)
+ .build();
+ return TransportProtocol.Response.newBuilder()
+ .setPayload(getByIdResponse.toByteString());
+ } catch (Exception e) {
+ logger.error("Error getting album has genre 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/albumhasgenre/GetAlbumHasGenreHandler.java b/src/main/java/com/mediamanager/service/delegate/handler/albumhasgenre/GetAlbumHasGenreHandler.java
new file mode 100644
index 0000000..d90dcc1
--- /dev/null
+++ b/src/main/java/com/mediamanager/service/delegate/handler/albumhasgenre/GetAlbumHasGenreHandler.java
@@ -0,0 +1,48 @@
+package com.mediamanager.service.delegate.handler.albumhasgenre;
+
+import com.google.protobuf.ByteString;
+import com.google.protobuf.InvalidProtocolBufferException;
+import com.mediamanager.mapper.AlbumHasGenreMapper;
+import com.mediamanager.model.AlbumHasGenre;
+import com.mediamanager.protocol.TransportProtocol;
+import com.mediamanager.protocol.messages.AlbumHasGenreMessages;
+import com.mediamanager.service.delegate.ActionHandler;
+import com.mediamanager.service.delegate.annotation.Action;
+import com.mediamanager.service.albumhasgenre.AlbumHasGenreService;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import java.util.List;
+
+
+@Action("albumhasgenre.getAll")
+public class GetAlbumHasGenreHandler implements ActionHandler {
+ private static final Logger logger = LogManager.getLogger(GetAlbumHasGenreHandler.class);
+
+ private final AlbumHasGenreService albumHasGenreService;
+
+ public GetAlbumHasGenreHandler(AlbumHasGenreService albumHasGenreService){this.albumHasGenreService = albumHasGenreService;}
+
+ @Override
+ public TransportProtocol.Response.Builder handle(ByteString requestPayload) throws InvalidProtocolBufferException {
+ try{
+ List albumHasGenres = albumHasGenreService.getAllAlbumHasGenres();
+ AlbumHasGenreMessages.GetAlbumHasGenresResponse.Builder responseBuilder = AlbumHasGenreMessages.GetAlbumHasGenresResponse.newBuilder();
+
+ for (AlbumHasGenre albumHasGenre : albumHasGenres) {
+ AlbumHasGenreMessages.AlbumHasGenre albumHasGenreProto = AlbumHasGenreMapper.toProtobuf(albumHasGenre);
+ responseBuilder.addAlbumhasgenre(albumHasGenreProto);
+ }
+ AlbumHasGenreMessages.GetAlbumHasGenresResponse getAlbumHasGenresResponse = responseBuilder.build();
+
+ return TransportProtocol.Response.newBuilder()
+ .setPayload(getAlbumHasGenresResponse.toByteString());
+
+ }catch (Exception e){
+ logger.error("Error getting album has genres", e);
+ return TransportProtocol.Response.newBuilder()
+ .setStatusCode(500)
+ .setPayload(ByteString.copyFromUtf8("Error: " + e.getMessage()));
+ }
+ }
+}
diff --git a/src/main/java/com/mediamanager/service/delegate/handler/albumtype/CreateAlbumTypeHandler.java b/src/main/java/com/mediamanager/service/delegate/handler/albumtype/CreateAlbumTypeHandler.java
new file mode 100644
index 0000000..774f559
--- /dev/null
+++ b/src/main/java/com/mediamanager/service/delegate/handler/albumtype/CreateAlbumTypeHandler.java
@@ -0,0 +1,49 @@
+package com.mediamanager.service.delegate.handler.albumtype;
+
+import com.google.protobuf.ByteString;
+import com.google.protobuf.InvalidProtocolBufferException;
+import com.mediamanager.mapper.AlbumTypeMapper;
+import com.mediamanager.model.AlbumType;
+import com.mediamanager.protocol.TransportProtocol;
+import com.mediamanager.protocol.messages.AlbumTypeMessages;
+import com.mediamanager.service.delegate.ActionHandler;
+import com.mediamanager.service.delegate.annotation.Action;
+import com.mediamanager.service.albumtype.AlbumTypeService;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+@Action("albumtype.create")
+public class CreateAlbumTypeHandler implements ActionHandler {
+ private static final Logger logger = LogManager.getLogger(CreateAlbumTypeHandler.class);
+ private final AlbumTypeService albumTypeService;
+
+ public CreateAlbumTypeHandler(AlbumTypeService albumTypeService) {
+ this.albumTypeService = albumTypeService;
+ }
+
+ @Override
+ public TransportProtocol.Response.Builder handle(ByteString requestPayload) throws InvalidProtocolBufferException {
+ try{
+ AlbumTypeMessages.CreateAlbumTypeRequest createRequest =
+ AlbumTypeMessages.CreateAlbumTypeRequest.parseFrom(requestPayload);
+ AlbumType albumType = albumTypeService.createAlbumType(createRequest.getValue());
+ AlbumTypeMessages.AlbumType albumTypeProto = AlbumTypeMapper.toProtobuf(albumType);
+ AlbumTypeMessages.CreateAlbumTypeResponse createAlbumTypeResponse = AlbumTypeMessages.CreateAlbumTypeResponse.newBuilder()
+ .setAlbumtype(albumTypeProto)
+ .build();
+ return TransportProtocol.Response.newBuilder()
+ .setPayload(createAlbumTypeResponse.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 type", e);
+ return TransportProtocol.Response.newBuilder()
+ .setStatusCode(500)
+ .setPayload(ByteString.copyFromUtf8("Error: " + e.getMessage()));
+ }
+ }
+}
diff --git a/src/main/java/com/mediamanager/service/delegate/handler/albumtype/DeleteAlbumTypeHandler.java b/src/main/java/com/mediamanager/service/delegate/handler/albumtype/DeleteAlbumTypeHandler.java
new file mode 100644
index 0000000..9ce400d
--- /dev/null
+++ b/src/main/java/com/mediamanager/service/delegate/handler/albumtype/DeleteAlbumTypeHandler.java
@@ -0,0 +1,62 @@
+package com.mediamanager.service.delegate.handler.albumtype;
+
+import com.google.protobuf.ByteString;
+import com.google.protobuf.InvalidProtocolBufferException;
+import com.mediamanager.protocol.TransportProtocol;
+import com.mediamanager.protocol.messages.AlbumTypeMessages;
+import com.mediamanager.service.delegate.ActionHandler;
+import com.mediamanager.service.delegate.annotation.Action;
+import com.mediamanager.service.albumtype.AlbumTypeService;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+@Action("albumtype.delete")
+public class DeleteAlbumTypeHandler implements ActionHandler {
+ private static final Logger logger = LogManager.getLogger(DeleteAlbumTypeHandler.class);
+
+ private final AlbumTypeService albumTypeService;
+
+ public DeleteAlbumTypeHandler(AlbumTypeService albumTypeService) {
+ this.albumTypeService = albumTypeService;
+ }
+
+ @Override
+ public TransportProtocol.Response.Builder handle(ByteString requestPayload)
+ throws InvalidProtocolBufferException {
+
+ try {
+ AlbumTypeMessages.DeleteAlbumTypeRequest deleteRequest =
+ AlbumTypeMessages.DeleteAlbumTypeRequest.parseFrom(requestPayload);
+ int id = deleteRequest.getId();
+ boolean success = albumTypeService.deleteAlbumType(id);
+ AlbumTypeMessages.DeleteAlbumTypeResponse deleteResponse;
+ if (success) {
+ deleteResponse = AlbumTypeMessages.DeleteAlbumTypeResponse.newBuilder()
+ .setSuccess(true)
+ .setMessage("Album type deleted successfully")
+ .build();
+ return TransportProtocol.Response.newBuilder()
+ .setPayload(deleteResponse.toByteString());
+ } else {
+ deleteResponse = AlbumTypeMessages.DeleteAlbumTypeResponse.newBuilder()
+ .setSuccess(false)
+ .setMessage("Album type not found")
+ .build();
+
+ return TransportProtocol.Response.newBuilder()
+ .setStatusCode(404)
+ .setPayload(deleteResponse.toByteString());
+ }
+ } catch (Exception e) {
+ logger.error("Error deleting album type", e);
+ AlbumTypeMessages.DeleteAlbumTypeResponse deleteResponse =
+ AlbumTypeMessages.DeleteAlbumTypeResponse.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/albumtype/GetAlbumTypeByIdHandler.java b/src/main/java/com/mediamanager/service/delegate/handler/albumtype/GetAlbumTypeByIdHandler.java
new file mode 100644
index 0000000..85a0775
--- /dev/null
+++ b/src/main/java/com/mediamanager/service/delegate/handler/albumtype/GetAlbumTypeByIdHandler.java
@@ -0,0 +1,56 @@
+package com.mediamanager.service.delegate.handler.albumtype;
+
+import com.google.protobuf.ByteString;
+import com.google.protobuf.InvalidProtocolBufferException;
+import com.mediamanager.mapper.AlbumTypeMapper;
+import com.mediamanager.model.AlbumType;
+import com.mediamanager.protocol.TransportProtocol;
+import com.mediamanager.protocol.messages.AlbumTypeMessages;
+import com.mediamanager.service.delegate.ActionHandler;
+import com.mediamanager.service.delegate.annotation.Action;
+import com.mediamanager.service.albumtype.AlbumTypeService;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import java.util.Optional;
+
+@Action(value = "albumtype.getById")
+public class GetAlbumTypeByIdHandler implements ActionHandler {
+ private static final Logger logger = LogManager.getLogger(GetAlbumTypeByIdHandler.class);
+ private final AlbumTypeService albumTypeService;
+
+ public GetAlbumTypeByIdHandler(AlbumTypeService albumTypeService) {
+ this.albumTypeService = albumTypeService;
+ }
+
+ @Override
+ public TransportProtocol.Response.Builder handle(ByteString requestPayload)
+ throws InvalidProtocolBufferException{
+
+ try{
+ AlbumTypeMessages.GetAlbumTypeByIdRequest getByIdRequest =
+ AlbumTypeMessages.GetAlbumTypeByIdRequest.parseFrom(requestPayload);
+ int id = getByIdRequest.getId();
+
+ Optional albumTypeOpt = albumTypeService.getAlbumTypeById(id);
+
+ if (albumTypeOpt.isEmpty()){
+ logger.warn("AlbumType not found with ID: {}", id);
+ return TransportProtocol.Response.newBuilder()
+ .setStatusCode(404)
+ .setPayload(ByteString.copyFromUtf8("AlbumType not found"));
+ }
+ AlbumTypeMessages.AlbumType albumTypeProto = AlbumTypeMapper.toProtobuf(albumTypeOpt.get());
+ AlbumTypeMessages.GetAlbumTypeByIdResponse getByIdResponse = AlbumTypeMessages.GetAlbumTypeByIdResponse.newBuilder()
+ .setAlbumtype(albumTypeProto)
+ .build();
+ return TransportProtocol.Response.newBuilder()
+ .setPayload(getByIdResponse.toByteString());
+ } catch (Exception e) {
+ logger.error("Error getting album type 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/albumtype/GetAlbumTypeHandler.java b/src/main/java/com/mediamanager/service/delegate/handler/albumtype/GetAlbumTypeHandler.java
new file mode 100644
index 0000000..b886107
--- /dev/null
+++ b/src/main/java/com/mediamanager/service/delegate/handler/albumtype/GetAlbumTypeHandler.java
@@ -0,0 +1,48 @@
+package com.mediamanager.service.delegate.handler.albumtype;
+
+import com.google.protobuf.ByteString;
+import com.google.protobuf.InvalidProtocolBufferException;
+import com.mediamanager.mapper.AlbumTypeMapper;
+import com.mediamanager.model.AlbumType;
+import com.mediamanager.protocol.TransportProtocol;
+import com.mediamanager.protocol.messages.AlbumTypeMessages;
+import com.mediamanager.service.delegate.ActionHandler;
+import com.mediamanager.service.delegate.annotation.Action;
+import com.mediamanager.service.albumtype.AlbumTypeService;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import java.util.List;
+
+
+@Action("albumtype.getAll")
+public class GetAlbumTypeHandler implements ActionHandler {
+ private static final Logger logger = LogManager.getLogger(GetAlbumTypeHandler.class);
+
+ private final AlbumTypeService albumTypeService;
+
+ public GetAlbumTypeHandler(AlbumTypeService albumTypeService){this.albumTypeService = albumTypeService;}
+
+ @Override
+ public TransportProtocol.Response.Builder handle(ByteString requestPayload) throws InvalidProtocolBufferException {
+ try{
+ List albumTypes = albumTypeService.getAllAlbumTypes();
+ AlbumTypeMessages.GetAlbumTypesResponse.Builder responseBuilder = AlbumTypeMessages.GetAlbumTypesResponse.newBuilder();
+
+ for (AlbumType albumType : albumTypes) {
+ AlbumTypeMessages.AlbumType albumTypeProto = AlbumTypeMapper.toProtobuf(albumType);
+ responseBuilder.addAlbumtypes(albumTypeProto);
+ }
+ AlbumTypeMessages.GetAlbumTypesResponse getAlbumTypesResponse = responseBuilder.build();
+
+ return TransportProtocol.Response.newBuilder()
+ .setPayload(getAlbumTypesResponse.toByteString());
+
+ }catch (Exception e){
+ logger.error("Error getting album types", e);
+ return TransportProtocol.Response.newBuilder()
+ .setStatusCode(500)
+ .setPayload(ByteString.copyFromUtf8("Error: " + e.getMessage()));
+ }
+ }
+}
diff --git a/src/main/java/com/mediamanager/service/delegate/handler/albumtype/UpdateAlbumTypeHandler.java b/src/main/java/com/mediamanager/service/delegate/handler/albumtype/UpdateAlbumTypeHandler.java
new file mode 100644
index 0000000..50f70ed
--- /dev/null
+++ b/src/main/java/com/mediamanager/service/delegate/handler/albumtype/UpdateAlbumTypeHandler.java
@@ -0,0 +1,65 @@
+package com.mediamanager.service.delegate.handler.albumtype;
+
+import com.google.protobuf.ByteString;
+import com.google.protobuf.InvalidProtocolBufferException;
+import com.mediamanager.mapper.AlbumTypeMapper;
+import com.mediamanager.model.AlbumType;
+import com.mediamanager.protocol.TransportProtocol;
+import com.mediamanager.protocol.messages.AlbumTypeMessages;
+import com.mediamanager.service.delegate.ActionHandler;
+import com.mediamanager.service.delegate.annotation.Action;
+import com.mediamanager.service.albumtype.AlbumTypeService;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import java.util.Optional;
+
+@Action("albumtype.update")
+public class UpdateAlbumTypeHandler implements ActionHandler {
+ private static final Logger logger = LogManager.getLogger(UpdateAlbumTypeHandler.class);
+ private final AlbumTypeService albumTypeService;
+
+ public UpdateAlbumTypeHandler(AlbumTypeService albumTypeService) {
+ this.albumTypeService = albumTypeService;
+ }
+
+ @Override
+ public TransportProtocol.Response.Builder handle(ByteString requestPayload) throws InvalidProtocolBufferException {
+ try{
+ AlbumTypeMessages.UpdateAlbumTypeRequest updateRequest =
+ AlbumTypeMessages.UpdateAlbumTypeRequest.parseFrom(requestPayload);
+
+ int id = updateRequest.getId();
+ String newValue = updateRequest.getValue();
+
+ Optional albumTypeOpt = albumTypeService.updateAlbumType(id, newValue);
+
+ if(albumTypeOpt.isEmpty()){
+ logger.warn("AlbumType not found with ID: {}", id);
+ return TransportProtocol.Response.newBuilder()
+ .setStatusCode(404)
+ .setPayload(ByteString.copyFromUtf8("AlbumType not found"));
+ }
+
+ AlbumTypeMessages.AlbumType albumTypeProto = AlbumTypeMapper.toProtobuf(albumTypeOpt.get());
+
+ AlbumTypeMessages.UpdateAlbumTypeResponse updateResponse = AlbumTypeMessages.UpdateAlbumTypeResponse.newBuilder()
+ .setAlbumtype(albumTypeProto)
+ .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 album type", e);
+ return TransportProtocol.Response.newBuilder()
+ .setStatusCode(500)
+ .setPayload(ByteString.copyFromUtf8("Error: " + e.getMessage()));
+ }
+ }
+}
diff --git a/src/main/java/com/mediamanager/service/delegate/handler/artist/CreateArtistHandler.java b/src/main/java/com/mediamanager/service/delegate/handler/artist/CreateArtistHandler.java
new file mode 100644
index 0000000..268a4bd
--- /dev/null
+++ b/src/main/java/com/mediamanager/service/delegate/handler/artist/CreateArtistHandler.java
@@ -0,0 +1,50 @@
+package com.mediamanager.service.delegate.handler.artist;
+
+import com.google.protobuf.ByteString;
+import com.google.protobuf.InvalidProtocolBufferException;
+import com.mediamanager.mapper.ArtistMapper;
+import com.mediamanager.model.Artist;
+import com.mediamanager.protocol.TransportProtocol;
+import com.mediamanager.protocol.messages.ArtistMessages;
+import com.mediamanager.service.artist.ArtistService;
+import com.mediamanager.service.delegate.ActionHandler;
+import com.mediamanager.service.delegate.annotation.Action;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+@Action("artist.create")
+public class CreateArtistHandler implements ActionHandler {
+ private static final Logger logger = LogManager.getLogger(CreateArtistHandler.class);
+ private final ArtistService artistService;
+
+ public CreateArtistHandler(ArtistService artistService) {
+ this.artistService = artistService;
+ }
+
+ @Override
+ public TransportProtocol.Response.Builder handle(ByteString requestPayload) throws InvalidProtocolBufferException {
+ try{
+ ArtistMessages.CreateArtistRequest createRequest =
+ ArtistMessages.CreateArtistRequest.parseFrom(requestPayload);
+ Artist artist = artistService.createArtist(createRequest.getName());
+ ArtistMessages.Artist artistProto = ArtistMapper.toProtobuf(artist);
+ ArtistMessages.CreateArtistResponse createArtistResponse = ArtistMessages.CreateArtistResponse.newBuilder()
+ .setArtist(artistProto)
+ .build();
+ return TransportProtocol.Response.newBuilder()
+ .setPayload(createArtistResponse.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 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/artist/DeleteArtistHandler.java b/src/main/java/com/mediamanager/service/delegate/handler/artist/DeleteArtistHandler.java
new file mode 100644
index 0000000..a3d3c72
--- /dev/null
+++ b/src/main/java/com/mediamanager/service/delegate/handler/artist/DeleteArtistHandler.java
@@ -0,0 +1,62 @@
+package com.mediamanager.service.delegate.handler.artist;
+
+import com.google.protobuf.ByteString;
+import com.google.protobuf.InvalidProtocolBufferException;
+import com.mediamanager.protocol.TransportProtocol;
+import com.mediamanager.protocol.messages.ArtistMessages;
+import com.mediamanager.service.artist.ArtistService;
+import com.mediamanager.service.delegate.ActionHandler;
+import com.mediamanager.service.delegate.annotation.Action;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+@Action("artist.delete")
+public class DeleteArtistHandler implements ActionHandler {
+ private static final Logger logger = LogManager.getLogger(DeleteArtistHandler.class);
+
+ private final ArtistService artistService;
+
+ public DeleteArtistHandler(ArtistService artistService) {
+ this.artistService = artistService;
+ }
+
+ @Override
+ public TransportProtocol.Response.Builder handle(ByteString requestPayload)
+ throws InvalidProtocolBufferException {
+
+ try {
+ ArtistMessages.DeleteArtistRequest deleteRequest =
+ ArtistMessages.DeleteArtistRequest.parseFrom(requestPayload);
+ int id = deleteRequest.getId();
+ boolean success = artistService.deleteArtist(id);
+ ArtistMessages.DeleteArtistResponse deleteResponse;
+ if (success) {
+ deleteResponse = ArtistMessages.DeleteArtistResponse.newBuilder()
+ .setSuccess(true)
+ .setMessage("Artist deleted successfully")
+ .build();
+ return TransportProtocol.Response.newBuilder()
+ .setPayload(deleteResponse.toByteString());
+ } else {
+ deleteResponse = ArtistMessages.DeleteArtistResponse.newBuilder()
+ .setSuccess(false)
+ .setMessage("Artist not found")
+ .build();
+
+ return TransportProtocol.Response.newBuilder()
+ .setStatusCode(404)
+ .setPayload(deleteResponse.toByteString());
+ }
+ } catch (Exception e) {
+ logger.error("Error deleting artist", e);
+ ArtistMessages.DeleteArtistResponse deleteResponse =
+ ArtistMessages.DeleteArtistResponse.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/artist/GetArtistByIdHandler.java b/src/main/java/com/mediamanager/service/delegate/handler/artist/GetArtistByIdHandler.java
new file mode 100644
index 0000000..d98b48e
--- /dev/null
+++ b/src/main/java/com/mediamanager/service/delegate/handler/artist/GetArtistByIdHandler.java
@@ -0,0 +1,56 @@
+package com.mediamanager.service.delegate.handler.artist;
+
+import com.google.protobuf.ByteString;
+import com.google.protobuf.InvalidProtocolBufferException;
+import com.mediamanager.mapper.ArtistMapper;
+import com.mediamanager.model.Artist;
+import com.mediamanager.protocol.TransportProtocol;
+import com.mediamanager.protocol.messages.ArtistMessages;
+import com.mediamanager.service.artist.ArtistService;
+import com.mediamanager.service.delegate.ActionHandler;
+import com.mediamanager.service.delegate.annotation.Action;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import java.util.Optional;
+
+@Action(value = "artist.getById")
+public class GetArtistByIdHandler implements ActionHandler {
+ private static final Logger logger = LogManager.getLogger(GetArtistByIdHandler.class);
+ private final ArtistService artistService;
+
+ public GetArtistByIdHandler(ArtistService artistService) {
+ this.artistService = artistService;
+ }
+
+ @Override
+ public TransportProtocol.Response.Builder handle(ByteString requestPayload)
+ throws InvalidProtocolBufferException{
+
+ try{
+ ArtistMessages.GetArtistByIdRequest getByIdRequest =
+ ArtistMessages.GetArtistByIdRequest.parseFrom(requestPayload);
+ int id = getByIdRequest.getId();
+
+ Optional artistOpt = artistService.getArtistById(id);
+
+ if (artistOpt.isEmpty()){
+ logger.warn("Artist not found with ID: {}", id);
+ return TransportProtocol.Response.newBuilder()
+ .setStatusCode(404)
+ .setPayload(ByteString.copyFromUtf8("Artist not found"));
+ }
+ ArtistMessages.Artist artistProto = ArtistMapper.toProtobuf(artistOpt.get());
+ ArtistMessages.GetArtistByIdResponse getByIdResponse = ArtistMessages.GetArtistByIdResponse.newBuilder()
+ .setArtist(artistProto)
+ .build();
+ return TransportProtocol.Response.newBuilder()
+ .setPayload(getByIdResponse.toByteString());
+ } catch (Exception e) {
+ logger.error("Error getting 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/artist/GetArtistHandler.java b/src/main/java/com/mediamanager/service/delegate/handler/artist/GetArtistHandler.java
new file mode 100644
index 0000000..bf91fff
--- /dev/null
+++ b/src/main/java/com/mediamanager/service/delegate/handler/artist/GetArtistHandler.java
@@ -0,0 +1,48 @@
+package com.mediamanager.service.delegate.handler.artist;
+
+import com.google.protobuf.ByteString;
+import com.google.protobuf.InvalidProtocolBufferException;
+import com.mediamanager.mapper.ArtistMapper;
+import com.mediamanager.model.Artist;
+import com.mediamanager.protocol.TransportProtocol;
+import com.mediamanager.protocol.messages.ArtistMessages;
+import com.mediamanager.service.artist.ArtistService;
+import com.mediamanager.service.delegate.ActionHandler;
+import com.mediamanager.service.delegate.annotation.Action;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import java.util.List;
+
+
+@Action("artist.getAll")
+public class GetArtistHandler implements ActionHandler {
+ private static final Logger logger = LogManager.getLogger(GetArtistHandler.class);
+
+ private final ArtistService artistService;
+
+ public GetArtistHandler(ArtistService artistService){this.artistService = artistService;}
+
+ @Override
+ public TransportProtocol.Response.Builder handle(ByteString requestPayload) throws InvalidProtocolBufferException {
+ try{
+ List artists = artistService.getAllArtists();
+ ArtistMessages.GetArtistsResponse.Builder responseBuilder = ArtistMessages.GetArtistsResponse.newBuilder();
+
+ for (Artist artist : artists) {
+ ArtistMessages.Artist artistProto = ArtistMapper.toProtobuf(artist);
+ responseBuilder.addArtists(artistProto);
+ }
+ ArtistMessages.GetArtistsResponse getArtistsResponse = responseBuilder.build();
+
+ return TransportProtocol.Response.newBuilder()
+ .setPayload(getArtistsResponse.toByteString());
+
+ }catch (Exception e){
+ logger.error("Error getting artists", e);
+ return TransportProtocol.Response.newBuilder()
+ .setStatusCode(500)
+ .setPayload(ByteString.copyFromUtf8("Error: " + e.getMessage()));
+ }
+ }
+}
diff --git a/src/main/java/com/mediamanager/service/delegate/handler/artist/UpdateArtistHandler.java b/src/main/java/com/mediamanager/service/delegate/handler/artist/UpdateArtistHandler.java
new file mode 100644
index 0000000..69c3cd6
--- /dev/null
+++ b/src/main/java/com/mediamanager/service/delegate/handler/artist/UpdateArtistHandler.java
@@ -0,0 +1,65 @@
+package com.mediamanager.service.delegate.handler.artist;
+
+import com.google.protobuf.ByteString;
+import com.google.protobuf.InvalidProtocolBufferException;
+import com.mediamanager.mapper.ArtistMapper;
+import com.mediamanager.model.Artist;
+import com.mediamanager.protocol.TransportProtocol;
+import com.mediamanager.protocol.messages.ArtistMessages;
+import com.mediamanager.service.artist.ArtistService;
+import com.mediamanager.service.delegate.ActionHandler;
+import com.mediamanager.service.delegate.annotation.Action;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import java.util.Optional;
+
+@Action("artist.update")
+public class UpdateArtistHandler implements ActionHandler {
+ private static final Logger logger = LogManager.getLogger(UpdateArtistHandler.class);
+ private final ArtistService artistService;
+
+ public UpdateArtistHandler(ArtistService artistService) {
+ this.artistService = artistService;
+ }
+
+ @Override
+ public TransportProtocol.Response.Builder handle(ByteString requestPayload) throws InvalidProtocolBufferException {
+ try{
+ ArtistMessages.UpdateArtistRequest updateRequest =
+ ArtistMessages.UpdateArtistRequest.parseFrom(requestPayload);
+
+ int id = updateRequest.getId();
+ String newName = updateRequest.getName();
+
+ Optional artistOpt = artistService.updateArtist(id, newName);
+
+ if(artistOpt.isEmpty()){
+ logger.warn("Artist not found with ID: {}", id);
+ return TransportProtocol.Response.newBuilder()
+ .setStatusCode(404)
+ .setPayload(ByteString.copyFromUtf8("Artist not found"));
+ }
+
+ ArtistMessages.Artist artistProto = ArtistMapper.toProtobuf(artistOpt.get());
+
+ ArtistMessages.UpdateArtistResponse updateResponse = ArtistMessages.UpdateArtistResponse.newBuilder()
+ .setArtist(artistProto)
+ .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 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/bitdepth/CreateBitDepthHandler.java b/src/main/java/com/mediamanager/service/delegate/handler/bitdepth/CreateBitDepthHandler.java
new file mode 100644
index 0000000..db9e034
--- /dev/null
+++ b/src/main/java/com/mediamanager/service/delegate/handler/bitdepth/CreateBitDepthHandler.java
@@ -0,0 +1,51 @@
+package com.mediamanager.service.delegate.handler.bitdepth;
+
+import com.google.protobuf.ByteString;
+import com.google.protobuf.InvalidProtocolBufferException;
+import com.mediamanager.mapper.BitDepthMapper;
+import com.mediamanager.model.BitDepth;
+import com.mediamanager.protocol.TransportProtocol;
+import com.mediamanager.protocol.messages.ArtistMessages;
+import com.mediamanager.protocol.messages.BitDepthMessages;
+import com.mediamanager.service.bitdepth.BitDepthService;
+import com.mediamanager.service.delegate.ActionHandler;
+import com.mediamanager.service.delegate.annotation.Action;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+@Action("bitdepth.create")
+public class CreateBitDepthHandler implements ActionHandler {
+ private static final Logger logger = LogManager.getLogger(CreateBitDepthHandler.class);
+ private final BitDepthService bitDepthService;
+
+ public CreateBitDepthHandler(BitDepthService bitDepthService) {
+ this.bitDepthService = bitDepthService;
+ }
+
+ @Override
+ public TransportProtocol.Response.Builder handle(ByteString requestPayload) throws InvalidProtocolBufferException {
+ try{
+ BitDepthMessages.CreateBitDepthRequest createRequest =
+ BitDepthMessages.CreateBitDepthRequest.parseFrom(requestPayload);
+ BitDepth bitDepth = bitDepthService.createBitDepth(createRequest.getValue());
+ BitDepthMessages.BitDepth BitDepthProto = BitDepthMapper.toProtobuf(bitDepth);
+ BitDepthMessages.CreateBitDepthResponse createBitDepthResponse = BitDepthMessages.CreateBitDepthResponse.newBuilder()
+ .setBitdepth(BitDepthProto)
+ .build();
+ return TransportProtocol.Response.newBuilder()
+ .setPayload(createBitDepthResponse.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 bit-depth", e);
+ return TransportProtocol.Response.newBuilder()
+ .setStatusCode(500)
+ .setPayload(ByteString.copyFromUtf8("Error: " + e.getMessage()));
+ }
+ }
+}
+
diff --git a/src/main/java/com/mediamanager/service/delegate/handler/bitdepth/DeleteBitDepthHandler.java b/src/main/java/com/mediamanager/service/delegate/handler/bitdepth/DeleteBitDepthHandler.java
new file mode 100644
index 0000000..b71a9a1
--- /dev/null
+++ b/src/main/java/com/mediamanager/service/delegate/handler/bitdepth/DeleteBitDepthHandler.java
@@ -0,0 +1,62 @@
+package com.mediamanager.service.delegate.handler.bitdepth;
+
+import com.google.protobuf.ByteString;
+import com.google.protobuf.InvalidProtocolBufferException;
+import com.mediamanager.protocol.TransportProtocol;
+import com.mediamanager.protocol.messages.BitDepthMessages;
+import com.mediamanager.service.bitdepth.BitDepthService;
+import com.mediamanager.service.delegate.ActionHandler;
+import com.mediamanager.service.delegate.annotation.Action;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+@Action("bitdepth.delete")
+public class DeleteBitDepthHandler implements ActionHandler {
+ private static final Logger logger = LogManager.getLogger(DeleteBitDepthHandler.class);
+
+ private final BitDepthService bitDepthService;
+
+ public DeleteBitDepthHandler(BitDepthService bitDepthService) {
+ this.bitDepthService = bitDepthService;
+ }
+
+ @Override
+ public TransportProtocol.Response.Builder handle(ByteString requestPayload)
+ throws InvalidProtocolBufferException {
+
+ try {
+ BitDepthMessages.DeleteBitDepthRequest deleteRequest =
+ BitDepthMessages.DeleteBitDepthRequest.parseFrom(requestPayload);
+ int id = deleteRequest.getId();
+ boolean success = bitDepthService.deleteBitDepth(id);
+ BitDepthMessages.DeleteBitDepthResponse deleteResponse;
+ if (success) {
+ deleteResponse = BitDepthMessages.DeleteBitDepthResponse.newBuilder()
+ .setSuccess(true)
+ .setMessage("Bit-Depth deleted successfully")
+ .build();
+ return TransportProtocol.Response.newBuilder()
+ .setPayload(deleteResponse.toByteString());
+ } else {
+ deleteResponse = BitDepthMessages.DeleteBitDepthResponse.newBuilder()
+ .setSuccess(false)
+ .setMessage("Bit-Depth not found")
+ .build();
+
+ return TransportProtocol.Response.newBuilder()
+ .setStatusCode(404)
+ .setPayload(deleteResponse.toByteString());
+ }
+ } catch (Exception e) {
+ logger.error("Error deleting bit-depth", e);
+ BitDepthMessages.DeleteBitDepthResponse deleteResponse =
+ BitDepthMessages.DeleteBitDepthResponse.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/bitdepth/GetBitDepthByIdHandler.java b/src/main/java/com/mediamanager/service/delegate/handler/bitdepth/GetBitDepthByIdHandler.java
new file mode 100644
index 0000000..96e630d
--- /dev/null
+++ b/src/main/java/com/mediamanager/service/delegate/handler/bitdepth/GetBitDepthByIdHandler.java
@@ -0,0 +1,56 @@
+package com.mediamanager.service.delegate.handler.bitdepth;
+
+import com.google.protobuf.ByteString;
+import com.google.protobuf.InvalidProtocolBufferException;
+import com.mediamanager.mapper.BitDepthMapper;
+import com.mediamanager.model.BitDepth;
+import com.mediamanager.protocol.TransportProtocol;
+import com.mediamanager.protocol.messages.BitDepthMessages;
+import com.mediamanager.service.bitdepth.BitDepthService;
+import com.mediamanager.service.delegate.ActionHandler;
+import com.mediamanager.service.delegate.annotation.Action;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import java.util.Optional;
+
+@Action(value = "bitdepth.getById")
+public class GetBitDepthByIdHandler implements ActionHandler {
+ private static final Logger logger = LogManager.getLogger(GetBitDepthByIdHandler.class);
+ private final BitDepthService bitDepthServicee;
+
+ public GetBitDepthByIdHandler(BitDepthService bitDepthServicee) {
+ this.bitDepthServicee = bitDepthServicee;
+ }
+
+ @Override
+ public TransportProtocol.Response.Builder handle(ByteString requestPayload)
+ throws InvalidProtocolBufferException{
+
+ try{
+ BitDepthMessages.GetBitDepthByIdRequest getByIdRequest =
+ BitDepthMessages.GetBitDepthByIdRequest.parseFrom(requestPayload);
+ int id = getByIdRequest.getId();
+
+ Optional bitDepthOpt = bitDepthServicee.getBitDepthById(id);
+
+ if (bitDepthOpt.isEmpty()){
+ logger.warn("BitDepth not found with ID: {}", id);
+ return TransportProtocol.Response.newBuilder()
+ .setStatusCode(404)
+ .setPayload(ByteString.copyFromUtf8("BitDepth not found"));
+ }
+ BitDepthMessages.BitDepth bitDepthProto = BitDepthMapper.toProtobuf(bitDepthOpt.get());
+ BitDepthMessages.GetBitDepthByIdResponse getByIdResponse = BitDepthMessages.GetBitDepthByIdResponse.newBuilder()
+ .setBitdepth(bitDepthProto)
+ .build();
+ return TransportProtocol.Response.newBuilder()
+ .setPayload(getByIdResponse.toByteString());
+ } catch (Exception e) {
+ logger.error("Error getting bit-depth 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/bitdepth/GetBitDepthHandler.java b/src/main/java/com/mediamanager/service/delegate/handler/bitdepth/GetBitDepthHandler.java
new file mode 100644
index 0000000..71cf92f
--- /dev/null
+++ b/src/main/java/com/mediamanager/service/delegate/handler/bitdepth/GetBitDepthHandler.java
@@ -0,0 +1,48 @@
+package com.mediamanager.service.delegate.handler.bitdepth;
+
+import com.google.protobuf.ByteString;
+import com.google.protobuf.InvalidProtocolBufferException;
+import com.mediamanager.mapper.BitDepthMapper;
+import com.mediamanager.model.BitDepth;
+import com.mediamanager.protocol.TransportProtocol;
+import com.mediamanager.protocol.messages.BitDepthMessages;
+import com.mediamanager.service.bitdepth.BitDepthService;
+import com.mediamanager.service.delegate.ActionHandler;
+import com.mediamanager.service.delegate.annotation.Action;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import java.util.List;
+
+
+@Action("bitdepth.getAll")
+public class GetBitDepthHandler implements ActionHandler {
+ private static final Logger logger = LogManager.getLogger(GetBitDepthHandler.class);
+
+ private final BitDepthService bitDepthService;
+
+ public GetBitDepthHandler(BitDepthService bitDepthService){this.bitDepthService = bitDepthService;}
+
+ @Override
+ public TransportProtocol.Response.Builder handle(ByteString requestPayload) throws InvalidProtocolBufferException {
+ try{
+ List bitDepths = bitDepthService.getAllBitDepths();
+ BitDepthMessages.GetBitDepthsResponse.Builder responseBuilder = BitDepthMessages.GetBitDepthsResponse.newBuilder();
+
+ for (BitDepth bitDepth : bitDepths) {
+ BitDepthMessages.BitDepth bitDepthProto = BitDepthMapper.toProtobuf(bitDepth);
+ responseBuilder.addBitdepths(bitDepthProto);
+ }
+ BitDepthMessages.GetBitDepthsResponse getBitDepthsResponse = responseBuilder.build();
+
+ return TransportProtocol.Response.newBuilder()
+ .setPayload(getBitDepthsResponse.toByteString());
+
+ }catch (Exception e){
+ logger.error("Error getting bit-depths", e);
+ return TransportProtocol.Response.newBuilder()
+ .setStatusCode(500)
+ .setPayload(ByteString.copyFromUtf8("Error: " + e.getMessage()));
+ }
+ }
+}
diff --git a/src/main/java/com/mediamanager/service/delegate/handler/bitdepth/UpdateBitDepthHandler.java b/src/main/java/com/mediamanager/service/delegate/handler/bitdepth/UpdateBitDepthHandler.java
new file mode 100644
index 0000000..c786b12
--- /dev/null
+++ b/src/main/java/com/mediamanager/service/delegate/handler/bitdepth/UpdateBitDepthHandler.java
@@ -0,0 +1,65 @@
+package com.mediamanager.service.delegate.handler.bitdepth;
+
+import com.google.protobuf.ByteString;
+import com.google.protobuf.InvalidProtocolBufferException;
+import com.mediamanager.mapper.BitDepthMapper;
+import com.mediamanager.model.BitDepth;
+import com.mediamanager.protocol.TransportProtocol;
+import com.mediamanager.protocol.messages.BitDepthMessages;
+import com.mediamanager.service.bitdepth.BitDepthService;
+import com.mediamanager.service.delegate.ActionHandler;
+import com.mediamanager.service.delegate.annotation.Action;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import java.util.Optional;
+
+@Action("bitdepth.update")
+public class UpdateBitDepthHandler implements ActionHandler {
+ private static final Logger logger = LogManager.getLogger(UpdateBitDepthHandler.class);
+ private final BitDepthService bitDepthService;
+
+ public UpdateBitDepthHandler(BitDepthService bitDepthService) {
+ this.bitDepthService = bitDepthService;
+ }
+
+ @Override
+ public TransportProtocol.Response.Builder handle(ByteString requestPayload) throws InvalidProtocolBufferException {
+ try{
+ BitDepthMessages.UpdateBitDepthRequest updateRequest =
+ BitDepthMessages.UpdateBitDepthRequest.parseFrom(requestPayload);
+
+ int id = updateRequest.getId();
+ String newValue = updateRequest.getValue();
+
+ Optional bitDepthOpt = bitDepthService.updateBitDepth(id, newValue);
+
+ if(bitDepthOpt.isEmpty()){
+ logger.warn("BitDepth not found with ID: {}", id);
+ return TransportProtocol.Response.newBuilder()
+ .setStatusCode(404)
+ .setPayload(ByteString.copyFromUtf8("BitDepth not found"));
+ }
+
+ BitDepthMessages.BitDepth bitDepthProto = BitDepthMapper.toProtobuf(bitDepthOpt.get());
+
+ BitDepthMessages.UpdateBitDepthResponse updateResponse = BitDepthMessages.UpdateBitDepthResponse.newBuilder()
+ .setBitdepth(bitDepthProto)
+ .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 bit-depth", e);
+ return TransportProtocol.Response.newBuilder()
+ .setStatusCode(500)
+ .setPayload(ByteString.copyFromUtf8("Error: " + e.getMessage()));
+ }
+ }
+}
diff --git a/src/main/java/com/mediamanager/service/delegate/handler/bitrate/CreateBitRateHandler.java b/src/main/java/com/mediamanager/service/delegate/handler/bitrate/CreateBitRateHandler.java
new file mode 100644
index 0000000..cfa9d2b
--- /dev/null
+++ b/src/main/java/com/mediamanager/service/delegate/handler/bitrate/CreateBitRateHandler.java
@@ -0,0 +1,50 @@
+package com.mediamanager.service.delegate.handler.bitrate;
+
+import com.google.protobuf.ByteString;
+import com.google.protobuf.InvalidProtocolBufferException;
+import com.mediamanager.mapper.BitRateMapper;
+import com.mediamanager.model.BitRate;
+import com.mediamanager.protocol.TransportProtocol;
+import com.mediamanager.protocol.messages.BitRateMessages;
+import com.mediamanager.service.bitrate.BitRateService;
+import com.mediamanager.service.delegate.ActionHandler;
+import com.mediamanager.service.delegate.annotation.Action;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+@Action("bitrate.create")
+public class CreateBitRateHandler implements ActionHandler {
+ private static final Logger logger = LogManager.getLogger(CreateBitRateHandler.class);
+ private final BitRateService bitRateService;
+
+ public CreateBitRateHandler(BitRateService bitRateService) {
+ this.bitRateService = bitRateService;
+ }
+
+ @Override
+ public TransportProtocol.Response.Builder handle(ByteString requestPayload) throws InvalidProtocolBufferException {
+ try{
+ BitRateMessages.CreateBitRateRequest createRequest =
+ BitRateMessages.CreateBitRateRequest.parseFrom(requestPayload);
+ BitRate bitRate = bitRateService.createBitRate(createRequest.getValue());
+ BitRateMessages.BitRate BitRateProto = BitRateMapper.toProtobuf(bitRate);
+ BitRateMessages.CreateBitRateResponse createBitRateResponse = BitRateMessages.CreateBitRateResponse.newBuilder()
+ .setBitrate(BitRateProto)
+ .build();
+ return TransportProtocol.Response.newBuilder()
+ .setPayload(createBitRateResponse.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 bit-rate", e);
+ return TransportProtocol.Response.newBuilder()
+ .setStatusCode(500)
+ .setPayload(ByteString.copyFromUtf8("Error: " + e.getMessage()));
+ }
+ }
+}
+
diff --git a/src/main/java/com/mediamanager/service/delegate/handler/bitrate/DeleteBitRateHandler.java b/src/main/java/com/mediamanager/service/delegate/handler/bitrate/DeleteBitRateHandler.java
new file mode 100644
index 0000000..35c520e
--- /dev/null
+++ b/src/main/java/com/mediamanager/service/delegate/handler/bitrate/DeleteBitRateHandler.java
@@ -0,0 +1,62 @@
+package com.mediamanager.service.delegate.handler.bitrate;
+
+import com.google.protobuf.ByteString;
+import com.google.protobuf.InvalidProtocolBufferException;
+import com.mediamanager.protocol.TransportProtocol;
+import com.mediamanager.protocol.messages.BitRateMessages;
+import com.mediamanager.service.bitrate.BitRateService;
+import com.mediamanager.service.delegate.ActionHandler;
+import com.mediamanager.service.delegate.annotation.Action;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+@Action("bitrate.delete")
+public class DeleteBitRateHandler implements ActionHandler {
+ private static final Logger logger = LogManager.getLogger(DeleteBitRateHandler.class);
+
+ private final BitRateService bitRateService;
+
+ public DeleteBitRateHandler(BitRateService bitRateService) {
+ this.bitRateService = bitRateService;
+ }
+
+ @Override
+ public TransportProtocol.Response.Builder handle(ByteString requestPayload)
+ throws InvalidProtocolBufferException {
+
+ try {
+ BitRateMessages.DeleteBitRateRequest deleteRequest =
+ BitRateMessages.DeleteBitRateRequest.parseFrom(requestPayload);
+ int id = deleteRequest.getId();
+ boolean success = bitRateService.deleteBitRate(id);
+ BitRateMessages.DeleteBitRateResponse deleteResponse;
+ if (success) {
+ deleteResponse = BitRateMessages.DeleteBitRateResponse.newBuilder()
+ .setSuccess(true)
+ .setMessage("Bit-Rate deleted successfully")
+ .build();
+ return TransportProtocol.Response.newBuilder()
+ .setPayload(deleteResponse.toByteString());
+ } else {
+ deleteResponse = BitRateMessages.DeleteBitRateResponse.newBuilder()
+ .setSuccess(false)
+ .setMessage("Bit-Rate not found")
+ .build();
+
+ return TransportProtocol.Response.newBuilder()
+ .setStatusCode(404)
+ .setPayload(deleteResponse.toByteString());
+ }
+ } catch (Exception e) {
+ logger.error("Error deleting bit-rate", e);
+ BitRateMessages.DeleteBitRateResponse deleteResponse =
+ BitRateMessages.DeleteBitRateResponse.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/bitrate/GetBitRateByIdHandler.java b/src/main/java/com/mediamanager/service/delegate/handler/bitrate/GetBitRateByIdHandler.java
new file mode 100644
index 0000000..a88893b
--- /dev/null
+++ b/src/main/java/com/mediamanager/service/delegate/handler/bitrate/GetBitRateByIdHandler.java
@@ -0,0 +1,56 @@
+package com.mediamanager.service.delegate.handler.bitrate;
+
+import com.google.protobuf.ByteString;
+import com.google.protobuf.InvalidProtocolBufferException;
+import com.mediamanager.mapper.BitRateMapper;
+import com.mediamanager.model.BitRate;
+import com.mediamanager.protocol.TransportProtocol;
+import com.mediamanager.protocol.messages.BitRateMessages;
+import com.mediamanager.service.bitrate.BitRateService;
+import com.mediamanager.service.delegate.ActionHandler;
+import com.mediamanager.service.delegate.annotation.Action;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import java.util.Optional;
+
+@Action(value = "bitrate.getById")
+public class GetBitRateByIdHandler implements ActionHandler {
+ private static final Logger logger = LogManager.getLogger(GetBitRateByIdHandler.class);
+ private final BitRateService bitRateService;
+
+ public GetBitRateByIdHandler(BitRateService bitRateService) {
+ this.bitRateService = bitRateService;
+ }
+
+ @Override
+ public TransportProtocol.Response.Builder handle(ByteString requestPayload)
+ throws InvalidProtocolBufferException{
+
+ try{
+ BitRateMessages.GetBitRateByIdRequest getByIdRequest =
+ BitRateMessages.GetBitRateByIdRequest.parseFrom(requestPayload);
+ int id = getByIdRequest.getId();
+
+ Optional bitRateOpt = bitRateService.getBitRateById(id);
+
+ if (bitRateOpt.isEmpty()){
+ logger.warn("BitRate not found with ID: {}", id);
+ return TransportProtocol.Response.newBuilder()
+ .setStatusCode(404)
+ .setPayload(ByteString.copyFromUtf8("BitRate not found"));
+ }
+ BitRateMessages.BitRate bitRateProto = BitRateMapper.toProtobuf(bitRateOpt.get());
+ BitRateMessages.GetBitRateByIdResponse getByIdResponse = BitRateMessages.GetBitRateByIdResponse.newBuilder()
+ .setBitrate(bitRateProto)
+ .build();
+ return TransportProtocol.Response.newBuilder()
+ .setPayload(getByIdResponse.toByteString());
+ } catch (Exception e) {
+ logger.error("Error getting bit-rate 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/bitrate/GetBitRateHandler.java b/src/main/java/com/mediamanager/service/delegate/handler/bitrate/GetBitRateHandler.java
new file mode 100644
index 0000000..87c6ca3
--- /dev/null
+++ b/src/main/java/com/mediamanager/service/delegate/handler/bitrate/GetBitRateHandler.java
@@ -0,0 +1,48 @@
+package com.mediamanager.service.delegate.handler.bitrate;
+
+import com.google.protobuf.ByteString;
+import com.google.protobuf.InvalidProtocolBufferException;
+import com.mediamanager.mapper.BitRateMapper;
+import com.mediamanager.model.BitRate;
+import com.mediamanager.protocol.TransportProtocol;
+import com.mediamanager.protocol.messages.BitRateMessages;
+import com.mediamanager.service.bitrate.BitRateService;
+import com.mediamanager.service.delegate.ActionHandler;
+import com.mediamanager.service.delegate.annotation.Action;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import java.util.List;
+
+
+@Action("bitrate.getAll")
+public class GetBitRateHandler implements ActionHandler {
+ private static final Logger logger = LogManager.getLogger(GetBitRateHandler.class);
+
+ private final BitRateService bitRateService;
+
+ public GetBitRateHandler(BitRateService bitRateService){this.bitRateService = bitRateService;}
+
+ @Override
+ public TransportProtocol.Response.Builder handle(ByteString requestPayload) throws InvalidProtocolBufferException {
+ try{
+ List bitRates = bitRateService.getAllBitRates();
+ BitRateMessages.GetBitRatesResponse.Builder responseBuilder = BitRateMessages.GetBitRatesResponse.newBuilder();
+
+ for (BitRate bitRate : bitRates) {
+ BitRateMessages.BitRate bitRateProto = BitRateMapper.toProtobuf(bitRate);
+ responseBuilder.addBitrates(bitRateProto);
+ }
+ BitRateMessages.GetBitRatesResponse getBitRatesResponse = responseBuilder.build();
+
+ return TransportProtocol.Response.newBuilder()
+ .setPayload(getBitRatesResponse.toByteString());
+
+ }catch (Exception e){
+ logger.error("Error getting bit-rates", e);
+ return TransportProtocol.Response.newBuilder()
+ .setStatusCode(500)
+ .setPayload(ByteString.copyFromUtf8("Error: " + e.getMessage()));
+ }
+ }
+}
diff --git a/src/main/java/com/mediamanager/service/delegate/handler/bitrate/UpdateBitRateHandler.java b/src/main/java/com/mediamanager/service/delegate/handler/bitrate/UpdateBitRateHandler.java
new file mode 100644
index 0000000..f5e6dc9
--- /dev/null
+++ b/src/main/java/com/mediamanager/service/delegate/handler/bitrate/UpdateBitRateHandler.java
@@ -0,0 +1,65 @@
+package com.mediamanager.service.delegate.handler.bitrate;
+
+import com.google.protobuf.ByteString;
+import com.google.protobuf.InvalidProtocolBufferException;
+import com.mediamanager.mapper.BitRateMapper;
+import com.mediamanager.model.BitRate;
+import com.mediamanager.protocol.TransportProtocol;
+import com.mediamanager.protocol.messages.BitRateMessages;
+import com.mediamanager.service.bitrate.BitRateService;
+import com.mediamanager.service.delegate.ActionHandler;
+import com.mediamanager.service.delegate.annotation.Action;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import java.util.Optional;
+
+@Action("bitrate.update")
+public class UpdateBitRateHandler implements ActionHandler {
+ private static final Logger logger = LogManager.getLogger(UpdateBitRateHandler.class);
+ private final BitRateService bitRateService;
+
+ public UpdateBitRateHandler(BitRateService bitRateService) {
+ this.bitRateService = bitRateService;
+ }
+
+ @Override
+ public TransportProtocol.Response.Builder handle(ByteString requestPayload) throws InvalidProtocolBufferException {
+ try{
+ BitRateMessages.UpdateBitRateRequest updateRequest =
+ BitRateMessages.UpdateBitRateRequest.parseFrom(requestPayload);
+
+ int id = updateRequest.getId();
+ String newValue = updateRequest.getValue();
+
+ Optional bitRateOpt = bitRateService.updateBitRate(id, newValue);
+
+ if(bitRateOpt.isEmpty()){
+ logger.warn("BitRate not found with ID: {}", id);
+ return TransportProtocol.Response.newBuilder()
+ .setStatusCode(404)
+ .setPayload(ByteString.copyFromUtf8("BitRate not found"));
+ }
+
+ BitRateMessages.BitRate bitRateProto = BitRateMapper.toProtobuf(bitRateOpt.get());
+
+ BitRateMessages.UpdateBitRateResponse updateResponse = BitRateMessages.UpdateBitRateResponse.newBuilder()
+ .setBitrate(bitRateProto)
+ .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 bit-rate", e);
+ return TransportProtocol.Response.newBuilder()
+ .setStatusCode(500)
+ .setPayload(ByteString.copyFromUtf8("Error: " + e.getMessage()));
+ }
+ }
+}
diff --git a/src/main/java/com/mediamanager/service/delegate/handler/composer/CreateComposerHandler.java b/src/main/java/com/mediamanager/service/delegate/handler/composer/CreateComposerHandler.java
new file mode 100644
index 0000000..5ec5658
--- /dev/null
+++ b/src/main/java/com/mediamanager/service/delegate/handler/composer/CreateComposerHandler.java
@@ -0,0 +1,51 @@
+package com.mediamanager.service.delegate.handler.composer;
+
+import com.google.protobuf.ByteString;
+import com.google.protobuf.InvalidProtocolBufferException;
+import com.mediamanager.mapper.ComposerMapper;
+import com.mediamanager.model.Composer;
+import com.mediamanager.protocol.TransportProtocol;
+import com.mediamanager.protocol.messages.ComposerMessages;
+import com.mediamanager.service.composer.ComposerService;
+import com.mediamanager.service.delegate.ActionHandler;
+import com.mediamanager.service.delegate.annotation.Action;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+@Action("composer.create")
+public class CreateComposerHandler implements ActionHandler {
+ private static final Logger logger = LogManager.getLogger(CreateComposerHandler.class);
+ private final ComposerService composerService;
+
+ public CreateComposerHandler(ComposerService composerService) {
+ this.composerService = composerService;
+ }
+
+ @Override
+ public TransportProtocol.Response.Builder handle(ByteString requestPayload)
+ throws InvalidProtocolBufferException {
+ try{
+ ComposerMessages.CreateComposerRequest CreateRequest = ComposerMessages.CreateComposerRequest
+ .parseFrom(requestPayload);
+ Composer composer = composerService.createComposer(CreateRequest.getName());
+ ComposerMessages.Composer composerProto = ComposerMapper.toProtobuf(composer);
+ ComposerMessages.CreateComposerResponse createResponse = ComposerMessages.CreateComposerResponse
+ .newBuilder().setComposer(composerProto).build();
+ return TransportProtocol.Response.newBuilder().setPayload(createResponse.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 composer", e);
+ return TransportProtocol.Response.newBuilder()
+ .setStatusCode(500)
+ .setPayload(ByteString.copyFromUtf8("Error: " + e.getMessage()));
+ }
+
+ }
+}
diff --git a/src/main/java/com/mediamanager/service/delegate/handler/composer/DeleteComposerHandler.java b/src/main/java/com/mediamanager/service/delegate/handler/composer/DeleteComposerHandler.java
new file mode 100644
index 0000000..b159427
--- /dev/null
+++ b/src/main/java/com/mediamanager/service/delegate/handler/composer/DeleteComposerHandler.java
@@ -0,0 +1,53 @@
+package com.mediamanager.service.delegate.handler.composer;
+
+import com.google.protobuf.ByteString;
+import com.google.protobuf.InvalidProtocolBufferException;
+import com.mediamanager.protocol.TransportProtocol;
+import com.mediamanager.protocol.messages.ComposerMessages;
+import com.mediamanager.service.composer.ComposerService;
+import com.mediamanager.service.delegate.ActionHandler;
+import com.mediamanager.service.delegate.annotation.Action;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+@Action( "composer.delete")
+public class DeleteComposerHandler implements ActionHandler {
+ private static final Logger logger = LogManager.getLogger(DeleteComposerHandler.class);
+ private final ComposerService composerService;
+
+
+ public DeleteComposerHandler(ComposerService composerService){
+ this.composerService = composerService;
+ }
+ @Override
+ public TransportProtocol.Response.Builder handle(ByteString requestPayload)
+ throws InvalidProtocolBufferException {
+ try {
+ ComposerMessages.DeleteComposerRequest deleteRequest =
+ ComposerMessages.DeleteComposerRequest.parseFrom(requestPayload);
+ int id = deleteRequest.getId();
+ boolean success = composerService.deleteComposer(id);
+ ComposerMessages.DeleteComposerResponse deleteResponse;
+ if(success){
+ deleteResponse = ComposerMessages.DeleteComposerResponse.newBuilder().setSuccess(true)
+ .setMessage("Composer deleted successfully").build();
+
+
+ return TransportProtocol.Response.newBuilder()
+ .setPayload(deleteResponse.toByteString());
+ }else {
+ deleteResponse = ComposerMessages.DeleteComposerResponse.newBuilder().setSuccess(false)
+ .setMessage("Composer not found").build();
+ return TransportProtocol.Response.newBuilder().setStatusCode(404)
+ .setPayload(deleteResponse.toByteString());
+ }
+
+ } catch (Exception e) {
+ logger.error("Error deleting composer", e);
+ ComposerMessages.DeleteComposerResponse deleteResponse = ComposerMessages.DeleteComposerResponse
+ .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/composer/GetComposerByIdHandler.java b/src/main/java/com/mediamanager/service/delegate/handler/composer/GetComposerByIdHandler.java
new file mode 100644
index 0000000..d1336b9
--- /dev/null
+++ b/src/main/java/com/mediamanager/service/delegate/handler/composer/GetComposerByIdHandler.java
@@ -0,0 +1,57 @@
+package com.mediamanager.service.delegate.handler.composer;
+
+import com.google.protobuf.ByteString;
+import com.google.protobuf.InvalidProtocolBufferException;
+import com.mediamanager.mapper.ComposerMapper;
+import com.mediamanager.model.Composer;
+import com.mediamanager.protocol.TransportProtocol;
+import com.mediamanager.protocol.messages.ComposerMessages;
+import com.mediamanager.service.composer.ComposerService;
+import com.mediamanager.service.delegate.ActionHandler;
+import com.mediamanager.service.delegate.annotation.Action;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import java.util.Optional;
+
+@Action( "composer.getById")
+public class GetComposerByIdHandler implements ActionHandler {
+ private static final Logger logger = LogManager.getLogger(GetComposerByIdHandler.class);
+ private final ComposerService composerService;
+
+ public GetComposerByIdHandler(ComposerService composerService){
+ this.composerService = composerService;
+ }
+
+ @Override
+ public TransportProtocol.Response.Builder handle(ByteString requestPayload)
+ throws InvalidProtocolBufferException {
+ try{
+
+ ComposerMessages.GetComposerByIdRequest getByIdRequest = ComposerMessages.GetComposerByIdRequest
+ .parseFrom(requestPayload);
+ int id = getByIdRequest.getId();
+
+ Optional composerOpt = composerService.getComposerById(id);
+
+ if (composerOpt.isEmpty()) {
+ logger.warn("Composer not found with ID: {}", id);
+ return TransportProtocol.Response.newBuilder()
+ .setStatusCode(404)
+ .setPayload(ByteString.copyFromUtf8("Composer not found"));
+ }
+
+ ComposerMessages.Composer composerProto = ComposerMapper.toProtobuf(composerOpt.get());
+
+ ComposerMessages.GetComposerByIdResponse getByIdResponse = ComposerMessages.GetComposerByIdResponse
+ .newBuilder().setComposer(composerProto).build();
+
+ return TransportProtocol.Response.newBuilder().setPayload(getByIdResponse.toByteString());
+ } catch (Exception e) {
+ logger.error("Error getting composer 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/composer/GetComposerHandler.java b/src/main/java/com/mediamanager/service/delegate/handler/composer/GetComposerHandler.java
new file mode 100644
index 0000000..0d41487
--- /dev/null
+++ b/src/main/java/com/mediamanager/service/delegate/handler/composer/GetComposerHandler.java
@@ -0,0 +1,50 @@
+package com.mediamanager.service.delegate.handler.composer;
+
+import com.google.protobuf.ByteString;
+import com.google.protobuf.InvalidProtocolBufferException;
+import com.mediamanager.mapper.ComposerMapper;
+import com.mediamanager.model.Composer;
+import com.mediamanager.protocol.TransportProtocol;
+import com.mediamanager.protocol.messages.ComposerMessages;
+import com.mediamanager.protocol.messages.GenreMessages;
+import com.mediamanager.service.composer.ComposerService;
+import com.mediamanager.service.delegate.ActionHandler;
+import com.mediamanager.service.delegate.annotation.Action;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import java.util.List;
+
+@Action( "composer.getAll")
+public class GetComposerHandler implements ActionHandler {
+ private static final Logger logger = LogManager.getLogger(GetComposerHandler.class);
+ private final ComposerService composerService;
+
+ public GetComposerHandler(ComposerService composerService){
+ this.composerService = composerService;
+ }
+
+ @Override
+ public TransportProtocol.Response.Builder handle(ByteString requestPayload)
+ throws InvalidProtocolBufferException {
+
+ try{
+ List composers = composerService.getAllComposers();
+
+ ComposerMessages.GetComposersResponse.Builder responseBuilder = ComposerMessages.GetComposersResponse.newBuilder();
+ for(Composer composer : composers){
+ ComposerMessages.Composer composerProto = ComposerMapper.toProtobuf(composer);
+ responseBuilder.addComposers(composerProto);
+ }
+ ComposerMessages.GetComposersResponse getGenresResponse = responseBuilder.build();
+ return TransportProtocol.Response.newBuilder().setPayload(getGenresResponse.toByteString());
+ } catch (Exception e) {
+ logger.error("Error getting composers", e);
+ return TransportProtocol.Response.newBuilder()
+ .setStatusCode(500)
+ .setPayload(ByteString.copyFromUtf8("Error: " + e.getMessage()));
+ }
+
+ }
+
+}
diff --git a/src/main/java/com/mediamanager/service/delegate/handler/composer/UpdateComposerHandler.java b/src/main/java/com/mediamanager/service/delegate/handler/composer/UpdateComposerHandler.java
new file mode 100644
index 0000000..d81af26
--- /dev/null
+++ b/src/main/java/com/mediamanager/service/delegate/handler/composer/UpdateComposerHandler.java
@@ -0,0 +1,56 @@
+package com.mediamanager.service.delegate.handler.composer;
+
+import com.google.protobuf.ByteString;
+import com.google.protobuf.InvalidProtocolBufferException;
+import com.mediamanager.mapper.ComposerMapper;
+import com.mediamanager.model.Composer;
+import com.mediamanager.protocol.TransportProtocol;
+import com.mediamanager.protocol.messages.ComposerMessages;
+import com.mediamanager.service.composer.ComposerService;
+import com.mediamanager.service.delegate.ActionHandler;
+import com.mediamanager.service.delegate.annotation.Action;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import java.util.Optional;
+
+@Action("composer.update")
+public class UpdateComposerHandler implements ActionHandler {
+ private static final Logger logger = LogManager.getLogger(UpdateComposerHandler.class);
+ private final ComposerService composerService;
+ public UpdateComposerHandler(ComposerService composerService){
+ this.composerService = composerService;
+ }
+
+ @Override
+ public TransportProtocol.Response.Builder handle(ByteString requestPayload)
+ throws InvalidProtocolBufferException {
+ try{
+ ComposerMessages.UpdateComposerRequest updateRequest = ComposerMessages.UpdateComposerRequest
+ .parseFrom(requestPayload);
+ int id = updateRequest.getId();
+ String newName = updateRequest.getName();
+ Optional composerOpt = composerService.updateComposer(id, newName);
+ if (composerOpt.isEmpty()) {
+ logger.warn("Composer not found with ID: {}", id);
+ return TransportProtocol.Response.newBuilder()
+ .setStatusCode(404)
+ .setPayload(ByteString.copyFromUtf8("Composer not found"));
+ }
+ ComposerMessages.Composer composerProto = ComposerMapper.toProtobuf(composerOpt.get());
+ ComposerMessages.UpdateComposerResponse updateResponse = ComposerMessages.UpdateComposerResponse
+ .newBuilder().setComposer(composerProto).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 composer", e);
+ return TransportProtocol.Response.newBuilder()
+ .setStatusCode(500)
+ .setPayload(ByteString.copyFromUtf8("Error: " + e.getMessage()));
+ }
+ }
+}
diff --git a/src/main/java/com/mediamanager/service/delegate/handler/genre/CreateGenreHandler.java b/src/main/java/com/mediamanager/service/delegate/handler/genre/CreateGenreHandler.java
new file mode 100644
index 0000000..569b119
--- /dev/null
+++ b/src/main/java/com/mediamanager/service/delegate/handler/genre/CreateGenreHandler.java
@@ -0,0 +1,62 @@
+package com.mediamanager.service.delegate.handler.genre;
+
+import com.google.protobuf.ByteString;
+import com.google.protobuf.InvalidProtocolBufferException;
+import com.mediamanager.mapper.GenreMapper;
+import com.mediamanager.model.Genre;
+import com.mediamanager.protocol.TransportProtocol;
+import com.mediamanager.protocol.messages.GenreMessages;
+import com.mediamanager.service.delegate.ActionHandler;
+import com.mediamanager.service.delegate.annotation.Action;
+import com.mediamanager.service.genre.GenreService;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+@Action("genre.create")
+public class CreateGenreHandler implements ActionHandler {
+ private static final Logger logger = LogManager.getLogger(CreateGenreHandler.class);
+
+ private final GenreService genreService;
+
+ public CreateGenreHandler(GenreService genreService) {
+ this.genreService = genreService;
+ }
+
+ @Override
+ public TransportProtocol.Response.Builder handle(ByteString requestPayload)
+ throws InvalidProtocolBufferException {
+ try {
+ // 1. Parse protobuf request
+ GenreMessages.CreateGenreRequest createRequest =
+ GenreMessages.CreateGenreRequest.parseFrom(requestPayload);
+
+ // 2. Chama service (lógica de negócio)
+ Genre genre = genreService.createGenre(createRequest.getName());
+
+ // 3. Converte entity para protobuf
+ GenreMessages.Genre genreProto = GenreMapper.toProtobuf(genre);
+
+ // 4. Cria response protobuf
+ GenreMessages.CreateGenreResponse createResponse =
+ GenreMessages.CreateGenreResponse.newBuilder()
+ .setGenre(genreProto)
+ .build();
+
+ // 5. Retorna
+ return TransportProtocol.Response.newBuilder()
+ .setPayload(createResponse.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 genre", e);
+ return TransportProtocol.Response.newBuilder()
+ .setStatusCode(500)
+ .setPayload(ByteString.copyFromUtf8("Error: " + e.getMessage()));
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/mediamanager/service/delegate/handler/genre/DeleteGenreHandler.java b/src/main/java/com/mediamanager/service/delegate/handler/genre/DeleteGenreHandler.java
new file mode 100644
index 0000000..bffdb1e
--- /dev/null
+++ b/src/main/java/com/mediamanager/service/delegate/handler/genre/DeleteGenreHandler.java
@@ -0,0 +1,72 @@
+package com.mediamanager.service.delegate.handler.genre;
+
+import com.google.protobuf.ByteString;
+import com.google.protobuf.InvalidProtocolBufferException;
+import com.mediamanager.protocol.TransportProtocol;
+import com.mediamanager.protocol.messages.GenreMessages;
+import com.mediamanager.service.delegate.ActionHandler;
+import com.mediamanager.service.delegate.annotation.Action;
+import com.mediamanager.service.genre.GenreService;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+@Action("genre.delete")
+public class DeleteGenreHandler implements ActionHandler {
+ private static final Logger logger = LogManager.getLogger(DeleteGenreHandler.class);
+
+ private final GenreService genreService;
+
+ public DeleteGenreHandler(GenreService genreService) {
+ this.genreService = genreService;
+ }
+
+ @Override
+ public TransportProtocol.Response.Builder handle(ByteString requestPayload)
+ throws InvalidProtocolBufferException {
+ try {
+ // 1. Parse protobuf request
+ GenreMessages.DeleteGenreRequest deleteRequest =
+ GenreMessages.DeleteGenreRequest.parseFrom(requestPayload);
+
+ int id = deleteRequest.getId();
+
+ // 2. Deleta via service
+ boolean success = genreService.deleteGenre(id);
+
+ // 3. Cria response
+ GenreMessages.DeleteGenreResponse deleteResponse;
+
+ if (success) {
+ deleteResponse = GenreMessages.DeleteGenreResponse.newBuilder()
+ .setSuccess(true)
+ .setMessage("Genre deleted successfully")
+ .build();
+
+ return TransportProtocol.Response.newBuilder()
+ .setPayload(deleteResponse.toByteString());
+ } else {
+ deleteResponse = GenreMessages.DeleteGenreResponse.newBuilder()
+ .setSuccess(false)
+ .setMessage("Genre not found")
+ .build();
+
+ return TransportProtocol.Response.newBuilder()
+ .setStatusCode(404)
+ .setPayload(deleteResponse.toByteString());
+ }
+
+ } catch (Exception e) {
+ logger.error("Error deleting genre", e);
+
+ GenreMessages.DeleteGenreResponse deleteResponse =
+ GenreMessages.DeleteGenreResponse.newBuilder()
+ .setSuccess(false)
+ .setMessage("Error: " + e.getMessage())
+ .build();
+
+ return TransportProtocol.Response.newBuilder()
+ .setStatusCode(500)
+ .setPayload(deleteResponse.toByteString());
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/mediamanager/service/delegate/handler/genre/GetGenreByIdHandler.java b/src/main/java/com/mediamanager/service/delegate/handler/genre/GetGenreByIdHandler.java
new file mode 100644
index 0000000..4dc4c71
--- /dev/null
+++ b/src/main/java/com/mediamanager/service/delegate/handler/genre/GetGenreByIdHandler.java
@@ -0,0 +1,66 @@
+package com.mediamanager.service.delegate.handler.genre;
+
+import com.google.protobuf.ByteString;
+import com.google.protobuf.InvalidProtocolBufferException;
+import com.mediamanager.mapper.GenreMapper;
+import com.mediamanager.model.Genre;
+import com.mediamanager.protocol.TransportProtocol;
+import com.mediamanager.protocol.messages.GenreMessages;
+import com.mediamanager.service.delegate.ActionHandler;
+import com.mediamanager.service.delegate.annotation.Action;
+import com.mediamanager.service.genre.GenreService;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import java.util.Optional;
+
+@Action("genre.getById")
+public class GetGenreByIdHandler implements ActionHandler {
+ private static final Logger logger = LogManager.getLogger(GetGenreByIdHandler.class);
+
+ private final GenreService genreService;
+
+ public GetGenreByIdHandler(GenreService genreService) {
+ this.genreService = genreService;
+ }
+
+ @Override
+ public TransportProtocol.Response.Builder handle(ByteString requestPayload)
+ throws InvalidProtocolBufferException {
+ try {
+ // 1. Parse protobuf request
+ GenreMessages.GetGenreByIdRequest getByIdRequest =
+ GenreMessages.GetGenreByIdRequest.parseFrom(requestPayload);
+
+ int id = getByIdRequest.getId();
+
+ // 2. Busca via service
+ Optional genreOpt = genreService.getGenreById(id);
+
+ if (genreOpt.isEmpty()) {
+ logger.warn("Genre not found with ID: {}", id);
+ return TransportProtocol.Response.newBuilder()
+ .setStatusCode(404)
+ .setPayload(ByteString.copyFromUtf8("Genre not found"));
+ }
+
+ // 3. Converte para protobuf
+ GenreMessages.Genre genreProto = GenreMapper.toProtobuf(genreOpt.get());
+
+ GenreMessages.GetGenreByIdResponse getByIdResponse =
+ GenreMessages.GetGenreByIdResponse.newBuilder()
+ .setGenre(genreProto)
+ .build();
+
+ // 4. Retorna
+ return TransportProtocol.Response.newBuilder()
+ .setPayload(getByIdResponse.toByteString());
+
+ } catch (Exception e) {
+ logger.error("Error getting genre by ID", e);
+ return TransportProtocol.Response.newBuilder()
+ .setStatusCode(500)
+ .setPayload(ByteString.copyFromUtf8("Error: " + e.getMessage()));
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/mediamanager/service/delegate/handler/genre/GetGenreHandler.java b/src/main/java/com/mediamanager/service/delegate/handler/genre/GetGenreHandler.java
new file mode 100644
index 0000000..068b44c
--- /dev/null
+++ b/src/main/java/com/mediamanager/service/delegate/handler/genre/GetGenreHandler.java
@@ -0,0 +1,56 @@
+package com.mediamanager.service.delegate.handler.genre;
+
+import com.google.protobuf.ByteString;
+import com.google.protobuf.InvalidProtocolBufferException;
+import com.mediamanager.mapper.GenreMapper;
+import com.mediamanager.model.Genre;
+import com.mediamanager.protocol.TransportProtocol;
+import com.mediamanager.protocol.messages.GenreMessages;
+import com.mediamanager.service.delegate.ActionHandler;
+import com.mediamanager.service.delegate.annotation.Action;
+import com.mediamanager.service.genre.GenreService;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import java.util.List;
+
+@Action("genre.getAll")
+public class GetGenreHandler implements ActionHandler {
+ private static final Logger logger = LogManager.getLogger(GetGenreHandler.class);
+
+ private final GenreService genreService;
+
+ public GetGenreHandler(GenreService genreService) {
+ this.genreService = genreService;
+ }
+
+ @Override
+ public TransportProtocol.Response.Builder handle(ByteString requestPayload)
+ throws InvalidProtocolBufferException {
+ try {
+ // 1. Busca todos os genres via service
+ List genres = genreService.getAllGenres();
+
+ // 2. Converte cada Genre para protobuf
+ GenreMessages.GetGenresResponse.Builder responseBuilder =
+ GenreMessages.GetGenresResponse.newBuilder();
+
+ for (Genre genre : genres) {
+ GenreMessages.Genre genreProto = GenreMapper.toProtobuf(genre);
+ responseBuilder.addGenres(genreProto);
+ }
+
+ GenreMessages.GetGenresResponse getGenresResponse = responseBuilder.build();
+
+ // 3. Retorna
+ return TransportProtocol.Response.newBuilder()
+ .setPayload(getGenresResponse.toByteString());
+
+ } catch (Exception e) {
+ logger.error("Error getting genres", e);
+ return TransportProtocol.Response.newBuilder()
+ .setStatusCode(500)
+ .setPayload(ByteString.copyFromUtf8("Error: " + e.getMessage()));
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/mediamanager/service/delegate/handler/genre/UpdateGenreHandler.java b/src/main/java/com/mediamanager/service/delegate/handler/genre/UpdateGenreHandler.java
new file mode 100644
index 0000000..d0b54d1
--- /dev/null
+++ b/src/main/java/com/mediamanager/service/delegate/handler/genre/UpdateGenreHandler.java
@@ -0,0 +1,73 @@
+package com.mediamanager.service.delegate.handler.genre;
+
+import com.google.protobuf.ByteString;
+import com.google.protobuf.InvalidProtocolBufferException;
+import com.mediamanager.mapper.GenreMapper;
+import com.mediamanager.model.Genre;
+import com.mediamanager.protocol.TransportProtocol;
+import com.mediamanager.protocol.messages.GenreMessages;
+import com.mediamanager.service.delegate.ActionHandler;
+import com.mediamanager.service.delegate.annotation.Action;
+import com.mediamanager.service.genre.GenreService;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import java.util.Optional;
+
+@Action("genre.update")
+public class UpdateGenreHandler implements ActionHandler {
+ private static final Logger logger = LogManager.getLogger(UpdateGenreHandler.class);
+
+ private final GenreService genreService;
+
+ public UpdateGenreHandler(GenreService genreService) {
+ this.genreService = genreService;
+ }
+
+ @Override
+ public TransportProtocol.Response.Builder handle(ByteString requestPayload)
+ throws InvalidProtocolBufferException {
+ try {
+ // 1. Parse protobuf request
+ GenreMessages.UpdateGenreRequest updateRequest =
+ GenreMessages.UpdateGenreRequest.parseFrom(requestPayload);
+
+ int id = updateRequest.getId();
+ String newName = updateRequest.getName();
+
+ // 2. Atualiza via service
+ Optional genreOpt = genreService.updateGenre(id, newName);
+
+ if (genreOpt.isEmpty()) {
+ logger.warn("Genre not found with ID: {}", id);
+ return TransportProtocol.Response.newBuilder()
+ .setStatusCode(404)
+ .setPayload(ByteString.copyFromUtf8("Genre not found"));
+ }
+
+ // 3. Converte para protobuf
+ GenreMessages.Genre genreProto = GenreMapper.toProtobuf(genreOpt.get());
+
+ GenreMessages.UpdateGenreResponse updateResponse =
+ GenreMessages.UpdateGenreResponse.newBuilder()
+ .setGenre(genreProto)
+ .build();
+
+ // 4. Retorna
+ 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 genre", e);
+ return TransportProtocol.Response.newBuilder()
+ .setStatusCode(500)
+ .setPayload(ByteString.copyFromUtf8("Error: " + e.getMessage()));
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/mediamanager/service/delegate/handler/samplingrate/CreateSamplingRateHandler.java b/src/main/java/com/mediamanager/service/delegate/handler/samplingrate/CreateSamplingRateHandler.java
new file mode 100644
index 0000000..a3e0715
--- /dev/null
+++ b/src/main/java/com/mediamanager/service/delegate/handler/samplingrate/CreateSamplingRateHandler.java
@@ -0,0 +1,50 @@
+package com.mediamanager.service.delegate.handler.samplingrate;
+
+import com.google.protobuf.ByteString;
+import com.google.protobuf.InvalidProtocolBufferException;
+import com.mediamanager.mapper.SamplingRateMapper;
+import com.mediamanager.model.SamplingRate;
+import com.mediamanager.protocol.TransportProtocol;
+import com.mediamanager.protocol.messages.SamplingRateMessages;
+import com.mediamanager.service.delegate.ActionHandler;
+import com.mediamanager.service.delegate.annotation.Action;
+import com.mediamanager.service.samplingrate.SamplingRateService;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+@Action("samplingrate.create")
+public class CreateSamplingRateHandler implements ActionHandler {
+ private static final Logger logger = LogManager.getLogger(CreateSamplingRateHandler.class);
+ private final SamplingRateService samplingRateService;
+
+ public CreateSamplingRateHandler(SamplingRateService samplingRateService) {
+ this.samplingRateService = samplingRateService;
+ }
+
+ @Override
+ public TransportProtocol.Response.Builder handle(ByteString requestPayload) throws InvalidProtocolBufferException {
+ try{
+ SamplingRateMessages.CreateSamplingRateRequest createRequest =
+ SamplingRateMessages.CreateSamplingRateRequest.parseFrom(requestPayload);
+ SamplingRate samplingRate = samplingRateService.createSamplingRate(createRequest.getValue());
+ SamplingRateMessages.SamplingRate samplingRateProto = SamplingRateMapper.toProtobuf(samplingRate);
+ SamplingRateMessages.CreateSamplingRateResponse createSamplingRateResponse = SamplingRateMessages.CreateSamplingRateResponse.newBuilder()
+ .setSamplingrate(samplingRateProto)
+ .build();
+ return TransportProtocol.Response.newBuilder()
+ .setPayload(createSamplingRateResponse.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 sampling rate", e);
+ return TransportProtocol.Response.newBuilder()
+ .setStatusCode(500)
+ .setPayload(ByteString.copyFromUtf8("Error: " + e.getMessage()));
+ }
+ }
+}
+
diff --git a/src/main/java/com/mediamanager/service/delegate/handler/samplingrate/DeleteSamplingRateHandler.java b/src/main/java/com/mediamanager/service/delegate/handler/samplingrate/DeleteSamplingRateHandler.java
new file mode 100644
index 0000000..1881045
--- /dev/null
+++ b/src/main/java/com/mediamanager/service/delegate/handler/samplingrate/DeleteSamplingRateHandler.java
@@ -0,0 +1,62 @@
+package com.mediamanager.service.delegate.handler.samplingrate;
+
+import com.google.protobuf.ByteString;
+import com.google.protobuf.InvalidProtocolBufferException;
+import com.mediamanager.protocol.TransportProtocol;
+import com.mediamanager.protocol.messages.SamplingRateMessages;
+import com.mediamanager.service.delegate.ActionHandler;
+import com.mediamanager.service.delegate.annotation.Action;
+import com.mediamanager.service.samplingrate.SamplingRateService;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+@Action("samplingrate.delete")
+public class DeleteSamplingRateHandler implements ActionHandler {
+ private static final Logger logger = LogManager.getLogger(DeleteSamplingRateHandler.class);
+
+ private final SamplingRateService samplingRateService;
+
+ public DeleteSamplingRateHandler(SamplingRateService samplingRateService) {
+ this.samplingRateService = samplingRateService;
+ }
+
+ @Override
+ public TransportProtocol.Response.Builder handle(ByteString requestPayload)
+ throws InvalidProtocolBufferException {
+
+ try {
+ SamplingRateMessages.DeleteSamplingRateRequest deleteRequest =
+ SamplingRateMessages.DeleteSamplingRateRequest.parseFrom(requestPayload);
+ int id = deleteRequest.getId();
+ boolean success = samplingRateService.deleteSamplingRate(id);
+ SamplingRateMessages.DeleteSamplingRateResponse deleteResponse;
+ if (success) {
+ deleteResponse = SamplingRateMessages.DeleteSamplingRateResponse.newBuilder()
+ .setSuccess(true)
+ .setMessage("Sampling rate deleted successfully")
+ .build();
+ return TransportProtocol.Response.newBuilder()
+ .setPayload(deleteResponse.toByteString());
+ } else {
+ deleteResponse = SamplingRateMessages.DeleteSamplingRateResponse.newBuilder()
+ .setSuccess(false)
+ .setMessage("Sampling rate not found")
+ .build();
+
+ return TransportProtocol.Response.newBuilder()
+ .setStatusCode(404)
+ .setPayload(deleteResponse.toByteString());
+ }
+ } catch (Exception e) {
+ logger.error("Error deleting sampling rate", e);
+ SamplingRateMessages.DeleteSamplingRateResponse deleteResponse =
+ SamplingRateMessages.DeleteSamplingRateResponse.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/samplingrate/GetSamplingRateByIdHandler.java b/src/main/java/com/mediamanager/service/delegate/handler/samplingrate/GetSamplingRateByIdHandler.java
new file mode 100644
index 0000000..c791798
--- /dev/null
+++ b/src/main/java/com/mediamanager/service/delegate/handler/samplingrate/GetSamplingRateByIdHandler.java
@@ -0,0 +1,56 @@
+package com.mediamanager.service.delegate.handler.samplingrate;
+
+import com.google.protobuf.ByteString;
+import com.google.protobuf.InvalidProtocolBufferException;
+import com.mediamanager.mapper.SamplingRateMapper;
+import com.mediamanager.model.SamplingRate;
+import com.mediamanager.protocol.TransportProtocol;
+import com.mediamanager.protocol.messages.SamplingRateMessages;
+import com.mediamanager.service.delegate.ActionHandler;
+import com.mediamanager.service.delegate.annotation.Action;
+import com.mediamanager.service.samplingrate.SamplingRateService;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import java.util.Optional;
+
+@Action(value = "samplingrate.getById")
+public class GetSamplingRateByIdHandler implements ActionHandler {
+ private static final Logger logger = LogManager.getLogger(GetSamplingRateByIdHandler.class);
+ private final SamplingRateService samplingRateService;
+
+ public GetSamplingRateByIdHandler(SamplingRateService samplingRateService) {
+ this.samplingRateService = samplingRateService;
+ }
+
+ @Override
+ public TransportProtocol.Response.Builder handle(ByteString requestPayload)
+ throws InvalidProtocolBufferException{
+
+ try{
+ SamplingRateMessages.GetSamplingRateByIdRequest getByIdRequest =
+ SamplingRateMessages.GetSamplingRateByIdRequest.parseFrom(requestPayload);
+ int id = getByIdRequest.getId();
+
+ Optional samplingRateOpt = samplingRateService.getSamplingRateById(id);
+
+ if (samplingRateOpt.isEmpty()){
+ logger.warn("SamplingRate not found with ID: {}", id);
+ return TransportProtocol.Response.newBuilder()
+ .setStatusCode(404)
+ .setPayload(ByteString.copyFromUtf8("SamplingRate not found"));
+ }
+ SamplingRateMessages.SamplingRate samplingRateProto = SamplingRateMapper.toProtobuf(samplingRateOpt.get());
+ SamplingRateMessages.GetSamplingRateByIdResponse getByIdResponse = SamplingRateMessages.GetSamplingRateByIdResponse.newBuilder()
+ .setSamplingrate(samplingRateProto)
+ .build();
+ return TransportProtocol.Response.newBuilder()
+ .setPayload(getByIdResponse.toByteString());
+ } catch (Exception e) {
+ logger.error("Error getting sampling rate 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/samplingrate/GetSamplingRateHandler.java b/src/main/java/com/mediamanager/service/delegate/handler/samplingrate/GetSamplingRateHandler.java
new file mode 100644
index 0000000..5e51e46
--- /dev/null
+++ b/src/main/java/com/mediamanager/service/delegate/handler/samplingrate/GetSamplingRateHandler.java
@@ -0,0 +1,48 @@
+package com.mediamanager.service.delegate.handler.samplingrate;
+
+import com.google.protobuf.ByteString;
+import com.google.protobuf.InvalidProtocolBufferException;
+import com.mediamanager.mapper.SamplingRateMapper;
+import com.mediamanager.model.SamplingRate;
+import com.mediamanager.protocol.TransportProtocol;
+import com.mediamanager.protocol.messages.SamplingRateMessages;
+import com.mediamanager.service.delegate.ActionHandler;
+import com.mediamanager.service.delegate.annotation.Action;
+import com.mediamanager.service.samplingrate.SamplingRateService;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import java.util.List;
+
+
+@Action("samplingrate.getAll")
+public class GetSamplingRateHandler implements ActionHandler {
+ private static final Logger logger = LogManager.getLogger(GetSamplingRateHandler.class);
+
+ private final SamplingRateService samplingRateService;
+
+ public GetSamplingRateHandler(SamplingRateService samplingRateService){this.samplingRateService = samplingRateService;}
+
+ @Override
+ public TransportProtocol.Response.Builder handle(ByteString requestPayload) throws InvalidProtocolBufferException {
+ try{
+ List samplingRates = samplingRateService.getAllSamplingRates();
+ SamplingRateMessages.GetSamplingRatesResponse.Builder responseBuilder = SamplingRateMessages.GetSamplingRatesResponse.newBuilder();
+
+ for (SamplingRate samplingRate : samplingRates) {
+ SamplingRateMessages.SamplingRate samplingRateProto = SamplingRateMapper.toProtobuf(samplingRate);
+ responseBuilder.addSamplingrates(samplingRateProto);
+ }
+ SamplingRateMessages.GetSamplingRatesResponse getSamplingRatesResponse = responseBuilder.build();
+
+ return TransportProtocol.Response.newBuilder()
+ .setPayload(getSamplingRatesResponse.toByteString());
+
+ }catch (Exception e){
+ logger.error("Error getting sampling rates", e);
+ return TransportProtocol.Response.newBuilder()
+ .setStatusCode(500)
+ .setPayload(ByteString.copyFromUtf8("Error: " + e.getMessage()));
+ }
+ }
+}
diff --git a/src/main/java/com/mediamanager/service/delegate/handler/samplingrate/UpdateSamplingRateHandler.java b/src/main/java/com/mediamanager/service/delegate/handler/samplingrate/UpdateSamplingRateHandler.java
new file mode 100644
index 0000000..770ea82
--- /dev/null
+++ b/src/main/java/com/mediamanager/service/delegate/handler/samplingrate/UpdateSamplingRateHandler.java
@@ -0,0 +1,65 @@
+package com.mediamanager.service.delegate.handler.samplingrate;
+
+import com.google.protobuf.ByteString;
+import com.google.protobuf.InvalidProtocolBufferException;
+import com.mediamanager.mapper.SamplingRateMapper;
+import com.mediamanager.model.SamplingRate;
+import com.mediamanager.protocol.TransportProtocol;
+import com.mediamanager.protocol.messages.SamplingRateMessages;
+import com.mediamanager.service.delegate.ActionHandler;
+import com.mediamanager.service.delegate.annotation.Action;
+import com.mediamanager.service.samplingrate.SamplingRateService;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import java.util.Optional;
+
+@Action("samplingrate.update")
+public class UpdateSamplingRateHandler implements ActionHandler {
+ private static final Logger logger = LogManager.getLogger(UpdateSamplingRateHandler.class);
+ private final SamplingRateService samplingRateService;
+
+ public UpdateSamplingRateHandler(SamplingRateService samplingRateService) {
+ this.samplingRateService = samplingRateService;
+ }
+
+ @Override
+ public TransportProtocol.Response.Builder handle(ByteString requestPayload) throws InvalidProtocolBufferException {
+ try{
+ SamplingRateMessages.UpdateSamplingRateRequest updateRequest =
+ SamplingRateMessages.UpdateSamplingRateRequest.parseFrom(requestPayload);
+
+ int id = updateRequest.getId();
+ String newValue = updateRequest.getValue();
+
+ Optional samplingRateOpt = samplingRateService.updateSamplingRate(id, newValue);
+
+ if(samplingRateOpt.isEmpty()){
+ logger.warn("SamplingRate not found with ID: {}", id);
+ return TransportProtocol.Response.newBuilder()
+ .setStatusCode(404)
+ .setPayload(ByteString.copyFromUtf8("SamplingRate not found"));
+ }
+
+ SamplingRateMessages.SamplingRate samplingRateProto = SamplingRateMapper.toProtobuf(samplingRateOpt.get());
+
+ SamplingRateMessages.UpdateSamplingRateResponse updateResponse = SamplingRateMessages.UpdateSamplingRateResponse.newBuilder()
+ .setSamplingrate(samplingRateProto)
+ .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 sampling rate", e);
+ return TransportProtocol.Response.newBuilder()
+ .setStatusCode(500)
+ .setPayload(ByteString.copyFromUtf8("Error: " + e.getMessage()));
+ }
+ }
+}
diff --git a/src/main/java/com/mediamanager/service/genre/GenreService.java b/src/main/java/com/mediamanager/service/genre/GenreService.java
new file mode 100644
index 0000000..f0acf70
--- /dev/null
+++ b/src/main/java/com/mediamanager/service/genre/GenreService.java
@@ -0,0 +1,88 @@
+package com.mediamanager.service.genre;
+
+import com.mediamanager.model.Genre;
+import com.mediamanager.repository.GenreRepository;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * Service para lógica de negócio relacionada a Genre
+ */
+public class GenreService {
+ private static final Logger logger = LogManager.getLogger(GenreService.class);
+
+ private final GenreRepository genreRepository;
+
+ public GenreService(GenreRepository genreRepository) {
+ this.genreRepository = genreRepository;
+ }
+
+ /**
+ * Cria um novo genre
+ */
+ public Genre createGenre(String name) {
+ logger.info("Creating genre: {}", name);
+
+ // Aqui poderia ter validações de negócio
+ if (name == null || name.trim().isEmpty()) {
+ throw new IllegalArgumentException("Genre name cannot be empty");
+ }
+
+ Genre genre = new Genre();
+ genre.setName(name.trim());
+
+ return genreRepository.save(genre);
+ }
+
+ /**
+ * Busca todos os genres
+ */
+ public List getAllGenres() {
+ logger.info("Getting all genres");
+ return genreRepository.findAll();
+ }
+
+ /**
+ * Busca genre por ID
+ */
+ public Optional getGenreById(Integer id) {
+ logger.info("Getting genre by ID: {}", id);
+ return genreRepository.findById(id);
+ }
+
+ /**
+ * Atualiza um genre existente
+ */
+ public Optional updateGenre(Integer id, String name) {
+ logger.info("Updating genre ID {}: {}", id, name);
+
+ // Validação
+ if (name == null || name.trim().isEmpty()) {
+ throw new IllegalArgumentException("Genre name cannot be empty");
+ }
+
+ Optional existingGenre = genreRepository.findById(id);
+
+ if (existingGenre.isEmpty()) {
+ logger.warn("Genre not found with ID: {}", id);
+ return Optional.empty();
+ }
+
+ Genre genre = existingGenre.get();
+ genre.setName(name.trim());
+
+ Genre updated = genreRepository.update(genre);
+ return Optional.of(updated);
+ }
+
+ /**
+ * Deleta um genre por ID
+ */
+ public boolean deleteGenre(Integer id) {
+ logger.info("Deleting genre ID: {}", id);
+ return genreRepository.deleteById(id);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/mediamanager/service/ipc/IPCManager.java b/src/main/java/com/mediamanager/service/ipc/IPCManager.java
new file mode 100644
index 0000000..7fe7541
--- /dev/null
+++ b/src/main/java/com/mediamanager/service/ipc/IPCManager.java
@@ -0,0 +1,337 @@
+package com.mediamanager.service.ipc;
+
+import com.mediamanager.protocol.TransportProtocol;
+import com.mediamanager.service.delegate.DelegateActionManager;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+
+import java.io.IOException;
+import java.net.StandardProtocolFamily;
+import java.net.UnixDomainSocketAddress;
+import java.nio.channels.ServerSocketChannel;
+import java.nio.channels.SocketChannel;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.attribute.PosixFilePermission;
+import java.nio.file.attribute.PosixFilePermissions;
+import java.util.Properties;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
+
+public class IPCManager {
+ private final Properties configuration;
+ private static final Logger logger = LogManager.getLogger(IPCManager.class);
+ private final DelegateActionManager actionManager;
+
+ private Path socketPath;
+ private UnixDomainSocketAddress socketAddress;
+ private ServerSocketChannel serverChannel;
+ private ExecutorService clientThreadPool;
+ private final AtomicBoolean running = new AtomicBoolean(false);
+ private final ConcurrentHashMap activeClients = new ConcurrentHashMap<>();
+ private final AtomicInteger clientIdCounter = new AtomicInteger(0);
+
+
+ public IPCManager(Properties config, DelegateActionManager actionManager){
+ configuration = config;
+ this.actionManager = actionManager;
+ logger.debug("IPCManager created with configuration:");
+
+
+ }
+ public void init() throws Exception {
+ logger.info("Initializing IPC connection...");
+ validateConfiguration();
+ socketPath = Path.of(configuration.getProperty("ipc.socket.path")).resolve("mediamanager.sock");
+
+ if (Files.exists(socketPath)) {
+ logger.warn("Socket file already exists at: {}", socketPath);
+ logger.info("Deleting existing socket...");
+ Files.deleteIfExists(socketPath);
+ }
+
+ Path parentDir = socketPath.getParent();
+ if (parentDir != null && !Files.exists(parentDir)) {
+ logger.info("Creating parent directory for socket: {}", parentDir);
+ Files.createDirectories(parentDir);
+ }
+
+ try {
+ socketAddress = UnixDomainSocketAddress.of(socketPath);
+ logger.debug("Socket address created");
+
+ serverChannel = ServerSocketChannel.open(StandardProtocolFamily.UNIX);
+ serverChannel.bind(socketAddress);
+ logger.info("Server bound to socket - file created at: {}", socketPath);
+
+ // ESTA É A MUDANÇA CRÍTICA
+ // Configura o canal para modo não-bloqueante
+ // Isso faz accept() retornar null imediatamente se não houver cliente
+ // ao invés de bloquear esperando indefinidamente
+ serverChannel.configureBlocking(false);
+ logger.debug("Server channel configured for non-blocking mode");
+
+ Set perms = PosixFilePermissions.fromString("rw-------");
+ Files.setPosixFilePermissions(socketPath, perms);
+ logger.debug("Socket permissions set to: rw-------");
+
+ clientThreadPool = Executors.newCachedThreadPool(runnable -> {
+ Thread thread = new Thread(runnable);
+ thread.setName("IPC-Client-Handler-" + thread.getId());
+ thread.setDaemon(true);
+ return thread;
+ });
+ logger.debug("Client thread pool created");
+
+ running.set(true);
+
+ Thread serverThread = new Thread(this::acceptConnectionsLoop, "IPC-Server-Accept-Thread");
+ serverThread.setDaemon(true);
+ serverThread.start();
+ logger.info("Server thread started - accepting connections");
+
+ logger.info("IPC server initialized successfully on {}", socketPath.toAbsolutePath());
+
+ } catch (IOException e) {
+ logger.error("Failed to initialize IPC server: {}", e.getMessage());
+ throw new Exception("Failed to initialize IPC server: " + e.getMessage(), e);
+ }
+ }
+ private void validateConfiguration() throws Exception {
+ String[] requiredProperties = {
+ "ipc.socket.path"
+ };
+ for (String property : requiredProperties) {
+ if (configuration.getProperty(property) == null) {
+ throw new Exception("Missing required configuration property: " + property);
+ }
+ }
+ logger.debug("IPC configuration validated successfully");
+ }
+
+ public Path getSocketPath(){
+ return socketPath;
+ }
+
+ public void close() throws Exception {
+ if(!running.get()){
+ logger.warn("IPC connection is already closed");
+ }
+
+
+ logger.info("Closing IPC connection...");
+
+ running.set(false);
+ if (serverChannel != null && serverChannel.isOpen()) {
+ serverChannel.close();
+ logger.debug("Server channel closed");
+ }
+
+ if (clientThreadPool != null) {
+ clientThreadPool.shutdown();
+ try {
+ if (!clientThreadPool.awaitTermination(30, TimeUnit.SECONDS)) {
+ logger.warn("Some client handlers did not finish in time, forcing shutdown");
+ clientThreadPool.shutdownNow();
+ }
+ } catch (InterruptedException e) {
+ logger.error("Interrupted while waiting for client handlers", e);
+ clientThreadPool.shutdownNow();
+ Thread.currentThread().interrupt();
+ }
+ }
+
+ if (socketPath != null && Files.exists(socketPath)) {
+ Files.deleteIfExists(socketPath);
+ logger.info("Socket file deleted successfully");
+ }
+
+ logger.info("IPC server closed successfully");
+ }
+
+ private void acceptConnectionsLoop() {
+ logger.info("Preparing to accept connections...");
+
+ while (running.get()) {
+ try {
+ // Em modo não-bloqueante, accept() retorna imediatamente
+ // Se há um cliente esperando, retorna o SocketChannel
+ // Se não há cliente, retorna null
+ SocketChannel clientChannel = serverChannel.accept();
+
+ if (clientChannel != null) {
+ // Um cliente realmente se conectou!
+ int clientId = clientIdCounter.incrementAndGet();
+ logger.info("Client {} connected", clientId);
+
+ ClientHandler handler = new ClientHandler(clientId, clientChannel);
+ activeClients.put(clientId, handler);
+
+ clientThreadPool.submit(() -> {
+ try {
+ handler.handle();
+ } finally {
+ activeClients.remove(clientId);
+ logger.info("Client {} disconnected", clientId);
+ }
+ });
+ } else {
+ // Nenhum cliente conectado no momento
+ // Dorme por um curto período antes de verificar novamente
+ // Isso evita consumir CPU desnecessariamente em um loop vazio
+ Thread.sleep(1); // 1 milissegundos
+ }
+
+ } catch (InterruptedException e) {
+ // Thread foi interrompida, provavelmente durante shutdown
+ logger.debug("Accept loop interrupted");
+ break;
+
+ } catch (IOException e) {
+ // Erros de I/O reais devem ser logados
+ if (running.get()) {
+ logger.error("Error accepting client connection", e);
+ }
+ break;
+ }
+ }
+
+ logger.info("Connection loop stopped gracefully");
+ }
+
+
+ private class ClientHandler {
+ private final int clientId;
+ private final SocketChannel channel;
+
+ public ClientHandler(int clientId, SocketChannel channel) {
+ this.clientId = clientId;
+ this.channel = channel;
+ }
+
+ /**
+ * Método principal que processa a comunicação com o cliente.
+ * Aqui é onde vamos ler mensagens JSON, processá-las, e enviar respostas.
+ */
+ public void handle() {
+ logger.debug("Client {} handler thread started", clientId);
+
+ try {
+ // LOOP: processa múltiplas requests na mesma conexão
+ while (channel.isOpen()) {
+ TransportProtocol.Request request = readRequest(channel);
+
+ if (request == null) {
+ // Cliente desconectou gracefully
+ logger.info("Client {} disconnected (end of stream)", clientId);
+ break;
+ }
+
+ logger.info("Client {} sent request {}", clientId, request.getRequestId());
+
+ // Processa usando o DelegateActionManager
+ TransportProtocol.Response response = actionManager.ProcessedRequest(request);
+
+ // Envia resposta de volta
+ writeResponse(channel, response);
+ logger.info("Client {} response sent", clientId);
+
+ // Verifica se é comando CLOSE
+ String connectionHeader = response.getHeadersOrDefault("Connection", "");
+ if ("close".equals(connectionHeader)) {
+ logger.info("Client {} requested connection close", clientId);
+ break; // Sai do loop e fecha
+ }
+ }
+
+ } catch (IOException e) {
+ if (channel.isOpen()) {
+ logger.error("IO error handling client {}", clientId, e);
+ } else {
+ logger.debug("Client {} connection closed by peer", clientId);
+ }
+ } catch (Exception e) {
+ logger.error("Unexpected error handling client {}", clientId, e);
+ } finally {
+ try {
+ if (channel.isOpen()) {
+ channel.close();
+ }
+ logger.debug("Client {} channel closed", clientId);
+ } catch (IOException e) {
+ logger.error("Error closing client {} channel", clientId, e);
+ }
+ }
+ }
+ private TransportProtocol.Request readRequest(SocketChannel channel) throws IOException {
+ // Primeiro, lê o tamanho da mensagem (4 bytes = int32)
+ java.nio.ByteBuffer sizeBuffer = java.nio.ByteBuffer.allocate(4);
+ int bytesRead = 0;
+
+ while (bytesRead < 4) {
+ int read = channel.read(sizeBuffer);
+ if (read == -1) {
+ logger.debug("Client disconnected before sending size");
+ return null;
+ }
+ bytesRead += read;
+ }
+
+ sizeBuffer.flip();
+ int messageSize = sizeBuffer.getInt();
+ logger.debug("Expecting message of {} bytes", messageSize);
+
+ // Validação básica de segurança
+ if (messageSize <= 0 || messageSize > 1024 * 1024) { // Max 1MB
+ throw new IOException("Invalid message size: " + messageSize);
+ }
+
+ // Agora lê a mensagem completa
+ java.nio.ByteBuffer messageBuffer = java.nio.ByteBuffer.allocate(messageSize);
+ bytesRead = 0;
+
+ while (bytesRead < messageSize) {
+ int read = channel.read(messageBuffer);
+ if (read == -1) {
+ throw new IOException("Client disconnected while reading message");
+ }
+ bytesRead += read;
+ }
+
+ messageBuffer.flip();
+
+ // Deserializa o Protocol Buffers
+ byte[] messageBytes = new byte[messageSize];
+ messageBuffer.get(messageBytes);
+
+ return TransportProtocol.Request.parseFrom(messageBytes);
+ }
+
+ private void writeResponse(SocketChannel channel, TransportProtocol.Response response) throws IOException {
+ byte[] messageBytes = response.toByteArray();
+ int messageSize = messageBytes.length;
+
+ logger.debug("Writing response of {} bytes", messageSize);
+
+ java.nio.ByteBuffer buffer = java.nio.ByteBuffer.allocate(4 + messageSize);
+ buffer.putInt(messageSize);
+ buffer.put(messageBytes);
+ buffer.flip();
+
+ while (buffer.hasRemaining()) {
+ channel.write(buffer);
+ }
+
+ logger.debug("Response written successfully");
+ }
+ }
+}
+
+
+
diff --git a/src/main/java/com/mediamanager/service/samplingrate/SamplingRateService.java b/src/main/java/com/mediamanager/service/samplingrate/SamplingRateService.java
new file mode 100644
index 0000000..005e8e5
--- /dev/null
+++ b/src/main/java/com/mediamanager/service/samplingrate/SamplingRateService.java
@@ -0,0 +1,69 @@
+package com.mediamanager.service.samplingrate;
+
+import com.mediamanager.model.SamplingRate;
+import com.mediamanager.repository.SamplingRateRepository;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import java.util.List;
+import java.util.Optional;
+
+public class SamplingRateService {
+ private static final Logger logger = LogManager.getLogger(SamplingRateService.class);
+ private final SamplingRateRepository repository;
+
+ public SamplingRateService(SamplingRateRepository repository) {
+ this.repository = repository;
+ }
+
+ public SamplingRate createSamplingRate(String value) {
+ logger.debug("Creating sampling rate:{}", value);
+ if (value == null || value.trim().isEmpty()) {
+ throw new IllegalArgumentException("Sampling-Rate value cannot be null or empty");
+ }
+ SamplingRate samplingRate = new SamplingRate();
+ samplingRate.setValue(value);
+ return repository.save(samplingRate);
+ }
+
+ public List getAllSamplingRates() {
+ logger.info("Getting all sampling rates");
+ return repository.findAll();
+ }
+
+ public Optional getSamplingRateById(Integer id) {
+ if (id == null) {
+ throw new IllegalArgumentException("ID cannot be null");
+ }
+ logger.info("Getting sampling rate by id:{}", id);
+ return repository.findById(id);
+ }
+
+ public Optional updateSamplingRate(Integer id, String value) {
+ if (id == null) {
+ throw new IllegalArgumentException("ID cannot be null");
+ }
+ logger.info("Updating sampling rate:{}", value);
+ if (value == null || value.trim().isEmpty()) {
+ throw new IllegalArgumentException("Sampling-Rate value cannot be null or empty");
+ }
+ Optional existingSamplingRate = repository.findById(id);
+ if(existingSamplingRate.isEmpty()) {
+ logger.warn("Sampling rate not found with id:{}", id);
+ return Optional.empty();
+ }
+ SamplingRate samplingRate = existingSamplingRate.get();
+ samplingRate.setValue(value);
+ SamplingRate updatedSamplingRate = repository.update(samplingRate);
+ return Optional.of(updatedSamplingRate);
+ }
+
+ public boolean deleteSamplingRate(Integer id) {
+ if (id == null) {
+ throw new IllegalArgumentException("Sampling rate id cannot be null");
+ }
+ logger.info("Deleting sampling rate:{}", id);
+ return repository.deleteById(id);
+ }
+
+}
diff --git a/src/main/proto/album.proto b/src/main/proto/album.proto
new file mode 100644
index 0000000..e7d350a
--- /dev/null
+++ b/src/main/proto/album.proto
@@ -0,0 +1,77 @@
+syntax = "proto3";
+
+import "google/protobuf/wrappers.proto"; // ← Adicione esse import!
+
+option java_package = "com.mediamanager.protocol.messages";
+option java_outer_classname = "AlbumMessages";
+
+package mediamanager.messages;
+
+message Album {
+ int32 id = 1;
+ string name = 2;
+ int32 year = 3;
+ int32 number_of_discs = 4;
+ 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;
+}
+
+message CreateAlbumRequest {
+ string name = 1;
+ int32 year = 2;
+ int32 number_of_discs = 3;
+ string code = 4;
+ bool is_compilation = 5;
+ int32 fk_albumtype_id = 6;
+ int32 fk_albumart_id = 7;
+}
+
+message CreateAlbumResponse {
+ Album album = 1;
+}
+
+message GetAlbumsRequest {
+
+}
+
+message GetAlbumsResponse {
+ repeated Album albums = 1;
+}
+
+message GetAlbumByIdRequest {
+ int32 id = 1;
+}
+
+message GetAlbumByIdResponse {
+ Album album = 1;
+}
+
+message UpdateAlbumRequest {
+ int32 id = 1;
+ string name = 2;
+ google.protobuf.Int32Value year = 3; // ← Mudou!
+ google.protobuf.Int32Value number_of_discs = 4; // ← Mudou!
+ string code = 5;
+ bool is_compilation = 6;
+ google.protobuf.Int32Value fk_albumtype_id = 7; // ← Mudou!
+ google.protobuf.Int32Value fk_albumart_id = 8; // ← Mudou!
+}
+
+message UpdateAlbumResponse {
+ Album album = 1;
+}
+
+message DeleteAlbumRequest {
+ int32 id = 1;
+}
+
+message DeleteAlbumResponse {
+ bool success = 1;
+ string message = 2;
+}
\ No newline at end of file
diff --git a/src/main/proto/albumart.proto b/src/main/proto/albumart.proto
new file mode 100644
index 0000000..cce4ea8
--- /dev/null
+++ b/src/main/proto/albumart.proto
@@ -0,0 +1,53 @@
+syntax = "proto3";
+
+option java_package = "com.mediamanager.protocol.messages";
+option java_outer_classname = "AlbumArtMessages";
+
+package mediamanager.messages;
+
+message AlbumArt {
+ int32 id = 1;
+ string filepath = 2;
+}
+
+message CreateAlbumArtRequest {
+ string filepath = 1;
+}
+
+message CreateAlbumArtResponse {
+ AlbumArt albumart = 1;
+}
+
+message GetAlbumArtsRequest {
+
+}
+
+message GetAlbumArtsResponse {
+ repeated AlbumArt albumarts = 1;
+}
+
+message GetAlbumArtByIdRequest {
+ int32 id = 1;
+}
+
+message GetAlbumArtByIdResponse {
+ AlbumArt albumart = 1;
+}
+
+message UpdateAlbumArtRequest {
+ int32 id = 1;
+ string filepath = 2;
+}
+
+message UpdateAlbumArtResponse {
+ AlbumArt albumart = 1;
+}
+
+message DeleteAlbumArtRequest {
+ int32 id = 1;
+}
+
+message DeleteAlbumArtResponse {
+ bool success = 1;
+ string message = 2;
+}
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
diff --git a/src/main/proto/albumhasgenre.proto b/src/main/proto/albumhasgenre.proto
new file mode 100644
index 0000000..441de1d
--- /dev/null
+++ b/src/main/proto/albumhasgenre.proto
@@ -0,0 +1,46 @@
+syntax = "proto3";
+
+option java_package = "com.mediamanager.protocol.messages";
+option java_outer_classname = "AlbumHasGenreMessages";
+
+package mediamanager.messages;
+
+message AlbumHasGenre {
+ int32 id = 1;
+ int32 fk_album_id = 2;
+ int32 fk_genre_id = 3;
+}
+
+message CreateAlbumHasGenreRequest {
+ int32 fk_album_id = 1;
+ int32 fk_genre_id = 2;
+}
+
+message CreateAlbumHasGenreResponse {
+ AlbumHasGenre albumhasgenre = 1;
+}
+
+message GetAlbumHasGenresRequest {
+
+}
+
+message GetAlbumHasGenresResponse {
+ repeated AlbumHasGenre albumhasgenre = 1;
+}
+
+message GetAlbumHasGenreByIdRequest {
+ int32 id = 1;
+}
+
+message GetAlbumHasGenreByIdResponse {
+ AlbumHasGenre albumhasgenre = 1;
+}
+
+message DeleteAlbumHasGenreRequest {
+ int32 id = 1;
+}
+
+message DeleteAlbumHasGenreResponse {
+ bool success = 1;
+ string message = 2;
+}
\ No newline at end of file
diff --git a/src/main/proto/albumtype.proto b/src/main/proto/albumtype.proto
new file mode 100644
index 0000000..fba52b2
--- /dev/null
+++ b/src/main/proto/albumtype.proto
@@ -0,0 +1,53 @@
+syntax = "proto3";
+
+option java_package = "com.mediamanager.protocol.messages";
+option java_outer_classname = "AlbumTypeMessages";
+
+package mediamanager.messages;
+
+message AlbumType {
+ int32 id = 1;
+ string value = 2;
+}
+
+message CreateAlbumTypeRequest {
+ string value = 1;
+}
+
+message CreateAlbumTypeResponse {
+ AlbumType albumtype = 1;
+}
+
+message GetAlbumTypesRequest {
+
+}
+
+message GetAlbumTypesResponse {
+ repeated AlbumType albumtypes = 1;
+}
+
+message GetAlbumTypeByIdRequest {
+ int32 id = 1;
+}
+
+message GetAlbumTypeByIdResponse {
+ AlbumType albumtype = 1;
+}
+
+message UpdateAlbumTypeRequest {
+ int32 id = 1;
+ string value = 2; // Novo nome
+}
+
+message UpdateAlbumTypeResponse {
+ AlbumType albumtype = 1;
+}
+
+message DeleteAlbumTypeRequest {
+ int32 id = 1;
+}
+
+message DeleteAlbumTypeResponse {
+ bool success = 1;
+ string message = 2;
+}
diff --git a/src/main/proto/artist.proto b/src/main/proto/artist.proto
new file mode 100644
index 0000000..1f68272
--- /dev/null
+++ b/src/main/proto/artist.proto
@@ -0,0 +1,53 @@
+syntax = "proto3";
+
+option java_package = "com.mediamanager.protocol.messages";
+option java_outer_classname = "ArtistMessages";
+
+package mediamanager.messages;
+
+message Artist {
+ int32 id = 1;
+ string name = 2;
+}
+
+message CreateArtistRequest {
+ string name = 1;
+}
+
+message CreateArtistResponse {
+ Artist artist = 1;
+}
+
+message GetArtistsRequest {
+
+}
+
+message GetArtistsResponse {
+ repeated Artist artists = 1;
+}
+
+message GetArtistByIdRequest {
+ int32 id = 1;
+}
+
+message GetArtistByIdResponse {
+ Artist artist = 1;
+}
+
+message UpdateArtistRequest {
+ int32 id = 1;
+ string name = 2; // Novo nome
+}
+
+message UpdateArtistResponse {
+ Artist artist = 1;
+}
+
+message DeleteArtistRequest {
+ int32 id = 1;
+}
+
+message DeleteArtistResponse {
+ bool success = 1;
+ string message = 2;
+}
diff --git a/src/main/proto/bitdepth.proto b/src/main/proto/bitdepth.proto
new file mode 100644
index 0000000..571dc9a
--- /dev/null
+++ b/src/main/proto/bitdepth.proto
@@ -0,0 +1,53 @@
+syntax = "proto3";
+
+option java_package = "com.mediamanager.protocol.messages";
+option java_outer_classname = "BitDepthMessages";
+
+package mediamanager.messages;
+
+message BitDepth {
+ int32 id = 1;
+ string value = 2;
+}
+
+message CreateBitDepthRequest {
+ string value = 1;
+}
+
+message CreateBitDepthResponse {
+ BitDepth bitdepth = 1;
+}
+
+message GetBitDepthsRequest {
+
+}
+
+message GetBitDepthsResponse {
+ repeated BitDepth bitdepths = 1;
+}
+
+message GetBitDepthByIdRequest {
+ int32 id = 1;
+}
+
+message GetBitDepthByIdResponse {
+ BitDepth bitdepth = 1;
+}
+
+message UpdateBitDepthRequest {
+ int32 id = 1;
+ string value = 2; // Novo nome
+}
+
+message UpdateBitDepthResponse {
+ BitDepth bitdepth = 1;
+}
+
+message DeleteBitDepthRequest {
+ int32 id = 1;
+}
+
+message DeleteBitDepthResponse {
+ bool success = 1;
+ string message = 2;
+}
diff --git a/src/main/proto/bitrate.proto b/src/main/proto/bitrate.proto
new file mode 100644
index 0000000..4f69ea3
--- /dev/null
+++ b/src/main/proto/bitrate.proto
@@ -0,0 +1,53 @@
+syntax = "proto3";
+
+option java_package = "com.mediamanager.protocol.messages";
+option java_outer_classname = "BitRateMessages";
+
+package mediamanager.messages;
+
+message BitRate{
+ int32 id =1;
+ string value = 2;
+}
+
+message CreateBitRateRequest{
+ string value = 1;
+}
+
+message CreateBitRateResponse{
+ BitRate bitrate = 1;
+}
+
+message GetBitRatesRequest{
+
+}
+
+message GetBitRatesResponse{
+ repeated BitRate bitrates = 1;
+}
+
+message GetBitRateByIdRequest{
+ int32 id = 1;
+}
+
+message GetBitRateByIdResponse{
+ BitRate bitrate = 1;
+}
+
+message UpdateBitRateRequest{
+ int32 id = 1;
+ string value = 2;
+}
+
+message UpdateBitRateResponse{
+ BitRate bitrate = 1;
+}
+
+message DeleteBitRateRequest{
+ int32 id =1;
+}
+
+message DeleteBitRateResponse{
+ bool success = 1;
+ string message = 2;
+}
diff --git a/src/main/proto/composer.proto b/src/main/proto/composer.proto
new file mode 100644
index 0000000..ce82fba
--- /dev/null
+++ b/src/main/proto/composer.proto
@@ -0,0 +1,51 @@
+syntax = "proto3";
+
+option java_package = "com.mediamanager.protocol.messages";
+option java_outer_classname = "ComposerMessages";
+
+package mediamanager.messages;
+
+message Composer {
+ int32 id =1;
+ string name =2;
+}
+
+message CreateComposerRequest{
+ string name =1;
+}
+
+message CreateComposerResponse{
+ Composer composer = 1;
+}
+
+message GetComposersRequest{}
+
+message GetComposersResponse{
+ repeated Composer composers = 1;
+}
+
+message GetComposerByIdRequest{
+ int32 id =1;
+}
+
+message GetComposerByIdResponse{
+ Composer composer =1;
+}
+
+message UpdateComposerRequest{
+ int32 id = 1;
+ string name=2;
+}
+
+message UpdateComposerResponse{
+ Composer composer = 1;
+}
+
+message DeleteComposerRequest{
+ int32 id = 1;
+}
+
+message DeleteComposerResponse{
+ bool success = 1;
+ string message = 2;
+}
diff --git a/src/main/proto/genre.proto b/src/main/proto/genre.proto
new file mode 100644
index 0000000..b059b89
--- /dev/null
+++ b/src/main/proto/genre.proto
@@ -0,0 +1,53 @@
+syntax = "proto3";
+
+option java_package = "com.mediamanager.protocol.messages";
+option java_outer_classname = "GenreMessages";
+
+package mediamanager.messages;
+
+message Genre {
+ int32 id = 1;
+ string name = 2;
+}
+
+message CreateGenreRequest {
+ string name = 1;
+}
+
+message CreateGenreResponse {
+ Genre genre = 1;
+}
+
+message GetGenresRequest {
+
+}
+
+message GetGenresResponse {
+ repeated Genre genres = 1;
+}
+
+message GetGenreByIdRequest {
+ int32 id = 1;
+}
+
+message GetGenreByIdResponse {
+ Genre genre = 1;
+}
+
+message UpdateGenreRequest {
+ int32 id = 1;
+ string name = 2; // Novo nome
+}
+
+message UpdateGenreResponse {
+ Genre genre = 1; // Genre atualizado
+}
+
+message DeleteGenreRequest {
+ int32 id = 1;
+}
+
+message DeleteGenreResponse {
+ bool success = 1;
+ string message = 2;
+}
diff --git a/src/main/proto/messages.proto b/src/main/proto/messages.proto
new file mode 100644
index 0000000..106e59e
--- /dev/null
+++ b/src/main/proto/messages.proto
@@ -0,0 +1,19 @@
+syntax = "proto3";
+
+option java_package = "com.mediamanager.protocol";
+option java_outer_classname = "TransportProtocol";
+
+package mediamanager;
+
+message Request {
+ string request_id = 1;
+ bytes payload = 2;
+ map headers = 3;
+}
+
+message Response {
+ string request_id = 1;
+ int32 status_code = 2;
+ bytes payload = 3;
+ map headers = 4;
+}
\ No newline at end of file
diff --git a/src/main/proto/samplingrate.proto b/src/main/proto/samplingrate.proto
new file mode 100644
index 0000000..7a5f316
--- /dev/null
+++ b/src/main/proto/samplingrate.proto
@@ -0,0 +1,51 @@
+syntax = "proto3";
+
+option java_package = "com.mediamanager.protocol.messages";
+option java_outer_classname = "SamplingRateMessages";
+
+package mediamanager.messages;
+
+message SamplingRate{
+ int32 id=1;
+ string value=2;
+}
+
+message CreateSamplingRateRequest{
+ string value= 1;
+}
+
+message CreateSamplingRateResponse{
+ SamplingRate samplingrate =1;
+}
+
+message GetSamplingRatesRequest{}
+
+message GetSamplingRatesResponse{
+ repeated SamplingRate samplingrates = 1;
+}
+
+message GetSamplingRateByIdRequest{
+ int32 id =1;
+}
+
+message GetSamplingRateByIdResponse{
+ SamplingRate samplingrate = 1;
+}
+
+message UpdateSamplingRateRequest{
+ int32 id = 1;
+ string value = 2;
+}
+
+message UpdateSamplingRateResponse{
+ SamplingRate samplingrate = 1;
+}
+
+message DeleteSamplingRateRequest{
+ int32 id =1;
+}
+
+message DeleteSamplingRateResponse{
+ bool success = 1;
+ string message =2;
+}
\ No newline at end of file
diff --git a/src/main/proto/test.proto b/src/main/proto/test.proto
new file mode 100644
index 0000000..00330cd
--- /dev/null
+++ b/src/main/proto/test.proto
@@ -0,0 +1,30 @@
+syntax = "proto3";
+
+option java_package = "com.mediamanager.protocol";
+option java_outer_classname = "TestProtocol";
+
+package mediamanager.test;
+
+message EchoCommand {
+ string message = 1;
+}
+
+message EchoResponse {
+ string message = 1;
+ int64 server_timestamp = 2;
+}
+
+message HeartbeatCommand {
+ int64 client_timestamp = 1;
+}
+
+message HeartbeatResponse {
+ int64 client_timestamp = 1;
+ int64 server_timestamp = 2;
+}
+message CloseCommand {
+ // Vazio - apenas sinaliza fechamento
+}
+message CloseResponse {
+ string message = 1;
+}
\ No newline at end of file
diff --git a/src/main/resources/application.properties b/src/main/resources/config.properties.example
similarity index 92%
rename from src/main/resources/application.properties
rename to src/main/resources/config.properties.example
index fbef11a..0991905 100644
--- a/src/main/resources/application.properties
+++ b/src/main/resources/config.properties.example
@@ -21,3 +21,8 @@ hibernate.format_sql=true
ipc.pipe.name=mediamanager-pipe
ipc.pipe.path=/tmp/mediamanager
ipc.buffer.size=8192
+runtype=local
+ipc.socket.path=/tmp/mediamanager
+
+
+
diff --git a/src/main/resources/log4j2.xml b/src/main/resources/log4j2.xml
index 29d32dc..a9f3f84 100644
--- a/src/main/resources/log4j2.xml
+++ b/src/main/resources/log4j2.xml
@@ -1,12 +1,13 @@
-
+
-
+
+ filePattern="logs/mediamanager-%d{yyyy-MM-dd}-%i.log"
+ immediateFlush="true">
@@ -17,17 +18,17 @@
-
+
-
+
-
+