fix: enhance global key validation and update template parameters
This commit is contained in:
+10
-16
@@ -22,7 +22,6 @@ import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
final class JteRuntime implements ViewRuntimeBridge<JteTarget> {
|
||||
private static final String GLOBAL_NAMESPACE = "global";
|
||||
|
||||
private final JteSettings settings;
|
||||
private final List<GlobalValue> globals;
|
||||
@@ -60,30 +59,25 @@ final class JteRuntime implements ViewRuntimeBridge<JteTarget> {
|
||||
}
|
||||
|
||||
private ViewModel merge(Request req, ViewModel local) {
|
||||
LinkedHashMap<String, Object> values = null;
|
||||
LinkedHashMap<String, Object> values = new LinkedHashMap<>();
|
||||
|
||||
if (!globals.isEmpty()) {
|
||||
LinkedHashMap<String, Object> globalMap = new LinkedHashMap<>();
|
||||
for (GlobalValue binding : globals) {
|
||||
Object resolved = binding.resolver().apply(req);
|
||||
globalMap.put(binding.key(), ViewModel.unwrapValue(resolved));
|
||||
}
|
||||
if (!globalMap.isEmpty()) {
|
||||
values = new LinkedHashMap<>();
|
||||
values.put(GLOBAL_NAMESPACE, Collections.unmodifiableMap(globalMap));
|
||||
}
|
||||
for (GlobalValue binding : globals) {
|
||||
Object resolved = binding.resolver().apply(req);
|
||||
values.put(binding.key(), ViewModel.unwrapValue(resolved));
|
||||
}
|
||||
|
||||
if (local != null) {
|
||||
Map<String, Object> localMap = local.toMap();
|
||||
if (localMap.containsKey(GLOBAL_NAMESPACE)) {
|
||||
throw new IllegalStateException("ViewModel key 'global' is reserved for framework globals");
|
||||
for (String key : localMap.keySet()) {
|
||||
if (values.containsKey(key)) {
|
||||
throw new IllegalStateException(
|
||||
"ViewModel key '" + key + "' conflicts with a registered global");
|
||||
}
|
||||
}
|
||||
if (values == null) return ViewModel.copyOf(local);
|
||||
values.putAll(localMap);
|
||||
}
|
||||
|
||||
if (values == null || values.isEmpty()) return ViewModel.empty();
|
||||
if (values.isEmpty()) return ViewModel.empty();
|
||||
return ViewModel.owned(values);
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -38,7 +38,7 @@ class JteRuntimeTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
void render_rejectsReservedGlobalKeyInLocalModel() {
|
||||
void render_rejectsConflictingLocalKey() {
|
||||
JteRuntime runtime = new JteRuntime(
|
||||
JteSettings.builder().templateRoot("/templates").developmentMode(true).build(),
|
||||
List.of(new GlobalValue("appName", req -> "Flash"))
|
||||
@@ -48,12 +48,12 @@ class JteRuntimeTest {
|
||||
runtime.render(new JteHandler() {
|
||||
@Override
|
||||
public ViewModel render(Request req) {
|
||||
return ViewModel.of("global", "bad");
|
||||
return ViewModel.of("appName", "override"); // collide con global
|
||||
}
|
||||
}, new JteTarget("pages/home.jte", ContentType.TEXT_HTML), null, new Response(200, ContentType.JSON))
|
||||
);
|
||||
|
||||
assertTrue(ex.getMessage().contains("reserved"));
|
||||
assertTrue(ex.getMessage().contains("appName"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
@import dev.relism.flash.ext.view.jte.model.HomePage
|
||||
@import java.util.Map
|
||||
@param HomePage page
|
||||
@param String build
|
||||
@param Map<String, Object> global
|
||||
@param String appName
|
||||
|
||||
<h1>${page.title()}</h1>
|
||||
<p>${page.author()}</p>
|
||||
<small>${build}</small>
|
||||
<small>${(String) global.get("appName")}</small>
|
||||
<small>${appName}</small>
|
||||
Reference in New Issue
Block a user