feat(fls): read and write a project's own applications as their beans
A project's own applications (classes under projekt/anwendungen, installed on a host) are no longer left out. The decoder now keeps the Java type of every primitive — at setters, constructor and call arguments, also through shared ids like Integer0 — and which properties an object's own getter made. beanCapture.ts turns a decoded bean back into what the writer writes, with the node's system software as a mark the writer replaces by the system software it writes; what the format cannot say is refused, not guessed (an unresolved value, a Field, a factory-made object, an object a getter reaches elsewhere in the file). The reader keeps own applications as captured beans; the corpus no longer warns. The capture first took a setter with another object's getter result for an own getter; the round-trip test found it. The Java oracle did not show whether an application runs on its node's system software, so a mutation writing the mark instead survived; it now reports onItsSystem (true for all 192 applications of the corpus). Checked by Java: from the files written again, FILIUS loads Accumulator and Broadcast installed, switched on and on their node's system software, as in the original. The round-trip test covers every primitive, null, a class, an array, shared objects, getter chains, constructed elements, map reads and static constants. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -28,7 +28,9 @@
|
||||
// not know Java's constructors and sees a placeholder per path; they are
|
||||
// merged here.
|
||||
|
||||
import { captureBean } from './beanCapture.js';
|
||||
import { isDomainName } from './dnsHosts.js';
|
||||
import type { BeanObject } from './javaBeansWriter.js';
|
||||
import {
|
||||
EMAIL_CLIENT_FILE,
|
||||
EMAIL_SERVER_FILE,
|
||||
@@ -130,6 +132,13 @@ const SERVER_APPLICATIONS = new Set<string>([
|
||||
'filius.software.www.WebServer',
|
||||
]);
|
||||
|
||||
/** An application of the project's own: its key, class and bean, which refers to its node's system software by a mark. */
|
||||
export interface FlsOwnApplication {
|
||||
key: string | null;
|
||||
javaClass: string;
|
||||
bean: BeanObject;
|
||||
}
|
||||
|
||||
/** An installed application with the settings the model reads. */
|
||||
export interface FlsApplication {
|
||||
/** The key in installierteAnwendungen — the class name in every corpus file. */
|
||||
@@ -199,6 +208,12 @@ export interface FlsSystemSoftware {
|
||||
modem?: FlsModem;
|
||||
/** Rechner, Notebook: the installed applications, in the file's order. */
|
||||
applications?: FlsApplication[];
|
||||
/**
|
||||
* Rechner, Notebook: the installed applications FILIUS does not ship — a
|
||||
* project's own, compiled into projekt/anwendungen — kept as their beans,
|
||||
* to be written again as the file had them.
|
||||
*/
|
||||
ownApplications?: FlsOwnApplication[];
|
||||
/**
|
||||
* Every node with an IP stack: the root directory (named "root" by Java's
|
||||
* constructor) as the file has it. A router's or home router's holds only
|
||||
@@ -232,7 +247,7 @@ export function readSystemSoftware(device: JavaObject, javaClass: FlsNodeClass,
|
||||
case 'Notebook':
|
||||
result.ssid = optionalString(value('ssid'), 'ssid', warn) ?? null;
|
||||
result.fileSystem = fileSystem(value('dateisystem'), warn);
|
||||
result.applications = applications(value('installierteAnwendungen'), result.fileSystem, warn);
|
||||
[result.applications, result.ownApplications] = applications(value('installierteAnwendungen'), result.fileSystem, software, warn);
|
||||
break;
|
||||
case 'Vermittlungsrechner':
|
||||
result.ripEnabled = boolean(value('ripEnabled'), false, 'ripEnabled', warn);
|
||||
@@ -279,11 +294,18 @@ function modemAddress(value: string | null | undefined): string | null {
|
||||
|
||||
/**
|
||||
* installierteAnwendungen: key → application. A class FILIUS does not ship —
|
||||
* a project's own application, compiled into projekt/anwendungen — is left
|
||||
* out: this reader cannot run Java classes.
|
||||
* a project's own application, compiled into projekt/anwendungen — cannot
|
||||
* run here; it is kept as its bean (beanCapture.ts), or left out with a
|
||||
* warning where the bean cannot be written again.
|
||||
*/
|
||||
function applications(map: JavaValue | undefined, root: FlsFileTree, warn: Warn): FlsApplication[] {
|
||||
function applications(
|
||||
map: JavaValue | undefined,
|
||||
root: FlsFileTree,
|
||||
software: JavaObject | undefined,
|
||||
warn: Warn,
|
||||
): [FlsApplication[], FlsOwnApplication[]] {
|
||||
const result: FlsApplication[] = [];
|
||||
const own: FlsOwnApplication[] = [];
|
||||
for (const [key, application] of mapEntries(map)) {
|
||||
if (!isJavaObject(application)) {
|
||||
warn(`application ${describe(key)} is ${describe(application)}, left out`);
|
||||
@@ -291,7 +313,9 @@ function applications(map: JavaValue | undefined, root: FlsFileTree, warn: Warn)
|
||||
}
|
||||
const javaClass = application.className;
|
||||
if (!(FILIUS_APPLICATION_CLASSES as readonly string[]).includes(javaClass)) {
|
||||
warn(`application ${javaClass} is not part of FILIUS (a project's own application), left out`);
|
||||
const captured = captureBean(application, software);
|
||||
if ('bean' in captured) own.push({ key: typeof key === 'string' ? key : null, javaClass, bean: captured.bean });
|
||||
else warn(`application ${javaClass}, a project's own, cannot be written again: ${captured.failure}; left out`);
|
||||
continue;
|
||||
}
|
||||
const simple = simpleClassName(javaClass);
|
||||
@@ -348,7 +372,7 @@ function applications(map: JavaValue | undefined, root: FlsFileTree, warn: Warn)
|
||||
}
|
||||
result.push(entry);
|
||||
}
|
||||
return result;
|
||||
return [result, own];
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user