Files
WebServer/src/main/java/org/openautonomousconnection/webserver/runtime/JavaPageDispatcher.java

115 lines
4.6 KiB
Java
Raw Normal View History

2025-12-12 21:16:13 +01:00
package org.openautonomousconnection.webserver.runtime;
2026-02-22 17:26:22 +01:00
import org.openautonomousconnection.protocol.packets.v1_0_1.beta.web.impl.resource.WebResourceRequestPacket;
import org.openautonomousconnection.protocol.packets.v1_0_1.beta.web.impl.resource.WebResourceResponsePacket;
2026-02-01 19:28:45 +01:00
import org.openautonomousconnection.protocol.side.server.CustomConnectedClient;
2025-12-12 21:16:13 +01:00
import org.openautonomousconnection.protocol.side.web.ProtocolWebServer;
2026-01-19 14:23:53 +01:00
import org.openautonomousconnection.webserver.WebServer;
2025-12-12 21:16:13 +01:00
import org.openautonomousconnection.webserver.api.WebPage;
import org.openautonomousconnection.webserver.api.WebPageContext;
2026-02-08 21:40:23 +01:00
import org.openautonomousconnection.webserver.utils.HeaderMaps;
2026-01-19 14:23:53 +01:00
import org.openautonomousconnection.webserver.utils.RequestParams;
2026-02-06 18:03:32 +01:00
import org.openautonomousconnection.webserver.utils.WebHasher;
2026-02-22 17:26:22 +01:00
import org.openautonomousconnection.webserver.utils.WebUrlUtil;
2025-12-12 21:16:13 +01:00
2026-01-19 14:23:53 +01:00
import java.nio.charset.StandardCharsets;
2025-12-12 21:16:13 +01:00
2026-01-19 14:23:53 +01:00
/**
2026-02-22 17:26:22 +01:00
* Dispatches Java WebPages using {@code @Route} annotation (v1.0.1-BETA).
2026-01-19 14:23:53 +01:00
*/
2025-12-12 21:16:13 +01:00
public final class JavaPageDispatcher {
2026-01-19 14:23:53 +01:00
private static final JavaRouteRegistry ROUTES = new JavaRouteRegistry();
2026-02-08 22:33:31 +01:00
private static final JavaPageCache CACHE = new JavaPageCache();
2025-12-12 21:16:13 +01:00
2026-02-06 18:03:32 +01:00
private JavaPageDispatcher() {
}
2025-12-12 21:16:13 +01:00
2026-02-08 22:33:31 +01:00
/**
* Attempts to dispatch a request to a Java WebPage.
*
* @param client connected client
* @param server protocol web server
* @param request request packet
2026-02-22 17:26:22 +01:00
* @return response packet or {@code null} if no Java route matches
2026-02-08 22:33:31 +01:00
* @throws Exception on unexpected failures
*/
2026-02-22 17:26:22 +01:00
public static WebResourceResponsePacket dispatch(
2026-02-01 19:28:45 +01:00
CustomConnectedClient client,
2025-12-12 21:16:13 +01:00
ProtocolWebServer server,
2026-02-22 17:26:22 +01:00
WebResourceRequestPacket request
2025-12-12 21:16:13 +01:00
) throws Exception {
2026-02-22 17:26:22 +01:00
if (request == null || request.getUrl() == null) {
2026-02-08 22:33:31 +01:00
return null;
}
2025-12-12 21:16:13 +01:00
2026-02-22 17:26:22 +01:00
String route = WebUrlUtil.extractPathAndQuery(request.getUrl());
if (route == null) return null;
int q = route.indexOf('?');
if (q >= 0) route = route.substring(0, q);
2026-02-27 20:31:10 +01:00
route = WebUrlUtil.normalizeRequestPath(route);
2025-12-12 21:16:13 +01:00
2026-02-22 17:26:22 +01:00
java.io.File contentRoot = server.getContentFolder();
2026-01-19 14:23:53 +01:00
ROUTES.refreshIfNeeded(contentRoot);
2025-12-12 21:16:13 +01:00
2026-01-19 14:23:53 +01:00
JavaRouteRegistry.RouteLookupResult found = ROUTES.find(route);
if (found == null) {
2026-02-08 22:33:31 +01:00
return null;
2026-01-19 14:23:53 +01:00
}
2026-02-08 22:33:31 +01:00
long contentLm = ROUTES.currentContentLastModified(contentRoot);
JavaPageCache.LoadedClass loaded = CACHE.getOrCompile(contentRoot, found.sourceFile(), contentLm);
Class<?> clazz = loaded.clazz();
if (!WebPage.class.isAssignableFrom(clazz)) {
2026-02-22 17:26:22 +01:00
return error(request, 500, "Class has @Route but is not a WebPage: " + found.fqcn());
2026-01-19 14:23:53 +01:00
}
2025-12-12 21:16:13 +01:00
Object instance = clazz.getDeclaredConstructor().newInstance();
2026-02-08 22:33:31 +01:00
WebPage page = (WebPage) instance;
2025-12-12 21:16:13 +01:00
2026-01-19 14:23:53 +01:00
WebHasher hasher = (server instanceof WebServer ws) ? ws.getHasher() : null;
2026-02-08 22:33:31 +01:00
if (hasher == null) {
2026-02-22 17:26:22 +01:00
return error(request, 500, "WebHasher missing on server instance.");
2026-02-08 22:33:31 +01:00
}
2026-01-19 14:23:53 +01:00
WebPageContext ctx = new WebPageContext(client, server, request, new RequestParams(request), hasher);
2025-12-12 21:16:13 +01:00
return page.handle(ctx);
}
2026-01-19 14:23:53 +01:00
2026-02-22 17:26:22 +01:00
private static WebResourceResponsePacket error(WebResourceRequestPacket req, int code, String msg) {
byte[] body = (msg == null ? "" : msg).getBytes(StandardCharsets.UTF_8);
// Mirror correlation from the incoming request if possible.
org.openautonomousconnection.protocol.versions.v1_0_1.beta.WebPacketHeader in =
(req != null && req.getHeader() != null)
? req.getHeader()
: new org.openautonomousconnection.protocol.versions.v1_0_1.beta.WebPacketHeader(
0, 0, 0, 0, org.openautonomousconnection.protocol.versions.v1_0_1.beta.WebPacketFlags.RESOURCE, System.currentTimeMillis()
);
org.openautonomousconnection.protocol.versions.v1_0_1.beta.WebPacketHeader out =
new org.openautonomousconnection.protocol.versions.v1_0_1.beta.WebPacketHeader(
in.getRequestId(),
in.getTabId(),
in.getPageId(),
in.getFrameId(),
in.getFlags() | org.openautonomousconnection.protocol.versions.v1_0_1.beta.WebPacketFlags.RESOURCE,
System.currentTimeMillis()
);
return new WebResourceResponsePacket(
out,
2026-01-19 14:23:53 +01:00
code,
"text/plain; charset=utf-8",
2026-02-08 21:40:23 +01:00
HeaderMaps.mutable(),
2026-02-22 17:26:22 +01:00
body,
null
2026-01-19 14:23:53 +01:00
);
}
2026-02-27 20:31:10 +01:00
}