feat(editor): F4.5a the device sheet for PCs, notebooks, switches and modems
Measured first: the new oracle SheetRun types 77 texts into FILIUS' own settings panels and records what was marked red, what the device took and what the field showed afterwards. Java's two judgements disagree (red text taken, black text refused, any int as a modem port, a refused text dropped without a word); here one rule decides both (packages/doc fields.ts), a refused text stays marked in the field, and only what Java's model accepts reaches the document. - doc: settings.ts (name, label policy, addresses, IP forwarding, DHCP stopping the own DHCP server, LAN/WLAN with the wireless connection, switch SSID dropping its wireless hosts, retention time, cloud, modem port as its pair), sheet.ts (what the sheet shows) - fls: modemPair/modemPort in one place - editor: DeviceSheet beside the surface or below it on a phone, opened with the selection; every change one undo step - not adopted from Java: the name overwritten by the MAC address, the access point search depending on unrelated devices Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,199 @@
|
||||
// Types into FILIUS' own settings panels (JHostKonfiguration,
|
||||
// JSwitchKonfiguration, JModemKonfiguration) and lets them take the text as
|
||||
// they do when a field loses the focus (aenderungenAnnehmen), then writes,
|
||||
// for each case, whether the panel marked the text red while typing, what the
|
||||
// device holds afterwards and what the field shows then (updateAttribute):
|
||||
// the reference for the editor's device sheet (packages/doc/test/sheet.test.ts).
|
||||
// Each case starts from a new device ("start": the field's value then). The cases file is ASCII, with
|
||||
// Java-style unicode escapes (backslash, u, four hex digits) for anything
|
||||
// else, one case a line:
|
||||
//
|
||||
// <host|switch|modem> <field> <text> the text may be empty
|
||||
//
|
||||
// Fields: host name, ip, mask, gateway, dns; switch name, ssid, retention;
|
||||
// modem name, port. After the cases, a few flows of the check boxes
|
||||
// ("flows"): a host's name while it shows its address or MAC address, and
|
||||
// DHCP switched on while its own DHCP server runs.
|
||||
//
|
||||
// Usage: java -cp filius.jar:lib/*:classes SheetRun <cases txt> <output json>
|
||||
|
||||
import filius.gui.GUIContainer;
|
||||
import filius.gui.netzwerksicht.JKonfiguration;
|
||||
import filius.hardware.knoten.Host;
|
||||
import filius.hardware.knoten.Modem;
|
||||
import filius.hardware.knoten.Rechner;
|
||||
import filius.hardware.knoten.Switch;
|
||||
import filius.rahmenprogramm.EingabenUeberpruefung;
|
||||
import filius.software.system.Betriebssystem;
|
||||
import filius.software.system.ModemFirmware;
|
||||
import filius.software.system.SwitchFirmware;
|
||||
|
||||
import java.io.FileOutputStream;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import javax.swing.JCheckBox;
|
||||
import javax.swing.JTextField;
|
||||
|
||||
public class SheetRun {
|
||||
static Object get(Object panel, String name) throws Exception {
|
||||
Field field = panel.getClass().getDeclaredField(name);
|
||||
field.setAccessible(true);
|
||||
return field.get(panel);
|
||||
}
|
||||
|
||||
static void call(Object panel, String name) throws Exception {
|
||||
Method method = panel.getClass().getDeclaredMethod(name);
|
||||
method.setAccessible(true);
|
||||
method.invoke(panel);
|
||||
}
|
||||
|
||||
/** The panel's field and its check (the method its key listener calls), per device and field. */
|
||||
static final Map<String, String[]> FIELDS = new LinkedHashMap<>();
|
||||
static {
|
||||
FIELDS.put("host name", new String[] { "name", null });
|
||||
FIELDS.put("host ip", new String[] { "ipAdresse", "checkIpAddress" });
|
||||
FIELDS.put("host mask", new String[] { "netzmaske", "checkNetmask" });
|
||||
FIELDS.put("host gateway", new String[] { "gateway", "checkGatewayAddress" });
|
||||
FIELDS.put("host dns", new String[] { "dns", "checkDnsAddress" });
|
||||
FIELDS.put("switch name", new String[] { "name", null });
|
||||
FIELDS.put("switch ssid", new String[] { "ssid", "checkSSID" });
|
||||
FIELDS.put("switch retention", new String[] { "retentionTime", "checkRetentionTime" });
|
||||
FIELDS.put("modem name", new String[] { "name", null });
|
||||
FIELDS.put("modem port", new String[] { "tfPort", null });
|
||||
}
|
||||
|
||||
static String stored(Object device, String key) {
|
||||
if (device instanceof Host) {
|
||||
Host host = (Host) device;
|
||||
Betriebssystem os = (Betriebssystem) host.getSystemSoftware();
|
||||
switch (key) {
|
||||
case "host name": return host.getName();
|
||||
case "host ip": return os.primaryIPAdresse();
|
||||
case "host mask": return os.primarySubnetMask();
|
||||
case "host gateway": return os.getStandardGateway();
|
||||
case "host dns": return os.getDNSServer();
|
||||
}
|
||||
} else if (device instanceof Switch) {
|
||||
Switch sw = (Switch) device;
|
||||
SwitchFirmware firmware = (SwitchFirmware) sw.getSystemSoftware();
|
||||
switch (key) {
|
||||
case "switch name": return sw.getName();
|
||||
case "switch ssid": return firmware.getSSID();
|
||||
case "switch retention": return Long.toString(firmware.getRetentionTime());
|
||||
}
|
||||
} else if (device instanceof Modem) {
|
||||
Modem modem = (Modem) device;
|
||||
switch (key) {
|
||||
case "modem name": return modem.getName();
|
||||
case "modem port": return Integer.toString(((ModemFirmware) modem.getSystemSoftware()).getPort());
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException(key);
|
||||
}
|
||||
|
||||
/** A new device; a host with a gateway and a DNS server, a switch with a known SSID, so that what a case leaves alone shows. */
|
||||
static Object device(String kind) {
|
||||
switch (kind) {
|
||||
case "host": {
|
||||
Rechner host = new Rechner();
|
||||
Betriebssystem os = (Betriebssystem) host.getSystemSoftware();
|
||||
os.setStandardGateway("192.168.0.254");
|
||||
os.setDNSServer("192.168.0.253");
|
||||
return host;
|
||||
}
|
||||
case "switch": {
|
||||
Switch sw = new Switch();
|
||||
((SwitchFirmware) sw.getSystemSoftware()).setSSID("Start");
|
||||
return sw;
|
||||
}
|
||||
case "modem": return new Modem();
|
||||
}
|
||||
throw new IllegalArgumentException(kind);
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
// FILIUS' window keeps the JVM alive: end it on any failure too.
|
||||
try {
|
||||
run(args);
|
||||
} catch (Throwable error) {
|
||||
error.printStackTrace();
|
||||
System.exit(1);
|
||||
}
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
static void run(String[] args) throws Exception {
|
||||
GUIContainer.getGUIContainer();
|
||||
List<Object> cases = new ArrayList<>();
|
||||
for (String line : Files.readAllLines(Path.of(args[0]), StandardCharsets.US_ASCII)) {
|
||||
if (line.isEmpty() || line.startsWith("#")) continue;
|
||||
String[] words = line.split(" ", 3);
|
||||
String key = words[0] + " " + words[1];
|
||||
String text = words.length < 3 ? "" : IpCheckCases.unescape(words[2]);
|
||||
String[] names = FIELDS.get(key);
|
||||
if (names == null) throw new IllegalArgumentException(line);
|
||||
Object device = device(words[0]);
|
||||
String start = stored(device, key);
|
||||
JKonfiguration panel = JKonfiguration.getInstance((filius.hardware.Hardware) device);
|
||||
JTextField field = (JTextField) get(panel, names[0]);
|
||||
field.setText(text);
|
||||
boolean marked = false;
|
||||
if (names[1] != null) {
|
||||
call(panel, names[1]);
|
||||
marked = field.getForeground().equals(EingabenUeberpruefung.farbeFalsch);
|
||||
}
|
||||
call(panel, "aenderungenAnnehmen");
|
||||
panel.updateAttribute();
|
||||
Map<String, Object> result = new LinkedHashMap<>();
|
||||
result.put("device", words[0]);
|
||||
result.put("field", words[1]);
|
||||
result.put("input", text);
|
||||
result.put("start", start);
|
||||
result.put("marked", marked);
|
||||
result.put("stored", stored(device, key));
|
||||
result.put("shown", field.getText());
|
||||
cases.add(result);
|
||||
}
|
||||
|
||||
Map<String, Object> flows = new LinkedHashMap<>();
|
||||
// The MAC address as name, then another field taken: what becomes of the name?
|
||||
for (String box : new String[] { "useMacAsName", "useIpAsName" }) {
|
||||
Rechner host = new Rechner();
|
||||
host.setName("PC-A");
|
||||
JKonfiguration panel = JKonfiguration.getInstance(host);
|
||||
((JCheckBox) get(panel, box)).setSelected(true);
|
||||
call(panel, "aendereAnzeigeName");
|
||||
((JTextField) get(panel, "gateway")).setText("192.168.0.1");
|
||||
call(panel, "aenderungenAnnehmen");
|
||||
((JCheckBox) get(panel, box)).setSelected(false);
|
||||
call(panel, "aendereAnzeigeName");
|
||||
flows.put(box + "ThenOff", host.getName());
|
||||
}
|
||||
// DHCP for the configuration while the host's own DHCP server is on.
|
||||
{
|
||||
Rechner host = new Rechner();
|
||||
Betriebssystem os = (Betriebssystem) host.getSystemSoftware();
|
||||
os.getDHCPServer().setAktiv(true);
|
||||
JKonfiguration panel = JKonfiguration.getInstance(host);
|
||||
((JCheckBox) get(panel, "dhcp")).setSelected(true);
|
||||
call(panel, "aenderungenAnnehmen");
|
||||
flows.put("dhcpClientStopsServer", !os.getDHCPServer().isAktiv());
|
||||
flows.put("dhcpClient", os.isDHCPKonfiguration());
|
||||
}
|
||||
|
||||
Map<String, Object> output = new LinkedHashMap<>();
|
||||
output.put("cases", cases);
|
||||
output.put("flows", flows);
|
||||
try (FileOutputStream out = new FileOutputStream(args[1])) {
|
||||
out.write((FlsOracle.Json.write(output, "") + "\n").getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
System.out.println("sheet cases: " + cases.size());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user