From dae17dfc6012e6d97b920f969eb43d8d5532ffd7 Mon Sep 17 00:00:00 2001 From: Anthony Stirling <77850077+Frooodle@users.noreply.github.com> Date: Mon, 24 Aug 2026 16:13:08 +0100 Subject: [PATCH] Apply review suggestions from balazs-szucs --- .../stirling/software/common/util/GeneralUtils.java | 7 +++++-- .../formdetection/catalog/ModelCatalogService.java | 3 +-- .../controller/FormDetectionController.java | 4 ---- .../controller/FormDetectionModelController.java | 4 ---- .../formdetection/inference/OnnxFormDetector.java | 4 ++-- .../formdetection/render/CoordinateMapper.java | 12 ++++++------ 6 files changed, 14 insertions(+), 20 deletions(-) diff --git a/app/common/src/main/java/stirling/software/common/util/GeneralUtils.java b/app/common/src/main/java/stirling/software/common/util/GeneralUtils.java index ea753d27c6..01dd700296 100644 --- a/app/common/src/main/java/stirling/software/common/util/GeneralUtils.java +++ b/app/common/src/main/java/stirling/software/common/util/GeneralUtils.java @@ -876,9 +876,12 @@ public class GeneralUtils { */ private final Object SETTINGS_WRITE_LOCK = new Object(); + /** Dotted-notation separator for settings keys; a literal, so compile it once. */ + private final Pattern SETTINGS_KEY_SEPARATOR = Pattern.compile("\\."); + public void saveKeyToSettings(String key, Object newValue) throws IOException { synchronized (SETTINGS_WRITE_LOCK) { - String[] keyArray = key.split("\\."); + String[] keyArray = SETTINGS_KEY_SEPARATOR.split(key); Path settingsPath = Path.of(InstallationPathConfig.getSettingsPath()); YamlHelper settingsYaml = new YamlHelper(settingsPath); settingsYaml.updateValue(Arrays.asList(keyArray), newValue); @@ -909,7 +912,7 @@ public class GeneralUtils { for (Map.Entry entry : settingsMap.entrySet()) { String key = entry.getKey(); Object value = entry.getValue(); - String[] keyArray = key.split("\\."); + String[] keyArray = SETTINGS_KEY_SEPARATOR.split(key); settingsYaml.updateValue(Arrays.asList(keyArray), value); } diff --git a/app/proprietary/src/main/java/stirling/software/proprietary/formdetection/catalog/ModelCatalogService.java b/app/proprietary/src/main/java/stirling/software/proprietary/formdetection/catalog/ModelCatalogService.java index c4cf1f23a1..a56fdc918b 100644 --- a/app/proprietary/src/main/java/stirling/software/proprietary/formdetection/catalog/ModelCatalogService.java +++ b/app/proprietary/src/main/java/stirling/software/proprietary/formdetection/catalog/ModelCatalogService.java @@ -35,8 +35,7 @@ public class ModelCatalogService { @PostConstruct void load() { try (InputStream is = new ClassPathResource(CATALOG_RESOURCE).getInputStream()) { - List loaded = - objectMapper.readValue(is, new TypeReference>() {}); + List loaded = objectMapper.readValue(is, new TypeReference<>() {}); Map map = new LinkedHashMap<>(); for (ModelCatalogEntry entry : loaded) { if (entry.getId() != null && !entry.getId().isBlank()) { diff --git a/app/proprietary/src/main/java/stirling/software/proprietary/formdetection/controller/FormDetectionController.java b/app/proprietary/src/main/java/stirling/software/proprietary/formdetection/controller/FormDetectionController.java index 2d6936b4d5..4a128fafd3 100644 --- a/app/proprietary/src/main/java/stirling/software/proprietary/formdetection/controller/FormDetectionController.java +++ b/app/proprietary/src/main/java/stirling/software/proprietary/formdetection/controller/FormDetectionController.java @@ -41,10 +41,6 @@ import stirling.software.proprietary.formdetection.service.FormDetectionModelMan * Server-side detection endpoint. Gated behind the {@code form-detection} endpoint key, which is * disabled until a model is installed (so the tool tile is greyed in the UI). Returns the shared * detection schema, or - when {@code applyToPdf=true} - the AcroForm-applied PDF. - * - *

Deliberately under {@code /api/v1/form}, not {@code /api/v1/ai}: anything on the AI prefix is - * classified billable by {@code BillableOperationClassifier} and blocked with 402 when the instance - * is unlinked - which would gate on-device detection that never touches the server. */ @Slf4j @RestController diff --git a/app/proprietary/src/main/java/stirling/software/proprietary/formdetection/controller/FormDetectionModelController.java b/app/proprietary/src/main/java/stirling/software/proprietary/formdetection/controller/FormDetectionModelController.java index 9b8b34cca6..d9299952ca 100644 --- a/app/proprietary/src/main/java/stirling/software/proprietary/formdetection/controller/FormDetectionModelController.java +++ b/app/proprietary/src/main/java/stirling/software/proprietary/formdetection/controller/FormDetectionModelController.java @@ -26,10 +26,6 @@ import stirling.software.proprietary.formdetection.service.FormDetectionModelMan * Admin-managed lifecycle for the Auto Form Detection model. Lives under the never-gated {@code * form-detection-model} endpoint key so install/status stay reachable while the feature itself (the * {@code form-detection} detect endpoint) is disabled until a model is ready. - * - *

Deliberately under {@code /api/v1/form}, not {@code /api/v1/ai}: anything on the AI prefix is - * classified billable by {@code BillableOperationClassifier} and blocked with 402 when the instance - * is unlinked - which would gate on-device detection that never touches the server. */ @Slf4j @RestController diff --git a/app/proprietary/src/main/java/stirling/software/proprietary/formdetection/inference/OnnxFormDetector.java b/app/proprietary/src/main/java/stirling/software/proprietary/formdetection/inference/OnnxFormDetector.java index 188cb71b04..dac870ffd1 100644 --- a/app/proprietary/src/main/java/stirling/software/proprietary/formdetection/inference/OnnxFormDetector.java +++ b/app/proprietary/src/main/java/stirling/software/proprietary/formdetection/inference/OnnxFormDetector.java @@ -168,8 +168,8 @@ public class OnnxFormDetector implements FormDetectionEngine { if (session != null) { try { session.close(); - } catch (Exception ignored) { - // ignore + } catch (Exception _) { + // already closing } session = null; } diff --git a/app/proprietary/src/main/java/stirling/software/proprietary/formdetection/render/CoordinateMapper.java b/app/proprietary/src/main/java/stirling/software/proprietary/formdetection/render/CoordinateMapper.java index 63bc25e9da..32b2363d67 100644 --- a/app/proprietary/src/main/java/stirling/software/proprietary/formdetection/render/CoordinateMapper.java +++ b/app/proprietary/src/main/java/stirling/software/proprietary/formdetection/render/CoordinateMapper.java @@ -1,5 +1,7 @@ package stirling.software.proprietary.formdetection.render; +import lombok.experimental.UtilityClass; + import stirling.software.proprietary.formdetection.inference.Yolo; import stirling.software.proprietary.formdetection.model.DetectedField; @@ -9,12 +11,10 @@ import stirling.software.proprietary.formdetection.model.DetectedField; * live in. The bitmap is display space: /Rotate baked in and the crop box anchored at (0,0), so the * mapping is scale + Y-flip, then the inverse page rotation, then the crop-box translation. */ -public final class CoordinateMapper { +@UtilityClass +public class CoordinateMapper { - private CoordinateMapper() {} - - public static DetectedField.RectPt toPdfPoints( - Yolo.Detection d, PageRasterizer.RasterPage page) { + public DetectedField.RectPt toPdfPoints(Yolo.Detection d, PageRasterizer.RasterPage page) { float sx = page.scaleX() > 0 ? page.scaleX() : 1f; float sy = page.scaleY() > 0 ? page.scaleY() : 1f; @@ -66,7 +66,7 @@ public final class CoordinateMapper { return new DetectedField.RectPt(x + page.cropLlxPt(), y + page.cropLlyPt(), w, h); } - private static double clamp(double v, double lo, double hi) { + private double clamp(double v, double lo, double hi) { return v < lo ? lo : Math.min(v, hi); } }