diff --git a/src/main/java/com/dostalgia/ConfigBuilder.java b/src/main/java/com/dostalgia/ConfigBuilder.java index 201c4c7..0db585f 100644 --- a/src/main/java/com/dostalgia/ConfigBuilder.java +++ b/src/main/java/com/dostalgia/ConfigBuilder.java @@ -7,10 +7,6 @@ import java.util.*; /** * Single source of truth for all DOSBox configuration generation. - * Eliminates the duplication that existed between GameService and UploadResource. - * - * Uses Java 21 text blocks for readable, maintainable config templates. - * Adding a new config parameter requires a change in exactly ONE place. */ @ApplicationScoped public class ConfigBuilder { @@ -20,8 +16,6 @@ public class ConfigBuilder { ".cue", 5, ".iso", 4, ".ccd", 3, ".img", 2, ".bin", 1 ); - // ─── Public API ─────────────────────────────────────────────── - /** * Build a dosbox.conf for a game with a known executable. * @param relExe relative path to the executable inside the ZIP (e.g. "FALLOUT.EXE" or "FALLOUT/FALLOUT.EXE") @@ -83,9 +77,6 @@ public class ConfigBuilder { public record ExeParts(String dir, String exe) {} - // ─── Config Templates ──────────────────────────────────────── - - // language=ini private static final String DOSBOX_CONF_TEMPLATE = """ [sdl] autolock=true @@ -121,7 +112,6 @@ public class ConfigBuilder { ${EXEC_PATH} """; - // language=ini private static final String CD_ONLY_DOSBOX_CONF_TEMPLATE = """ [sdl] autolock=true @@ -159,8 +149,6 @@ public class ConfigBuilder { echo Type D: and press Enter, then look for the game executable (e.g. DOTT.EXE). """; - // ─── Internal Helpers ──────────────────────────────────────── - /** * Build the CD mount lines for the autoexec section. * Mounts ALL CD images, deduplicating by parent directory. diff --git a/src/main/java/com/dostalgia/ConfigPatcher.java b/src/main/java/com/dostalgia/ConfigPatcher.java index 2286696..2f94515 100644 --- a/src/main/java/com/dostalgia/ConfigPatcher.java +++ b/src/main/java/com/dostalgia/ConfigPatcher.java @@ -32,10 +32,10 @@ public class ConfigPatcher { }) .forEach(f -> { try { - String text = new String(Files.readAllBytes(f), StandardCharsets.ISO_8859_1); + String text = Files.readString(f, StandardCharsets.ISO_8859_1); String patched = patchText(text, extractDir); if (!patched.equals(text)) { - Files.write(f, patched.getBytes(StandardCharsets.ISO_8859_1)); + Files.writeString(f, patched, StandardCharsets.ISO_8859_1); LOG.info("Patched absolute paths in " + f.getFileName()); } } catch (IOException e) { diff --git a/src/main/java/com/dostalgia/ExecutableDetector.java b/src/main/java/com/dostalgia/ExecutableDetector.java index a399d18..5acc110 100644 --- a/src/main/java/com/dostalgia/ExecutableDetector.java +++ b/src/main/java/com/dostalgia/ExecutableDetector.java @@ -4,10 +4,16 @@ import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; import java.io.IOException; -import java.nio.file.*; +import java.nio.file.FileVisitResult; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.SimpleFileVisitor; import java.nio.file.attribute.BasicFileAttributes; import java.nio.charset.StandardCharsets; -import java.util.*; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.Set; /** * Detects game executables within extracted archives. diff --git a/src/main/java/com/dostalgia/Game.java b/src/main/java/com/dostalgia/Game.java index fe34fba..181c6d9 100644 --- a/src/main/java/com/dostalgia/Game.java +++ b/src/main/java/com/dostalgia/Game.java @@ -17,37 +17,26 @@ public class Game { private String publisher; private String description; private Double rating; - - private String bundleFile; // relative path within game dir - - private String setupExe; // relative path to SETUP.EXE (null if none) - + private String bundleFile; + private String setupExe; /** Game bundle file size in bytes. Populated dynamically at load time (not persisted). */ private Long bundleSize; - /** Currently selected main executable (relative path inside the bundle). */ private String executable; - /** All discoverable executables in the bundle (for the UI picker). */ private List executables; - /** Platform type: "dos" for pure DOS, "windows" for Windows 3.x/9x+ */ private String platform; - private Integer igdbId; private String igdbCoverId; - private boolean hasCover; private boolean hasScreenshots; private List screenshots; private List videos; - private boolean ready; private Instant createdAt; private Instant updatedAt; - // ─── Constructors ──────────────────────────────────────────── - public Game() {} public Game(String id, String title) { @@ -58,8 +47,6 @@ public class Game { this.updatedAt = Instant.now(); } - // ─── Getters & Setters ────────────────────────────────────── - public String getId() { return id; } public void setId(String id) { this.id = id; } diff --git a/src/main/java/com/dostalgia/GameResource.java b/src/main/java/com/dostalgia/GameResource.java index 136819d..5121213 100644 --- a/src/main/java/com/dostalgia/GameResource.java +++ b/src/main/java/com/dostalgia/GameResource.java @@ -1,7 +1,15 @@ package com.dostalgia; import jakarta.inject.Inject; -import jakarta.ws.rs.*; +import jakarta.ws.rs.Consumes; +import jakarta.ws.rs.DELETE; +import jakarta.ws.rs.DefaultValue; +import jakarta.ws.rs.GET; +import jakarta.ws.rs.PATCH; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.PathParam; +import jakarta.ws.rs.Produces; +import jakarta.ws.rs.QueryParam; import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.Response; import jakarta.ws.rs.core.StreamingOutput; @@ -27,7 +35,6 @@ public class GameResource { try { var all = svc.list(); - // Client-side filtering (small dataset, fine for a personal library) if (search != null && !search.isBlank()) { all = all.stream() .filter(g -> g.getTitle().toLowerCase().contains(search.toLowerCase())) diff --git a/src/main/java/com/dostalgia/GameService.java b/src/main/java/com/dostalgia/GameService.java index 9308f32..5fa1005 100644 --- a/src/main/java/com/dostalgia/GameService.java +++ b/src/main/java/com/dostalgia/GameService.java @@ -12,7 +12,12 @@ import org.eclipse.microprofile.config.inject.ConfigProperty; import java.io.IOException; import java.io.OutputStream; -import java.nio.file.*; +import java.nio.file.FileVisitResult; +import java.nio.file.Files; +import java.nio.file.NoSuchFileException; +import java.nio.file.Path; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.StandardCopyOption; import java.nio.file.attribute.BasicFileAttributes; import java.time.Instant; import java.util.*; @@ -53,8 +58,6 @@ public class GameService implements GameStore { } } - // ─── Game Directory Helpers ────────────────────────────────── - public Path gameDir(String id) { return gamesDir.resolve(id); } @@ -63,8 +66,6 @@ public class GameService implements GameStore { return gameDir(id).resolve("game.json"); } - // ─── CRUD ──────────────────────────────────────────────────── - /** Load a game by ID. Throws if not found. */ public Game load(String id) throws IOException { Path path = gameJsonPath(id); @@ -142,8 +143,6 @@ public class GameService implements GameStore { return true; } - // ─── Utility ───────────────────────────────────────────────── - /** Sanitize a string for use as a game directory ID. */ public static String sanitizeId(String s) { StringBuilder sb = new StringBuilder(); diff --git a/src/main/java/com/dostalgia/IgdbResource.java b/src/main/java/com/dostalgia/IgdbResource.java index 2a72d6c..7d0d908 100644 --- a/src/main/java/com/dostalgia/IgdbResource.java +++ b/src/main/java/com/dostalgia/IgdbResource.java @@ -1,7 +1,13 @@ package com.dostalgia; import jakarta.inject.Inject; -import jakarta.ws.rs.*; +import jakarta.ws.rs.Consumes; +import jakarta.ws.rs.DefaultValue; +import jakarta.ws.rs.GET; +import jakarta.ws.rs.POST; +import jakarta.ws.rs.PathParam; +import jakarta.ws.rs.Produces; +import jakarta.ws.rs.QueryParam; import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.Response; import java.util.Map; diff --git a/src/main/java/com/dostalgia/IgdbService.java b/src/main/java/com/dostalgia/IgdbService.java index c3d16c4..5691e00 100644 --- a/src/main/java/com/dostalgia/IgdbService.java +++ b/src/main/java/com/dostalgia/IgdbService.java @@ -10,11 +10,14 @@ import java.net.URI; import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; -import java.nio.file.Files; import java.nio.file.Path; -import java.nio.file.StandardCopyOption; import java.time.Instant; -import java.util.*; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; import java.util.logging.Logger; /** Client for the IGDB (Internet Game Database) API via Twitch OAuth2. */ @@ -42,8 +45,6 @@ public class IgdbService { private String accessToken; private Instant tokenExpiry; - // ─── Token Management ───────────────────────────────────────── - public boolean isConfigured() { return clientId.isPresent() && clientSecret.isPresent() && !clientId.get().isBlank() && !clientSecret.get().isBlank(); @@ -84,8 +85,6 @@ public class IgdbService { .header("Content-Type", "text/plain"); } - // ─── Search ─────────────────────────────────────────────────── - /** * Search IGDB for games matching the given query. * Returns a list of simplified result maps suitable for JSON serialization. @@ -264,8 +263,6 @@ public class IgdbService { return screenshots; } - // ─── Auto-Scrape (called during upload) ────────────────────── - /** * Auto-search IGDB for the game title and apply the best match. * Updates the Game object in-place. Does NOT save — caller must svc.save(). @@ -439,8 +436,6 @@ public class IgdbService { } } - // ─── Utility ────────────────────────────────────────────────── - private String sanitize(String s) { return s.replace("\\", "\\\\").replace("\"", "\\\""); } diff --git a/src/main/java/com/dostalgia/StaticResource.java b/src/main/java/com/dostalgia/StaticResource.java index 4b50cba..ccccbc6 100644 --- a/src/main/java/com/dostalgia/StaticResource.java +++ b/src/main/java/com/dostalgia/StaticResource.java @@ -1,6 +1,5 @@ package com.dostalgia; -import jakarta.inject.Inject; import jakarta.ws.rs.GET; import jakarta.ws.rs.PathParam; import jakarta.ws.rs.core.MediaType; @@ -8,8 +7,10 @@ import jakarta.ws.rs.core.Response; import jakarta.ws.rs.core.StreamingOutput; import org.eclipse.microprofile.config.inject.ConfigProperty; -import java.io.*; -import java.nio.file.*; +import java.io.IOException; +import java.io.OutputStream; +import java.nio.file.Files; +import java.nio.file.Path; import java.util.Map; /** Serves game bundles (.jsdos) and artwork from the external data directory. */ diff --git a/src/main/java/com/dostalgia/UploadResource.java b/src/main/java/com/dostalgia/UploadResource.java index a47a04f..8d3d74c 100644 --- a/src/main/java/com/dostalgia/UploadResource.java +++ b/src/main/java/com/dostalgia/UploadResource.java @@ -10,10 +10,15 @@ import jakarta.ws.rs.core.Response; import org.jboss.resteasy.reactive.RestForm; import org.jboss.resteasy.reactive.multipart.FileUpload; -import java.io.*; -import java.nio.file.*; +import java.io.IOException; +import java.nio.file.FileVisitResult; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.StandardCopyOption; import java.nio.file.attribute.BasicFileAttributes; -import java.util.*; +import java.util.List; +import java.util.Map; import java.util.logging.Logger; @jakarta.ws.rs.Path("/api/upload") @@ -46,8 +51,6 @@ public class UploadResource { private static final Logger LOG = Logger.getLogger(UploadResource.class.getName()); - // ─── Upload ────────────────────────────────────────────────── - @POST @Consumes(MediaType.MULTIPART_FORM_DATA) public Response upload( @@ -217,8 +220,6 @@ public class UploadResource { return Response.ok(Map.of("status", "ok")).build(); } - // ─── File Utilities ────────────────────────────────────────── - private void deleteDir(Path dir) throws IOException { if (!Files.exists(dir)) return; Files.walkFileTree(dir, new SimpleFileVisitor<>() { diff --git a/src/main/java/com/dostalgia/ZipService.java b/src/main/java/com/dostalgia/ZipService.java index 6a83b08..eca6203 100644 --- a/src/main/java/com/dostalgia/ZipService.java +++ b/src/main/java/com/dostalgia/ZipService.java @@ -5,8 +5,13 @@ import jakarta.inject.Inject; import java.io.IOException; import java.io.UncheckedIOException; -import java.nio.file.*; -import java.util.*; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardCopyOption; +import java.util.Comparator; +import java.util.List; +import java.util.Set; +import java.util.TreeSet; import java.util.logging.Logger; /** diff --git a/src/test/java/com/dostalgia/CdImageServiceTest.java b/src/test/java/com/dostalgia/CdImageServiceTest.java index bd4be2c..d4e4fab 100644 --- a/src/test/java/com/dostalgia/CdImageServiceTest.java +++ b/src/test/java/com/dostalgia/CdImageServiceTest.java @@ -1,6 +1,5 @@ package com.dostalgia; -import static org.junit.jupiter.api.Assertions.*; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; @@ -8,6 +7,10 @@ import java.nio.file.Files; import java.nio.file.Path; import java.util.List; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + class CdImageServiceTest { private final CdImageService service = new CdImageService(); diff --git a/src/test/java/com/dostalgia/ConfigBuilderTest.java b/src/test/java/com/dostalgia/ConfigBuilderTest.java index 5d0ab0e..8c71fb6 100644 --- a/src/test/java/com/dostalgia/ConfigBuilderTest.java +++ b/src/test/java/com/dostalgia/ConfigBuilderTest.java @@ -1,13 +1,13 @@ package com.dostalgia; -import static org.junit.jupiter.api.Assertions.*; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.io.TempDir; - -import java.nio.file.Files; -import java.nio.file.Path; import java.util.List; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.assertNull; + class ConfigBuilderTest { private final ConfigBuilder builder = new ConfigBuilder(); diff --git a/src/test/java/com/dostalgia/ConfigPatcherTest.java b/src/test/java/com/dostalgia/ConfigPatcherTest.java index 2c4bc9a..0aec0be 100644 --- a/src/test/java/com/dostalgia/ConfigPatcherTest.java +++ b/src/test/java/com/dostalgia/ConfigPatcherTest.java @@ -1,6 +1,5 @@ package com.dostalgia; -import static org.junit.jupiter.api.Assertions.*; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; @@ -8,6 +7,12 @@ import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + class ConfigPatcherTest { private final ConfigPatcher patcher = new ConfigPatcher(); diff --git a/src/test/java/com/dostalgia/ExecutableDetectorTest.java b/src/test/java/com/dostalgia/ExecutableDetectorTest.java index 89c6e04..58f1fe2 100644 --- a/src/test/java/com/dostalgia/ExecutableDetectorTest.java +++ b/src/test/java/com/dostalgia/ExecutableDetectorTest.java @@ -1,6 +1,5 @@ package com.dostalgia; -import static org.junit.jupiter.api.Assertions.*; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; @@ -8,6 +7,11 @@ import java.nio.file.Files; import java.nio.file.Path; import java.util.List; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + class ExecutableDetectorTest { private final ExecutableDetector detector = new ExecutableDetector(); @@ -125,8 +129,6 @@ class ExecutableDetectorTest { assertFalse(ExecutableDetector.isLikelySelfExtractor(f)); } - // ─── helpers ───────────────────────────────────────────────── - private static byte[] createMZ(int size) { byte[] buf = new byte[size]; buf[0] = 0x4D; // M diff --git a/src/test/java/com/dostalgia/PlatformDetectorTest.java b/src/test/java/com/dostalgia/PlatformDetectorTest.java index b89af2f..c68f928 100644 --- a/src/test/java/com/dostalgia/PlatformDetectorTest.java +++ b/src/test/java/com/dostalgia/PlatformDetectorTest.java @@ -1,12 +1,14 @@ package com.dostalgia; -import static org.junit.jupiter.api.Assertions.*; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; import java.nio.file.Files; import java.nio.file.Path; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; + class PlatformDetectorTest { private final PlatformDetector detector = new PlatformDetector();