Validate preview sessions against real classpath and module-path fixtures

This commit is contained in:
2026-11-12 09:47:59 +01:00
parent e97af99412
commit 28c1e47c95
52 changed files with 1867 additions and 9 deletions
@@ -1,12 +1,20 @@
package de.neitzel.fxdesigner.preview;
import java.util.Objects;
/** Non-executing example metadata. Factory/session signatures await real target fixtures. */
public record ExampleDescriptor(String id, String label, String modelType) {
/** Resource-only metadata; reading this record must not initialize application classes. */
public record ExampleDescriptor(
String id,
String label,
String modelType,
String providerClass,
String viewResource,
String componentPackage) {
public ExampleDescriptor {
if (id == null || id.isBlank()) throw new IllegalArgumentException("Missing example ID");
Objects.requireNonNull(label);
Objects.requireNonNull(modelType);
for (String s :
new String[] {id, label, modelType, providerClass, viewResource, componentPackage})
if (s == null || s.isBlank() || s.length() > 4096)
throw new IllegalArgumentException("Invalid example metadata");
if (viewResource.startsWith("/") || viewResource.contains("..") || viewResource.contains(":"))
throw new IllegalArgumentException("View resource must be a classloader-relative resource");
}
}
@@ -0,0 +1,11 @@
package de.neitzel.fxdesigner.preview;
/** Created only after example selection, in a fresh target JVM on its FX application thread. */
public interface PreviewProvider<M, C> {
Class<M> modelType();
/**
* Must create a fresh Model graph and context/services; clean partial allocations if this throws.
*/
PreviewSession<M, C> open(String exampleId) throws Exception;
}
@@ -0,0 +1,23 @@
package de.neitzel.fxdesigner.preview;
import java.util.concurrent.*;
/** Owned example state. The NeitzelLib adapter requires C to be an ApplicationContext. */
public interface PreviewSession<M, C> extends AutoCloseable {
M model();
C context();
/**
* Called after View loading/CSS/layout, on FX. Never block FX; complete asynchronously if needed.
*/
default CompletionStage<Void> ready() {
return CompletableFuture.completedFuture(null);
}
/**
* Release owned services/timers/listeners. Called once on FX, including load/readiness failure.
*/
@Override
void close() throws Exception;
}