Bug fixes
This commit is contained in:
@@ -16,59 +16,68 @@ import java.nio.charset.StandardCharsets;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Dispatches Java WebPages using @Route annotation.
|
||||
* Dispatches Java WebPages using {@code @Route} annotation.
|
||||
*
|
||||
* <p>This dispatcher relies on {@link JavaRouteRegistry} for route-to-source mapping
|
||||
* and uses {@link JavaPageCache} to compile/load classes from the content tree.
|
||||
*/
|
||||
public final class JavaPageDispatcher {
|
||||
|
||||
private static final JavaRouteRegistry ROUTES = new JavaRouteRegistry();
|
||||
private static final JavaPageCache CACHE = new JavaPageCache();
|
||||
|
||||
private JavaPageDispatcher() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to dispatch a request to a Java WebPage.
|
||||
*
|
||||
* @param client connected client
|
||||
* @param server protocol web server
|
||||
* @param request request packet
|
||||
* @return response packet or {@code null} if no Java route matches and static file handling should proceed
|
||||
* @throws Exception on unexpected failures
|
||||
*/
|
||||
public static WebResponsePacket dispatch(
|
||||
CustomConnectedClient client,
|
||||
ProtocolWebServer server,
|
||||
WebRequestPacket request
|
||||
) throws Exception {
|
||||
|
||||
if (request.getPath() == null) return null;
|
||||
if (request == null || request.getPath() == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String route = request.getPath();
|
||||
if (!route.startsWith("/")) route = "/" + route;
|
||||
if (!route.startsWith("/")) {
|
||||
route = "/" + route;
|
||||
}
|
||||
|
||||
File contentRoot = server.getContentFolder();
|
||||
ROUTES.refreshIfNeeded(contentRoot);
|
||||
|
||||
JavaRouteRegistry.RouteLookupResult found = ROUTES.find(route);
|
||||
|
||||
// If no @Route match, still detect "requested a .java-backed path by filename"
|
||||
// (legacy behavior): if a matching *.java exists, compile/load but return error.
|
||||
if (found == null) {
|
||||
String p = route.startsWith("/") ? route.substring(1) : route;
|
||||
File javaFile = new File(contentRoot, p + ".java");
|
||||
if (javaFile.exists() && javaFile.isFile()) {
|
||||
// Compile/load but do not serve.
|
||||
new JavaPageCache().getOrCompile(javaFile);
|
||||
return error(501, "Java class exists but has no @Route: " + route);
|
||||
}
|
||||
return null; // not a Java route -> let file server handle it
|
||||
return null;
|
||||
}
|
||||
|
||||
// If it has @Route but is not a WebPage, compile/load but return error.
|
||||
if (!found.routable()) {
|
||||
long contentLm = ROUTES.currentContentLastModified(contentRoot);
|
||||
|
||||
JavaPageCache.LoadedClass loaded = CACHE.getOrCompile(contentRoot, found.sourceFile(), contentLm);
|
||||
Class<?> clazz = loaded.clazz();
|
||||
|
||||
// Verify that the loaded class is actually routable.
|
||||
if (!WebPage.class.isAssignableFrom(clazz)) {
|
||||
return error(500, "Class has @Route but is not a WebPage: " + found.fqcn());
|
||||
}
|
||||
|
||||
// Load and execute
|
||||
Class<?> clazz = Class.forName(found.fqcn());
|
||||
Object instance = clazz.getDeclaredConstructor().newInstance();
|
||||
|
||||
if (!(instance instanceof WebPage page)) {
|
||||
return error(500, "Routed class is not a WebPage: " + found.fqcn());
|
||||
}
|
||||
WebPage page = (WebPage) instance;
|
||||
|
||||
WebHasher hasher = (server instanceof WebServer ws) ? ws.getHasher() : null;
|
||||
if (hasher == null) return error(500, "WebHasher missing on server instance.");
|
||||
if (hasher == null) {
|
||||
return error(500, "WebHasher missing on server instance.");
|
||||
}
|
||||
|
||||
WebPageContext ctx = new WebPageContext(client, server, request, new RequestParams(request), hasher);
|
||||
return page.handle(ctx);
|
||||
@@ -82,4 +91,4 @@ public final class JavaPageDispatcher {
|
||||
msg.getBytes(StandardCharsets.UTF_8)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user