fix: merge jte extension refactor with static serving features
- Move JteStaticServing to dev.relism.flash package - Fix imports in HttpStatus and test files - Add fluent config methods to JteExtension (templateRoot, serveStatics, staticPrefix, etc.) - Implement routes() for static asset serving with HEAD support - Include Main.java entry point
This commit is contained in:
+56
-4
@@ -1,5 +1,7 @@
|
||||
package dev.relism.flash.ext.view.jte;
|
||||
|
||||
import dev.relism.flash.extension.FlashContext;
|
||||
import dev.relism.flash.extension.FlashRegistrar;
|
||||
import dev.relism.flash.ext.view.core.BaseViewExtension;
|
||||
import dev.relism.flash.ext.view.core.GlobalValue;
|
||||
import dev.relism.flash.ext.view.core.ViewRuntimeBridge;
|
||||
@@ -10,9 +12,6 @@ import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* Opinionated jte SSR extension for Flash.
|
||||
*/
|
||||
public final class JteExtension extends BaseViewExtension<JteTarget> {
|
||||
private final JteSettings settings;
|
||||
|
||||
@@ -21,7 +20,7 @@ public final class JteExtension extends BaseViewExtension<JteTarget> {
|
||||
}
|
||||
|
||||
public JteExtension() {
|
||||
this(JteSettings.builder().build());
|
||||
this.settings = JteSettings.builder().build();
|
||||
}
|
||||
|
||||
public JteExtension(Consumer<JteSettings.Builder> customizer) {
|
||||
@@ -34,6 +33,41 @@ public final class JteExtension extends BaseViewExtension<JteTarget> {
|
||||
this.settings = settings;
|
||||
}
|
||||
|
||||
public JteExtension templateRoot(String templateRoot) {
|
||||
return new JteExtension(settings.toBuilder().templateRoot(templateRoot).build());
|
||||
}
|
||||
|
||||
public JteExtension serveStatics(boolean serveStatics) {
|
||||
return new JteExtension(settings.toBuilder().serveStatics(serveStatics).build());
|
||||
}
|
||||
|
||||
public JteExtension staticPrefix(String staticPrefix) {
|
||||
return new JteExtension(settings.toBuilder().staticPrefix(staticPrefix).build());
|
||||
}
|
||||
|
||||
public JteExtension withStaticCors() {
|
||||
return new JteExtension(settings.toBuilder().enableStaticCors(true).build());
|
||||
}
|
||||
|
||||
public JteExtension staticCors(Consumer<JteSettings.Builder> corsConfig) {
|
||||
JteSettings.Builder builder = settings.toBuilder();
|
||||
builder.enableStaticCors(true);
|
||||
corsConfig.accept(builder);
|
||||
return new JteExtension(builder.build());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void routes(FlashRegistrar<?> app, FlashContext ctx) {
|
||||
if (!settings.serveStatics()) return;
|
||||
JteStaticServing staticServing = JteStaticServing.load(settings);
|
||||
if (staticServing == null) return;
|
||||
|
||||
String wildcard = settings.staticPrefix() + "/**";
|
||||
StaticJteHandler handler = new StaticJteHandler(staticServing);
|
||||
app.get(wildcard, handler::handle);
|
||||
app.head(wildcard, (req, res) -> { staticServing.serve(req, res, true); return null; });
|
||||
}
|
||||
|
||||
@Override
|
||||
public JteExtension addGlobal(String key, Function<Request, Object> resolver) {
|
||||
super.addGlobal(key, resolver);
|
||||
@@ -60,6 +94,24 @@ public final class JteExtension extends BaseViewExtension<JteTarget> {
|
||||
}
|
||||
}
|
||||
|
||||
JteSettings getSettings() {
|
||||
return settings;
|
||||
}
|
||||
|
||||
private static final class StaticJteHandler extends dev.relism.flash.models.RequestHandler {
|
||||
private final JteStaticServing serving;
|
||||
|
||||
StaticJteHandler(JteStaticServing serving) {
|
||||
this.serving = serving;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object handle(dev.relism.flash.models.Request req, dev.relism.flash.models.Response res) {
|
||||
serving.serve(req, res, false);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static void ensureJtePresent() {
|
||||
try {
|
||||
Class.forName("gg.jte.TemplateEngine", false, JteExtension.class.getClassLoader());
|
||||
|
||||
+5
-5
@@ -1,8 +1,8 @@
|
||||
package dev.relism.ext.view.jte;
|
||||
package dev.relism.flash.ext.view.jte;
|
||||
|
||||
import dev.relism.http.HttpStatus;
|
||||
import dev.relism.models.Request;
|
||||
import dev.relism.models.Response;
|
||||
import dev.relism.flash.http.HttpStatus;
|
||||
import dev.relism.flash.models.Request;
|
||||
import dev.relism.flash.models.Response;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -202,4 +202,4 @@ final class JteStaticServing {
|
||||
}
|
||||
|
||||
private record RangeSlice(int start, int end, int length) {}
|
||||
}
|
||||
}
|
||||
+17
-23
@@ -92,7 +92,7 @@ class JteExtensionTest {
|
||||
void routes_register_static_wildcard_when_enabled() {
|
||||
JteExtension ext = new JteExtension(cfg -> cfg.staticPrefix("/assets"));
|
||||
TestRegistrar app = new TestRegistrar();
|
||||
ext.routes(app, new dev.relism.extension.FlashContext());
|
||||
ext.routes(app, new dev.relism.flash.extension.FlashContext());
|
||||
assertTrue(app.routes.containsKey("GET /assets/**"));
|
||||
assertTrue(app.routes.containsKey("HEAD /assets/**"));
|
||||
}
|
||||
@@ -101,7 +101,7 @@ class JteExtensionTest {
|
||||
void routes_do_not_register_static_when_disabled() {
|
||||
JteExtension ext = new JteExtension().serveStatics(false);
|
||||
TestRegistrar app = new TestRegistrar();
|
||||
ext.routes(app, new dev.relism.extension.FlashContext());
|
||||
ext.routes(app, new dev.relism.flash.extension.FlashContext());
|
||||
assertTrue(app.routes.isEmpty());
|
||||
}
|
||||
|
||||
@@ -111,10 +111,10 @@ class JteExtensionTest {
|
||||
.staticPrefix("/assets")
|
||||
.largeFileThresholdBytes(1));
|
||||
TestRegistrar app = new TestRegistrar();
|
||||
ext.routes(app, new dev.relism.extension.FlashContext());
|
||||
ext.routes(app, new dev.relism.flash.extension.FlashContext());
|
||||
|
||||
Request req = request("/assets/sample.css", null, null, null);
|
||||
Response res = new Response(200, dev.relism.http.ContentType.TEXT_PLAIN);
|
||||
Response res = new Response(200, dev.relism.flash.http.ContentType.TEXT_PLAIN);
|
||||
Object out = app.routes.get("GET /assets/**").handle(req, res);
|
||||
|
||||
assertEquals(null, out);
|
||||
@@ -124,13 +124,7 @@ class JteExtensionTest {
|
||||
}
|
||||
|
||||
private static JteSettings readSettings(JteExtension ext) {
|
||||
try {
|
||||
var f = JteExtension.class.getDeclaredField("settings");
|
||||
f.setAccessible(true);
|
||||
return (JteSettings) f.get(ext);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return ext.getSettings();
|
||||
}
|
||||
|
||||
private static void invokeValidate(JteExtension ext, Class<? extends RequestHandler> type) throws Exception {
|
||||
@@ -147,39 +141,39 @@ class JteExtensionTest {
|
||||
}
|
||||
|
||||
private static Request request(String path, String query, String acceptEncoding, String origin) {
|
||||
dev.relism.models.HeaderMap headers = new dev.relism.models.HeaderMap();
|
||||
dev.relism.flash.models.HeaderMap headers = new dev.relism.flash.models.HeaderMap();
|
||||
String raw = "Host: localhost\r\n";
|
||||
if (acceptEncoding != null) raw += "Accept-Encoding: " + acceptEncoding + "\r\n";
|
||||
if (origin != null) raw += "Origin: " + origin + "\r\n";
|
||||
byte[] bytes = raw.getBytes(StandardCharsets.UTF_8);
|
||||
headers.reset(bytes, 0, bytes.length);
|
||||
|
||||
dev.relism.models.RequestLine line = new dev.relism.models.RequestLine(
|
||||
dev.relism.http.HttpMethod.GET,
|
||||
new dev.relism.routing.routers.fastpathrouter.FastPathViews.StringByteView(path),
|
||||
query == null ? null : new dev.relism.routing.routers.fastpathrouter.FastPathViews.StringByteView(query),
|
||||
new dev.relism.routing.routers.fastpathrouter.FastPathViews.StringByteView("HTTP/1.1"),
|
||||
dev.relism.flash.models.RequestLine line = new dev.relism.flash.models.RequestLine(
|
||||
dev.relism.flash.http.HttpMethod.GET,
|
||||
new dev.relism.flash.routing.routers.fastpathrouter.FastPathViews.StringByteView(path),
|
||||
query == null ? null : new dev.relism.flash.routing.routers.fastpathrouter.FastPathViews.StringByteView(query),
|
||||
new dev.relism.flash.routing.routers.fastpathrouter.FastPathViews.StringByteView("HTTP/1.1"),
|
||||
headers
|
||||
);
|
||||
return new Request(line, new byte[0]);
|
||||
}
|
||||
|
||||
private static final class TestRegistrar extends dev.relism.extension.FlashRegistrar<TestRegistrar> {
|
||||
private static final class TestRegistrar extends dev.relism.flash.extension.FlashRegistrar<TestRegistrar> {
|
||||
private final Map<String, RequestHandler> routes = new HashMap<>();
|
||||
private final List<dev.relism.routing.Middleware> mws = new ArrayList<>();
|
||||
private final List<dev.relism.flash.routing.Middleware> mws = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public dev.relism.extension.FlashContext ctx() {
|
||||
return new dev.relism.extension.FlashContext();
|
||||
public dev.relism.flash.extension.FlashContext ctx() {
|
||||
return new dev.relism.flash.extension.FlashContext();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addRoute(dev.relism.http.HttpMethod method, String path, RequestHandler handler, List<dev.relism.routing.Middleware> mw) {
|
||||
protected void addRoute(dev.relism.flash.http.HttpMethod method, String path, RequestHandler handler, List<dev.relism.flash.routing.Middleware> mw) {
|
||||
routes.put(method.name() + " " + path, handler);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addMiddleware(dev.relism.routing.Middleware mw) {
|
||||
protected void addMiddleware(dev.relism.flash.routing.Middleware mw) {
|
||||
mws.add(mw);
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
package dev.relism.ext.view.jte;
|
||||
package dev.relism.flash.ext.view.jte;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@@ -47,4 +47,4 @@ class JteStaticServingTest {
|
||||
assertEquals(-1, JteStaticServing.rangeLength("bytes=100-120", 100));
|
||||
assertEquals(-1, JteStaticServing.rangeLength("invalid", 100));
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user