From 34c04a951c425a551beeb4fa8408b1ec5c40a5e1 Mon Sep 17 00:00:00 2001 From: Colin Sharples Date: Sat, 26 Sep 2026 12:22:52 +1200 Subject: [PATCH] One icon controller, for whichever library is on the classpath (#93) jmsfx-creator has run against any symbology library since #76. jmsfx-server did not: it compiled against jmsfx-standard, and its icon API was 23 controllers, one per symbol set, each binding IconRestController's six type parameters to one set's generated enums. Those subclasses existed for one reason. Spring converts a @PathVariable of an enum type through Enum.valueOf, so a handler had to name a concrete enum to accept one - which made the class per-set and the module per-library. #90 is what that cost: several bindings were wrong, and only a request could reveal it. The symbol set moves into the path and a HandlerMethodArgumentResolver does the resolving. A resolver can do what a Converter cannot - see the rest of the request - so every value is resolved within the symbol set named earlier in the same path, and the handlers take jmsfx-core's interfaces. No generated type is named anywhere in the module now, and 23 files are gone. The URLs are unchanged. Each subclass's prefix was SymbolSetSummary.pathFor applied to its set, so it is matched rather than hard-coded, and path segments are still the enum constant names CodeElementSummary publishes. WebController and IconGeneratorController resolve through IconLibrary.discover() rather than SymbolSetEnum.values(). Two things this turned up: - The server never declared what it compiled against. jmsfx-core arrived transitively through jmsfx-standard, so demoting that dependency broke the compile until jmsfx-core was declared - which it should have been all along. - jmsfx-standard is runtime scope but not optional, unlike jmsfx-creator's. spring-boot:repackage leaves optional dependencies out of BOOT-INF/lib, so the fat jar started and then failed every request with "No IconLibrary on the classpath". optional is the wrong tool here anyway: it stops a dependency reaching consumers, and nothing consumes the server as a library. runtime alone is what stops anything compiling against it, and it keeps the jar runnable with a default library - swapping that one jar is then the whole of "an instance per library". One behavioural change, deliberate: an unknown entity, modifier or amplifier now answers 404 rather than 400. Enum conversion failing was a type mismatch, hence 400; a value that does not exist in the library is a missing resource, and an unknown symbol set already answered 404. Everything unknown now answers the same way. Verified against the live 1.5.0 server, which still runs the old controllers: 186 URLs covering every symbol set and every endpoint family, compared byte-for-byte - all identical. Plus a 648-request sweep of the reworked server, all 200, and the five pages and the Browse fragment rendering the same icon URLs as before. Closes #93 Co-Authored-By: Claude Opus 5 --- jmsfx-server/pom.xml | 6 + .../ctgnz/jmsfx/server/SpringWebConfig.java | 19 +++ .../ctgnz/jmsfx/server/WebController.java | 9 +- .../server/icon/ActivityIconController.java | 22 --- .../jmsfx/server/icon/AirIconController.java | 22 --- .../server/icon/AirMissileIconController.java | 22 --- .../server/icon/CommonIconController.java | 22 --- .../icon/ControlMeasureIconController.java | 22 --- .../icon/CyberspaceAirIconController.java | 22 --- ...aceDismountedIndividualIconController.java | 22 --- .../server/icon/CyberspaceIconController.java | 22 --- ...CyberspaceLandEquipmentIconController.java | 22 --- ...erspaceLandInstallationIconController.java | 22 --- .../CyberspaceLandUnitIconController.java | 22 --- ...CyberspaceSeaSubsurfaceIconController.java | 22 --- .../CyberspaceSeaSurfaceIconController.java | 22 --- .../icon/CyberspaceSpaceIconController.java | 22 --- .../DismountedIndividualIconController.java | 22 --- .../server/icon/IconGeneratorController.java | 11 +- .../jmsfx/server/icon/IconRestController.java | 122 +++++++-------- .../icon/LandCivilianIconController.java | 22 --- .../icon/LandEquipmentIconController.java | 22 --- .../icon/LandInstallationIconController.java | 22 --- .../server/icon/LandUnitsIconController.java | 22 --- .../icon/MineWarfareIconController.java | 22 --- .../icon/SeaSubsurfaceIconController.java | 22 --- .../server/icon/SeaSurfaceIconController.java | 22 --- .../server/icon/SpaceIconController.java | 22 --- .../icon/SymbologyArgumentResolver.java | 140 ++++++++++++++++++ 29 files changed, 231 insertions(+), 582 deletions(-) delete mode 100644 jmsfx-server/src/main/java/io/github/ctgnz/jmsfx/server/icon/ActivityIconController.java delete mode 100644 jmsfx-server/src/main/java/io/github/ctgnz/jmsfx/server/icon/AirIconController.java delete mode 100644 jmsfx-server/src/main/java/io/github/ctgnz/jmsfx/server/icon/AirMissileIconController.java delete mode 100644 jmsfx-server/src/main/java/io/github/ctgnz/jmsfx/server/icon/CommonIconController.java delete mode 100644 jmsfx-server/src/main/java/io/github/ctgnz/jmsfx/server/icon/ControlMeasureIconController.java delete mode 100644 jmsfx-server/src/main/java/io/github/ctgnz/jmsfx/server/icon/CyberspaceAirIconController.java delete mode 100644 jmsfx-server/src/main/java/io/github/ctgnz/jmsfx/server/icon/CyberspaceDismountedIndividualIconController.java delete mode 100644 jmsfx-server/src/main/java/io/github/ctgnz/jmsfx/server/icon/CyberspaceIconController.java delete mode 100644 jmsfx-server/src/main/java/io/github/ctgnz/jmsfx/server/icon/CyberspaceLandEquipmentIconController.java delete mode 100644 jmsfx-server/src/main/java/io/github/ctgnz/jmsfx/server/icon/CyberspaceLandInstallationIconController.java delete mode 100644 jmsfx-server/src/main/java/io/github/ctgnz/jmsfx/server/icon/CyberspaceLandUnitIconController.java delete mode 100644 jmsfx-server/src/main/java/io/github/ctgnz/jmsfx/server/icon/CyberspaceSeaSubsurfaceIconController.java delete mode 100644 jmsfx-server/src/main/java/io/github/ctgnz/jmsfx/server/icon/CyberspaceSeaSurfaceIconController.java delete mode 100644 jmsfx-server/src/main/java/io/github/ctgnz/jmsfx/server/icon/CyberspaceSpaceIconController.java delete mode 100644 jmsfx-server/src/main/java/io/github/ctgnz/jmsfx/server/icon/DismountedIndividualIconController.java delete mode 100644 jmsfx-server/src/main/java/io/github/ctgnz/jmsfx/server/icon/LandCivilianIconController.java delete mode 100644 jmsfx-server/src/main/java/io/github/ctgnz/jmsfx/server/icon/LandEquipmentIconController.java delete mode 100644 jmsfx-server/src/main/java/io/github/ctgnz/jmsfx/server/icon/LandInstallationIconController.java delete mode 100644 jmsfx-server/src/main/java/io/github/ctgnz/jmsfx/server/icon/LandUnitsIconController.java delete mode 100644 jmsfx-server/src/main/java/io/github/ctgnz/jmsfx/server/icon/MineWarfareIconController.java delete mode 100644 jmsfx-server/src/main/java/io/github/ctgnz/jmsfx/server/icon/SeaSubsurfaceIconController.java delete mode 100644 jmsfx-server/src/main/java/io/github/ctgnz/jmsfx/server/icon/SeaSurfaceIconController.java delete mode 100644 jmsfx-server/src/main/java/io/github/ctgnz/jmsfx/server/icon/SpaceIconController.java create mode 100644 jmsfx-server/src/main/java/io/github/ctgnz/jmsfx/server/icon/SymbologyArgumentResolver.java diff --git a/jmsfx-server/pom.xml b/jmsfx-server/pom.xml index f0c0de26..4bd200c2 100644 --- a/jmsfx-server/pom.xml +++ b/jmsfx-server/pom.xml @@ -25,9 +25,15 @@ spring-boot-starter-thymeleaf ${spring.boot.version} + + io.github.ctgnz + jmsfx-core + ${project.version} + io.github.ctgnz jmsfx-standard + runtime 2.0.0-SNAPSHOT