preparing for another refactoring...

This commit is contained in:
Relism
2026-03-29 23:16:41 +02:00
parent 2edd68b0aa
commit b5d4481502
69 changed files with 4329 additions and 1076 deletions
@@ -1,7 +1,7 @@
package dev.relism.ext.routeviewer;
import dev.relism.ext.routeviewer.model.RouteGraph;
import dev.relism.extension.ExtensionContext;
import dev.relism.extension.FlashContext;
import dev.relism.extension.FlashExtension;
import dev.relism.extension.FlashRegistrar;
import dev.relism.http.ContentType;
@@ -36,7 +36,7 @@ import dev.relism.http.ContentType;
* }</pre>
*
* <p>All route metadata is collected once at boot time via
* {@link ExtensionContext#addRouteListener}. Zero overhead on the request hot-path.
* {@link FlashContext#addRouteListener}. Zero overhead on the request hot-path.
*/
public class RouteViewerExtension implements FlashExtension {
@@ -55,7 +55,7 @@ public class RouteViewerExtension implements FlashExtension {
public RouteViewerExtension(String path) { this.path = path; }
@Override
public void install(FlashRegistrar app, ExtensionContext ctx) {
public void install(FlashRegistrar app, FlashContext ctx) {
RouteViewerHandler shell = new RouteViewerHandler();
RouteViewerDataHandler data = new RouteViewerDataHandler(graph);
@@ -47,6 +47,11 @@ public record RouteRecord(
/**
* Walks the superclass chain, stopping before {@code RequestHandler}.
* {@code RequestHandler} is the universal root — showing it adds no information.
*
* <p>Names are produced by {@link #displayName(Class)} so that static inner classes
* appear as {@code OuterClass.InnerClass} (e.g. {@code PostHandlers.List}) rather
* than the ambiguous simple name ({@code List}). This guarantees globally unique
* display labels in the React Flow graph regardless of inner-class naming collisions.
*/
private static List<String> buildAbstractionChain(Class<?> cls) {
if (cls == null) return List.of();
@@ -54,12 +59,31 @@ public record RouteRecord(
Class<?> c = cls;
while (c != null && !c.equals(Object.class)) {
if (ROOT_HANDLER.equals(c.getSimpleName())) break;
chain.add(c.getSimpleName());
chain.add(displayName(c));
c = c.getSuperclass();
}
return List.copyOf(chain);
}
/**
* Returns a human-readable, globally unique display name for a handler class.
*
* <ul>
* <li>Top-level class {@code HtmlHandler} → {@code "HtmlHandler"}</li>
* <li>Static inner class {@code PostHandlers$List} → {@code "PostHandlers.List"}</li>
* <li>Deeply nested {@code A$B$C} → {@code "A.B.C"}</li>
* </ul>
*
* Strategy: take {@code c.getName()} (binary name with {@code $} separators),
* strip the package prefix, then replace {@code $} with {@code .}.
*/
private static String displayName(Class<?> c) {
String binary = c.getName(); // e.g. dev.relism.bench.handler.api.PostHandlers$List
int lastDot = binary.lastIndexOf('.');
String local = lastDot >= 0 ? binary.substring(lastDot + 1) : binary; // PostHandlers$List
return local.replace('$', '.'); // PostHandlers.List
}
private static List<String> buildPointcuts(Class<?> cls) {
if (cls == null) return List.of();
List<String> pointcuts = new ArrayList<>();
File diff suppressed because one or more lines are too long