aboutsummaryrefslogtreecommitdiff
path: root/src/main
diff options
context:
space:
mode:
authorMatthias Andreas Benkard <code@mail.matthias.benkard.de>2026-08-15 08:36:14 +0200
committerMatthias Andreas Benkard <code@mail.matthias.benkard.de>2026-08-15 08:36:41 +0200
commit5700bbcb89186e432c5c7dd232b61c052de8e784 (patch)
tree6c931136a3b95e58cf876d673c077507ca00f957 /src/main
parent7235b34eeb6ff331c152116cbe4df846d7476110 (diff)
Quelltextformatierung
Change-Id: I51c63959e75af9373625a52b74d1d31f727a67ed
Diffstat (limited to 'src/main')
-rw-r--r--src/main/java/eu/mulk/aendggner/aenderung/Aenderungsbefehl.java6
-rw-r--r--src/main/java/eu/mulk/aendggner/aenderung/Stelle.java4
-rw-r--r--src/main/java/eu/mulk/aendggner/aenderung/parse/ZitatExtraktor.java7
-rw-r--r--src/main/java/eu/mulk/aendggner/anwendung/BefehlAnwender.java273
-rw-r--r--src/main/java/eu/mulk/aendggner/anwendung/InhaltsuebersichtAnwender.java14
-rw-r--r--src/main/java/eu/mulk/aendggner/anwendung/SatzTeiler.java8
-rw-r--r--src/main/java/eu/mulk/aendggner/anwendung/StellenAufloeser.java4
-rw-r--r--src/main/java/eu/mulk/aendggner/gesetz/Gliederung.java4
-rw-r--r--src/main/java/eu/mulk/aendggner/gesetz/Superskript.java6
-rw-r--r--src/main/java/eu/mulk/aendggner/gesetz/land/LandesRechtLoader.java8
-rw-r--r--src/main/java/eu/mulk/aendggner/gesetz/land/LandesRechtTextParser.java28
-rw-r--r--src/main/java/eu/mulk/aendggner/synopse/SynopseBuilder.java8
-rw-r--r--src/main/java/eu/mulk/aendggner/web/Multipart.java7
-rw-r--r--src/main/java/eu/mulk/aendggner/web/StaticHandler.java8
-rw-r--r--src/main/java/eu/mulk/aendggner/web/UploadHandler.java22
-rw-r--r--src/main/java/eu/mulk/aendggner/web/WebMain.java3
16 files changed, 228 insertions, 182 deletions
diff --git a/src/main/java/eu/mulk/aendggner/aenderung/Aenderungsbefehl.java b/src/main/java/eu/mulk/aendggner/aenderung/Aenderungsbefehl.java
index 606383f..4117922 100644
--- a/src/main/java/eu/mulk/aendggner/aenderung/Aenderungsbefehl.java
+++ b/src/main/java/eu/mulk/aendggner/aenderung/Aenderungsbefehl.java
@@ -73,9 +73,9 @@ public sealed interface Aenderungsbefehl {
* @param vorher {@code true} bei „Vor …“, {@code false} bei „Nach …“.
* @param bezeichnung die Bezeichnung des neuen Elements (z.B. „28a“, „5a“); {@code null}, wenn
* der Befehl keine nennt (z.B. „folgender Satz“).
- * @param anker bei „Vor den Wörtern „Aus dem Bereich Verkehr:“ wird folgender Absatz 5
- * eingefügt“ der Wortanker, der die Position innerhalb von {@code stelle} bestimmt;
- * {@code null}, wenn die Position wie üblich aus der Struktur folgt.
+ * @param anker bei „Vor den Wörtern „Aus dem Bereich Verkehr:“ wird folgender Absatz 5 eingefügt“
+ * der Wortanker, der die Position innerhalb von {@code stelle} bestimmt; {@code null}, wenn
+ * die Position wie üblich aus der Struktur folgt.
*/
record StrukturEinfuegung(
Stelle stelle,
diff --git a/src/main/java/eu/mulk/aendggner/aenderung/Stelle.java b/src/main/java/eu/mulk/aendggner/aenderung/Stelle.java
index 1c63a5f..69e6837 100644
--- a/src/main/java/eu/mulk/aendggner/aenderung/Stelle.java
+++ b/src/main/java/eu/mulk/aendggner/aenderung/Stelle.java
@@ -29,8 +29,8 @@ public record Stelle(List<Komponente> komponenten) {
Absatzbezeichnung {}
/**
- * „§ 5“, „§ 28a“, im bayerischen Landesrecht „Art. 5“ — die Normnummer ohne Sigel, dazu das
- * Sigel selbst („§“ oder „Art.“).
+ * „§ 5“, „§ 28a“, im bayerischen Landesrecht „Art. 5“ — die Normnummer ohne Sigel, dazu das Sigel
+ * selbst („§“ oder „Art.“).
*/
public record Paragraph(String nummer, String sigel) implements Komponente {
public Paragraph(String nummer) {
diff --git a/src/main/java/eu/mulk/aendggner/aenderung/parse/ZitatExtraktor.java b/src/main/java/eu/mulk/aendggner/aenderung/parse/ZitatExtraktor.java
index d4df176..4b9d511 100644
--- a/src/main/java/eu/mulk/aendggner/aenderung/parse/ZitatExtraktor.java
+++ b/src/main/java/eu/mulk/aendggner/aenderung/parse/ZitatExtraktor.java
@@ -170,8 +170,8 @@ public final class ZitatExtraktor {
Pattern.compile("^(?:\\d+[a-z]?\\.|[a-z]{1,3}\\))[ \\t]");
/**
- * Wahr, wenn das öffnende Anführungszeichen an Position {@code i} ein Fortführungszeichen ist:
- * Es steht am Zeilenanfang innerhalb eines offenen Zitats und ihm folgt unmittelbar ein
+ * Wahr, wenn das öffnende Anführungszeichen an Position {@code i} ein Fortführungszeichen ist: Es
+ * steht am Zeilenanfang innerhalb eines offenen Zitats und ihm folgt unmittelbar ein
* Aufzählungsmarker.
*/
private static boolean istFortfuehrungszeichen(String text, int i) {
@@ -191,7 +191,8 @@ public final class ZitatExtraktor {
* Stammgesetze zitieren ihre Normköpfe als „Art. N“, nicht als „Artikel N“ — zitierter Inhalt
* läuft hier also nicht versehentlich auf.
*/
- private static final Pattern ARTIKEL_GRENZE = Pattern.compile("^Artikel[ \\t]+\\d+[a-z]?[ \\t]*$");
+ private static final Pattern ARTIKEL_GRENZE =
+ Pattern.compile("^Artikel[ \\t]+\\d+[a-z]?[ \\t]*$");
/** Wahr, wenn die bei {@code von} beginnende Zeile eine Artikel-Überschrift ist. */
private static boolean beginntArtikelUeberschrift(String text, int von) {
diff --git a/src/main/java/eu/mulk/aendggner/anwendung/BefehlAnwender.java b/src/main/java/eu/mulk/aendggner/anwendung/BefehlAnwender.java
index d8e710c..b8540c5 100644
--- a/src/main/java/eu/mulk/aendggner/anwendung/BefehlAnwender.java
+++ b/src/main/java/eu/mulk/aendggner/anwendung/BefehlAnwender.java
@@ -2,14 +2,14 @@ package eu.mulk.aendggner.anwendung;
import eu.mulk.aendggner.aenderung.Aenderungsbefehl;
import eu.mulk.aendggner.aenderung.Aenderungsbefehl.Anfuegung;
-import eu.mulk.aendggner.aenderung.Aenderungsbefehl.Ebene;
import eu.mulk.aendggner.aenderung.Aenderungsbefehl.Aufhebung;
+import eu.mulk.aendggner.aenderung.Aenderungsbefehl.Ebene;
import eu.mulk.aendggner.aenderung.Aenderungsbefehl.Ersetzung;
import eu.mulk.aendggner.aenderung.Aenderungsbefehl.FussnotenAufhebung;
import eu.mulk.aendggner.aenderung.Aenderungsbefehl.GliederungsUeberschriften;
-import eu.mulk.aendggner.aenderung.Aenderungsbefehl.SatznummerierungStreichung;
import eu.mulk.aendggner.aenderung.Aenderungsbefehl.Neufassung;
import eu.mulk.aendggner.aenderung.Aenderungsbefehl.Sammelbefehl;
+import eu.mulk.aendggner.aenderung.Aenderungsbefehl.SatznummerierungStreichung;
import eu.mulk.aendggner.aenderung.Aenderungsbefehl.Streichung;
import eu.mulk.aendggner.aenderung.Aenderungsbefehl.StrukturEinfuegung;
import eu.mulk.aendggner.aenderung.Aenderungsbefehl.StrukturErsetzung;
@@ -298,7 +298,8 @@ public final class BefehlAnwender {
private static List<StrukturErsetzung> ersetzungen(Aenderungsbefehl befehl) {
return switch (befehl) {
case StrukturErsetzung e -> List.of(e);
- case Sammelbefehl s -> s.teilbefehle().stream().flatMap(t -> ersetzungen(t).stream()).toList();
+ case Sammelbefehl s ->
+ s.teilbefehle().stream().flatMap(t -> ersetzungen(t).stream()).toList();
default -> List.of();
};
}
@@ -374,8 +375,7 @@ public final class BefehlAnwender {
// Führende Eigenbezeichnung („Abschnitt 2 …“ oder „2. Abschnitt …“) aus dem Zitat entfernen.
var label = Pattern.compile("^(\\d+[a-z]?\\.\\s+\\S+|\\S+\\s+\\d+[a-z]?)\\s+").matcher(titel);
if (label.find()
- && kanonischeBezeichnung(label.group(1))
- .equals(kanonischeBezeichnung(alt.bezeichnung()))) {
+ && kanonischeBezeichnung(label.group(1)).equals(kanonischeBezeichnung(alt.bezeichnung()))) {
titel = titel.substring(label.end()).strip();
} else if (titel.startsWith(alt.bezeichnung())) {
titel = titel.substring(alt.bezeichnung().length()).strip();
@@ -395,7 +395,9 @@ public final class BefehlAnwender {
return angewandt(befehl, alt.bezeichnung());
}
- /** „Der bisherige Abschnitt 2 wird zu Abschnitt 3.“ — Bezeichnung der Gliederungseinheit umsetzen. */
+ /**
+ * „Der bisherige Abschnitt 2 wird zu Abschnitt 3.“ — Bezeichnung der Gliederungseinheit umsetzen.
+ */
private static AngewandteAenderung wendeGliederungUmnummerierungAn(
List<Gliederung> gliederungen, Umnummerierung befehl) {
int idx = findeGliederung(gliederungen, befehl.stelle().gliederungsPfad());
@@ -451,12 +453,12 @@ public final class BefehlAnwender {
if (idx < 0) {
return manuell(
befehl,
- "Gliederungseinheit nicht gefunden: "
- + pfad.get(pfad.size() - 1).bezeichnung());
+ "Gliederungseinheit nicht gefunden: " + pfad.get(pfad.size() - 1).bezeichnung());
}
indizes.add(idx);
}
- var alte = indizes.stream().map(gliederungen::get).collect(java.util.stream.Collectors.toSet());
+ var alte =
+ indizes.stream().map(gliederungen::get).collect(java.util.stream.Collectors.toSet());
int einfuegePos = java.util.Collections.min(indizes);
indizes.sort(java.util.Comparator.reverseOrder());
for (int idx : indizes) {
@@ -479,7 +481,9 @@ public final class BefehlAnwender {
}
var anker = normen.get(aufloesung.normIndex());
int gliederungsPos =
- anker.gliederung() != null ? gliederungen.indexOf(anker.gliederung()) + 1 : gliederungen.size();
+ anker.gliederung() != null
+ ? gliederungen.indexOf(anker.gliederung()) + 1
+ : gliederungen.size();
if (gliederungsPos == 0) {
gliederungsPos = gliederungen.size();
}
@@ -513,7 +517,8 @@ public final class BefehlAnwender {
gefunden = -1;
for (int i = 0; i < gliederungen.size(); i++) {
var g = gliederungen.get(i);
- if (kanonischeBezeichnung(g.bezeichnung()).equals(kanonischeBezeichnung(einheit.bezeichnung()))
+ if (kanonischeBezeichnung(g.bezeichnung())
+ .equals(kanonischeBezeichnung(einheit.bezeichnung()))
&& (g.kennzahl() == null || g.kennzahl().startsWith(praefix))) {
gefunden = i;
break;
@@ -542,34 +547,39 @@ public final class BefehlAnwender {
normen,
befehl,
ohneFussnoten(
- text -> {
- if (befehl.amEnde()) {
- var gestutzt = text.stripTrailing();
- if (!gestutzt.endsWith(befehl.alt())) {
- return TextErgebnis.fehler("Der Text endet nicht mit „" + befehl.alt() + "“.");
- }
- var rumpf = gestutzt.substring(0, gestutzt.length() - befehl.alt().length());
- // Tritt an die Stelle des Satzzeichens ein Klammerzusatz („Der Punkt am Ende wird
- // durch die Angabe „(Gesellschaftsdialog).“ ersetzt“), gehört davor ein Leerzeichen —
- // so setzt es auch die amtliche Nachfassung.
- var fuge =
- befehl.neu().startsWith("(")
- && !rumpf.isEmpty()
- && Character.isLetterOrDigit(rumpf.charAt(rumpf.length() - 1))
- ? " "
- : "";
- return TextErgebnis.ok(rumpf + fuge + befehl.neu());
- }
- int anzahl = zaehleVorkommen(text, befehl.alt());
- if (anzahl == 0) {
- return TextErgebnis.fehler("„" + befehl.alt() + "“ kommt im Zieltext nicht vor.");
- }
- if (anzahl > 1 && !befehl.jeweils()) {
- return TextErgebnis.fehler(
- "„" + befehl.alt() + "“ kommt " + anzahl + "-mal vor (ohne „jeweils“ mehrdeutig).");
- }
- return TextErgebnis.ok(text.replace(befehl.alt(), befehl.neu()));
- }));
+ text -> {
+ if (befehl.amEnde()) {
+ var gestutzt = text.stripTrailing();
+ if (!gestutzt.endsWith(befehl.alt())) {
+ return TextErgebnis.fehler("Der Text endet nicht mit „" + befehl.alt() + "“.");
+ }
+ var rumpf = gestutzt.substring(0, gestutzt.length() - befehl.alt().length());
+ // Tritt an die Stelle des Satzzeichens ein Klammerzusatz („Der Punkt am Ende wird
+ // durch die Angabe „(Gesellschaftsdialog).“ ersetzt“), gehört davor ein Leerzeichen
+ // —
+ // so setzt es auch die amtliche Nachfassung.
+ var fuge =
+ befehl.neu().startsWith("(")
+ && !rumpf.isEmpty()
+ && Character.isLetterOrDigit(rumpf.charAt(rumpf.length() - 1))
+ ? " "
+ : "";
+ return TextErgebnis.ok(rumpf + fuge + befehl.neu());
+ }
+ int anzahl = zaehleVorkommen(text, befehl.alt());
+ if (anzahl == 0) {
+ return TextErgebnis.fehler("„" + befehl.alt() + "“ kommt im Zieltext nicht vor.");
+ }
+ if (anzahl > 1 && !befehl.jeweils()) {
+ return TextErgebnis.fehler(
+ "„"
+ + befehl.alt()
+ + "“ kommt "
+ + anzahl
+ + "-mal vor (ohne „jeweils“ mehrdeutig).");
+ }
+ return TextErgebnis.ok(text.replace(befehl.alt(), befehl.neu()));
+ }));
}
private static AngewandteAenderung wendeStreichungAn(List<Norm> normen, Streichung befehl) {
@@ -577,19 +587,21 @@ public final class BefehlAnwender {
normen,
befehl,
ohneFussnoten(
- text -> {
- int anzahl = zaehleVorkommen(text, befehl.woerter());
- if (anzahl == 0) {
- return TextErgebnis.fehler("„" + befehl.woerter() + "“ kommt im Zieltext nicht vor.");
- }
- if (anzahl > 1) {
- return TextErgebnis.fehler("„" + befehl.woerter() + "“ kommt " + anzahl + "-mal vor.");
- }
- return TextErgebnis.ok(
- text.replace(befehl.woerter(), "")
- .replaceAll(" +", " ")
- .replaceAll(" ([,;.])", "$1"));
- }));
+ text -> {
+ int anzahl = zaehleVorkommen(text, befehl.woerter());
+ if (anzahl == 0) {
+ return TextErgebnis.fehler(
+ "„" + befehl.woerter() + "“ kommt im Zieltext nicht vor.");
+ }
+ if (anzahl > 1) {
+ return TextErgebnis.fehler(
+ "„" + befehl.woerter() + "“ kommt " + anzahl + "-mal vor.");
+ }
+ return TextErgebnis.ok(
+ text.replace(befehl.woerter(), "")
+ .replaceAll(" +", " ")
+ .replaceAll(" ([,;.])", "$1"));
+ }));
}
private static AngewandteAenderung wendeWoerterEinfuegungAn(
@@ -598,50 +610,57 @@ public final class BefehlAnwender {
normen,
befehl,
ohneFussnoten(
- text ->
- switch (befehl.anker()) {
- case WortAnker.NachWoertern nach -> {
- var pruefung = eindeutigeFundstelle(text, nach.woerter());
- if (pruefung.fehler() != null) {
- yield TextErgebnis.fehler(pruefung.fehler());
- }
- int ende = pruefung.index() + nach.woerter().length();
- yield TextErgebnis.ok(
- text.substring(0, ende) + fuge(befehl.woerter()) + befehl.woerter()
- + text.substring(ende));
- }
- case WortAnker.VorWoertern vor -> {
- var pruefung = eindeutigeFundstelle(text, vor.woerter());
- if (pruefung.fehler() != null) {
- yield TextErgebnis.fehler(pruefung.fehler());
- }
- yield TextErgebnis.ok(
- text.substring(0, pruefung.index())
- + befehl.woerter()
- + " "
- + text.substring(pruefung.index()));
- }
- case WortAnker.VorKommaAmEnde ignoriert -> {
- var gestutzt = text.stripTrailing();
- if (!gestutzt.endsWith(",")) {
- yield TextErgebnis.fehler("Der Zieltext endet nicht mit einem Komma.");
- }
- yield TextErgebnis.ok(
- gestutzt.substring(0, gestutzt.length() - 1) + " " + befehl.woerter() + ",");
- }
- case WortAnker.AmEnde ignoriert -> {
- var gestutzt = text.stripTrailing();
- if (gestutzt.endsWith(".") || gestutzt.endsWith(",") || gestutzt.endsWith(";")) {
- var satzzeichen = gestutzt.charAt(gestutzt.length() - 1);
- yield TextErgebnis.ok(
- gestutzt.substring(0, gestutzt.length() - 1)
- + " "
- + befehl.woerter()
- + satzzeichen);
- }
- yield TextErgebnis.ok(gestutzt + " " + befehl.woerter());
- }
- }));
+ text ->
+ switch (befehl.anker()) {
+ case WortAnker.NachWoertern nach -> {
+ var pruefung = eindeutigeFundstelle(text, nach.woerter());
+ if (pruefung.fehler() != null) {
+ yield TextErgebnis.fehler(pruefung.fehler());
+ }
+ int ende = pruefung.index() + nach.woerter().length();
+ yield TextErgebnis.ok(
+ text.substring(0, ende)
+ + fuge(befehl.woerter())
+ + befehl.woerter()
+ + text.substring(ende));
+ }
+ case WortAnker.VorWoertern vor -> {
+ var pruefung = eindeutigeFundstelle(text, vor.woerter());
+ if (pruefung.fehler() != null) {
+ yield TextErgebnis.fehler(pruefung.fehler());
+ }
+ yield TextErgebnis.ok(
+ text.substring(0, pruefung.index())
+ + befehl.woerter()
+ + " "
+ + text.substring(pruefung.index()));
+ }
+ case WortAnker.VorKommaAmEnde ignoriert -> {
+ var gestutzt = text.stripTrailing();
+ if (!gestutzt.endsWith(",")) {
+ yield TextErgebnis.fehler("Der Zieltext endet nicht mit einem Komma.");
+ }
+ yield TextErgebnis.ok(
+ gestutzt.substring(0, gestutzt.length() - 1)
+ + " "
+ + befehl.woerter()
+ + ",");
+ }
+ case WortAnker.AmEnde ignoriert -> {
+ var gestutzt = text.stripTrailing();
+ if (gestutzt.endsWith(".")
+ || gestutzt.endsWith(",")
+ || gestutzt.endsWith(";")) {
+ var satzzeichen = gestutzt.charAt(gestutzt.length() - 1);
+ yield TextErgebnis.ok(
+ gestutzt.substring(0, gestutzt.length() - 1)
+ + " "
+ + befehl.woerter()
+ + satzzeichen);
+ }
+ yield TextErgebnis.ok(gestutzt + " " + befehl.woerter());
+ }
+ }));
}
// --- Strukturoperationen -------------------------------------------------------------------
@@ -876,7 +895,8 @@ public final class BefehlAnwender {
var text = absatz.text();
var einrueckung = einrueckungVon(text, von);
var ersatz = rueckeZitatEin(normalisiereZitatText(befehl.text()), einrueckung);
- absaetze.set(f1.absatzIndex(), absatz.mitText(text.substring(0, von) + ersatz + text.substring(bis)));
+ absaetze.set(
+ f1.absatzIndex(), absatz.mitText(text.substring(0, von) + ersatz + text.substring(bis)));
normen.set(f1.normIndex(), norm.mitAbsaetzen(absaetze));
return angewandt(befehl, norm.enbez());
}
@@ -911,8 +931,7 @@ public final class BefehlAnwender {
yield angewandt(befehl, neue.stream().map(Norm::enbez).toList());
}
- var sigelNeu =
- befehl.stelle().paragraph().map(Stelle.Paragraph::sigel).orElse("§");
+ var sigelNeu = befehl.stelle().paragraph().map(Stelle.Paragraph::sigel).orElse("§");
var enbezNeu = sigelNeu + " " + befehl.bezeichnung();
if (StellenAufloeser.normIndex(gesetzAus(normen), enbezNeu) >= 0) {
yield manuell(befehl, enbezNeu + " existiert bereits im Stammgesetz.");
@@ -1016,7 +1035,10 @@ public final class BefehlAnwender {
normalisiereZitatText(befehl.text()), einrueckungVon(text, zeilenAnfang));
return TextErgebnis.ok(
befehl.vorher()
- ? text.substring(0, zeilenAnfang) + block + "\n" + text.substring(zeilenAnfang)
+ ? text.substring(0, zeilenAnfang)
+ + block
+ + "\n"
+ + text.substring(zeilenAnfang)
: text.substring(0, zeilenEnde) + "\n" + block + text.substring(zeilenEnde));
}));
}
@@ -1176,8 +1198,10 @@ public final class BefehlAnwender {
var absaetze = new ArrayList<>(norm.absaetze());
int quelleIdx = fundstelle.absatzIndex();
var neueNummer = neuAbsatz.get().nummer();
- // Ein leerer Platzhalter-Absatz mit der Zielnummer (weggefallen/gegenstandslos) wird durch die
- // Umnummerierung überschrieben (analog zur Norm-Umnummerierung auf eine weggefallene Zielnorm).
+ // Ein leerer Platzhalter-Absatz mit der Zielnummer (weggefallen/gegenstandslos) wird durch
+ // die
+ // Umnummerierung überschrieben (analog zur Norm-Umnummerierung auf eine weggefallene
+ // Zielnorm).
for (int i = absaetze.size() - 1; i >= 0; i--) {
if (i != quelleIdx
&& neueNummer.equals(absaetze.get(i).nummer())
@@ -1208,8 +1232,11 @@ public final class BefehlAnwender {
.matcher(text.substring(bereich.von(), bereich.bis()));
if (!marke.find()) {
return TextErgebnis.fehler(
- "„" + alteMarke + "“ steht nicht am Anfang von "
- + befehl.stelle().anzeigeText() + ".");
+ "„"
+ + alteMarke
+ + "“ steht nicht am Anfang von "
+ + befehl.stelle().anzeigeText()
+ + ".");
}
var umbenannt =
text.substring(0, bereich.von())
@@ -1235,9 +1262,11 @@ public final class BefehlAnwender {
var absaetze = new ArrayList<>(norm.absaetze());
var absatz = absaetze.get(fundstelle.absatzIndex());
var text = absatz.text();
- var marker = Superskript.LAUF.matcher(text).region(fundstelle.bereich().von(), fundstelle.bereich().bis());
- if (marker.lookingAt()
- && Superskript.istSatzanfang(text, marker.start(), marker.end())) {
+ var marker =
+ Superskript.LAUF
+ .matcher(text)
+ .region(fundstelle.bereich().von(), fundstelle.bereich().bis());
+ if (marker.lookingAt() && Superskript.istSatzanfang(text, marker.start(), marker.end())) {
var neuerText =
text.substring(0, marker.start())
+ Superskript.zuSuperskript(neuSatz.nummer())
@@ -1279,7 +1308,9 @@ public final class BefehlAnwender {
*/
private static String entferneWeggefallenenPlatzhalter(String text, String marke) {
return text.replaceFirst(
- "(?m)^[ \\t]*" + Pattern.quote(marke) + "[ \\t]+\\((?:weggefallen|gegenstandslos|aufgehoben)\\)\\n?",
+ "(?m)^[ \\t]*"
+ + Pattern.quote(marke)
+ + "[ \\t]+\\((?:weggefallen|gegenstandslos|aufgehoben)\\)\\n?",
"");
}
@@ -1310,8 +1341,7 @@ public final class BefehlAnwender {
// Steht genau ein unnummerierter Absatz zwischen nummerierten (bayerische Folge „Dem Wortlaut
// werden … Abs. 1 bis 4 vorangestellt“ → „Der bisherige Wortlaut wird Abs. 5“), erhält nur
// dieser die Nummer. Sind alle Absätze unnummeriert, wird der Gesamtwortlaut zu einem Absatz.
- var unnummerierte =
- norm.absaetze().stream().filter(a -> a.nummer() == null).toList();
+ var unnummerierte = norm.absaetze().stream().filter(a -> a.nummer() == null).toList();
if (unnummerierte.size() == 1 && norm.absaetze().size() > 1) {
var absaetze = new ArrayList<>(norm.absaetze());
int idx = absaetze.indexOf(unnummerierte.get(0));
@@ -1427,11 +1457,7 @@ public final class BefehlAnwender {
if (!fehlend.isEmpty()) {
return manuell(
befehl,
- "Fußnote "
- + String.join(", ", fehlend)
- + " kommt in "
- + norm.enbez()
- + " nicht vor.");
+ "Fußnote " + String.join(", ", fehlend) + " kommt in " + norm.enbez() + " nicht vor.");
}
normen.set(aufloesung.normIndex(), norm.mitAbsaetzen(absaetze));
return angewandt(befehl, norm.enbez());
@@ -1475,7 +1501,11 @@ public final class BefehlAnwender {
betroffene.addAll(ergebnis.betroffeneEnbez());
if (ergebnis.status() != Status.ANGEWANDT) {
meldungen[index] =
- "Teil " + (index + 1) + " (" + teil.stelle().anzeigeText() + "): "
+ "Teil "
+ + (index + 1)
+ + " ("
+ + teil.stelle().anzeigeText()
+ + "): "
+ ergebnis.begruendung();
}
}
@@ -1742,7 +1772,8 @@ public final class BefehlAnwender {
/**
* Zerlegt einen Zitatblock mehrerer Paragraphen an den §-Überschriften (nicht an Querverweisen)
- * und parst jeden Abschnitt zu einer {@link Norm}. Die Gliederung wird von der Vorlage übernommen.
+ * und parst jeden Abschnitt zu einer {@link Norm}. Die Gliederung wird von der Vorlage
+ * übernommen.
*/
private static List<Norm> parseNormenBlock(String block, @Nullable Gliederung gliederung) {
var normen = new ArrayList<Norm>();
@@ -1868,10 +1899,10 @@ public final class BefehlAnwender {
}
/**
- * Rückt die kanonischen Zitatzeilen auf die Ziel-Einrückung um: Aufzählungszeilen (und die
- * erste Zeile) auf {@code einrueckung}, Fortsetzungszeilen — etwa der Definitionstext unter
- * einer Kurzüberschrift — zwei Zeichen tiefer, damit sie Kindzeilen der Einheit bleiben
- * (dieselbe Form, die der ContentFlattener aus dem Stammgesetz-XML erzeugt).
+ * Rückt die kanonischen Zitatzeilen auf die Ziel-Einrückung um: Aufzählungszeilen (und die erste
+ * Zeile) auf {@code einrueckung}, Fortsetzungszeilen — etwa der Definitionstext unter einer
+ * Kurzüberschrift — zwei Zeichen tiefer, damit sie Kindzeilen der Einheit bleiben (dieselbe Form,
+ * die der ContentFlattener aus dem Stammgesetz-XML erzeugt).
*/
private static String rueckeZitatEin(String zitat, String einrueckung) {
var sb = new StringBuilder();
diff --git a/src/main/java/eu/mulk/aendggner/anwendung/InhaltsuebersichtAnwender.java b/src/main/java/eu/mulk/aendggner/anwendung/InhaltsuebersichtAnwender.java
index e9f84b6..acd42d7 100644
--- a/src/main/java/eu/mulk/aendggner/anwendung/InhaltsuebersichtAnwender.java
+++ b/src/main/java/eu/mulk/aendggner/anwendung/InhaltsuebersichtAnwender.java
@@ -74,12 +74,13 @@ final class InhaltsuebersichtAnwender {
/** Die adressierte Angabe: die §-/Gliederungs-Komponenten hinter der Inhaltsübersichts-Marke. */
private static List<Stelle.Komponente> zielKette(Stelle stelle) {
return stelle.komponenten().stream()
- .filter(
- k -> k instanceof Stelle.Paragraph || k instanceof Stelle.Gliederungseinheit)
+ .filter(k -> k instanceof Stelle.Paragraph || k instanceof Stelle.Gliederungseinheit)
.toList();
}
- /** Ersetzt die Zeilen von {@code von} bis {@code bis} durch die Angaben des Zitats (oder nichts). */
+ /**
+ * Ersetzt die Zeilen von {@code von} bis {@code bis} durch die Angaben des Zitats (oder nichts).
+ */
private static AngewandteAenderung ersetzeZeilen(
List<Norm> normen,
Aenderungsbefehl befehl,
@@ -139,8 +140,7 @@ final class InhaltsuebersichtAnwender {
// --- Zeilenmodell ----------------------------------------------------------------------------
- private record Zeilenfund(
- int absatzIndex, int vonZeile, int bisZeile, @Nullable String fehler) {
+ private record Zeilenfund(int absatzIndex, int vonZeile, int bisZeile, @Nullable String fehler) {
static Zeilenfund fehlgeschlagen(String begruendung) {
return new Zeilenfund(-1, -1, -1, begruendung);
}
@@ -148,8 +148,8 @@ final class InhaltsuebersichtAnwender {
/**
* Findet die (norm-weit eindeutige) Zeile der adressierten Angabe. Die Kette wird verschachtelt
- * aufgelöst: „Teil 2 Abschnitt 4“ sucht die Abschnitt-Zeile erst hinter der Teil-2-Zeile (und
- * vor dem nächsten Teil), sodass gleichnamige Abschnitte anderer Teile nicht stören.
+ * aufgelöst: „Teil 2 Abschnitt 4“ sucht die Abschnitt-Zeile erst hinter der Teil-2-Zeile (und vor
+ * dem nächsten Teil), sodass gleichnamige Abschnitte anderer Teile nicht stören.
*/
private static Zeilenfund findeZeile(Norm norm, List<Stelle.Komponente> kette) {
var ziel = kette.get(kette.size() - 1);
diff --git a/src/main/java/eu/mulk/aendggner/anwendung/SatzTeiler.java b/src/main/java/eu/mulk/aendggner/anwendung/SatzTeiler.java
index b457cf2..3360bc6 100644
--- a/src/main/java/eu/mulk/aendggner/anwendung/SatzTeiler.java
+++ b/src/main/java/eu/mulk/aendggner/anwendung/SatzTeiler.java
@@ -11,8 +11,8 @@ import org.jspecify.annotations.Nullable;
* Zerlegt einen Absatztext in Sätze im Rechtssinne, mit einer Stoppliste für juristische
* Abkürzungen und Datumsangaben („Abs.“, „31. März 2021“).
*
- * <p>Trägt der Text amtliche Satznummern als Unicode-Superskripte (bayerisches Landesrecht,
- * „¹Die freilebende Tierwelt …“), wird exakt an diesen geteilt statt heuristisch.
+ * <p>Trägt der Text amtliche Satznummern als Unicode-Superskripte (bayerisches Landesrecht, „¹Die
+ * freilebende Tierwelt …“), wird exakt an diesen geteilt statt heuristisch.
*/
public final class SatzTeiler {
@@ -182,8 +182,8 @@ public final class SatzTeiler {
/**
* Punkt einer Aufzählungsmarke am Zeilenanfang („… folgende Aufgaben ⏎ 1. Erlaß von Satzungen
* …“). Er beendet keinen Satz: die Glieder einer Aufzählung gehören zum tragenden Satz. Die
- * Beschränkung auf den Zeilenanfang unterscheidet die Marke von einer Zahl am Satzende („… beträgt
- * 30. Die Frist …“).
+ * Beschränkung auf den Zeilenanfang unterscheidet die Marke von einer Zahl am Satzende („…
+ * beträgt 30. Die Frist …“).
*/
private static boolean istAufzaehlungsMarke(String text, int punktPosition) {
var wort = wortVor(text, punktPosition);
diff --git a/src/main/java/eu/mulk/aendggner/anwendung/StellenAufloeser.java b/src/main/java/eu/mulk/aendggner/anwendung/StellenAufloeser.java
index dd8409e..ff77279 100644
--- a/src/main/java/eu/mulk/aendggner/anwendung/StellenAufloeser.java
+++ b/src/main/java/eu/mulk/aendggner/anwendung/StellenAufloeser.java
@@ -164,7 +164,9 @@ final class StellenAufloeser {
}
bereich =
zeilenBlock(
- text, labelRegex, bereich != null ? bereich : new SatzTeiler.SatzBereich(0, text.length()));
+ text,
+ labelRegex,
+ bereich != null ? bereich : new SatzTeiler.SatzBereich(0, text.length()));
if (bereich == null) {
return null;
}
diff --git a/src/main/java/eu/mulk/aendggner/gesetz/Gliederung.java b/src/main/java/eu/mulk/aendggner/gesetz/Gliederung.java
index 7a09093..00106d2 100644
--- a/src/main/java/eu/mulk/aendggner/gesetz/Gliederung.java
+++ b/src/main/java/eu/mulk/aendggner/gesetz/Gliederung.java
@@ -6,8 +6,8 @@ import org.jspecify.annotations.Nullable;
* Eine Gliederungseinheit (z.B. „Teil 2 — Anforderungen an zu errichtende Gebäude“ oder „2.
* Abschnitt — Koordinierung und Früherkennung“).
*
- * @param kennzahl die hierarchie-kodierende Gliederungskennzahl aus dem gii-XML (z.B. {@code 020020}
- * für Abschnitt 2 in Teil 2); {@code null} bei anderweitig konstruierten Einheiten.
+ * @param kennzahl die hierarchie-kodierende Gliederungskennzahl aus dem gii-XML (z.B. {@code
+ * 020020} für Abschnitt 2 in Teil 2); {@code null} bei anderweitig konstruierten Einheiten.
* @param bezeichnung die relative Bezeichnung („Teil 2“, „Abschnitt 2“).
* @param titel die Überschrift der Einheit ({@code null} bei titellosen Einheiten).
*/
diff --git a/src/main/java/eu/mulk/aendggner/gesetz/Superskript.java b/src/main/java/eu/mulk/aendggner/gesetz/Superskript.java
index 733c1f7..4ba8304 100644
--- a/src/main/java/eu/mulk/aendggner/gesetz/Superskript.java
+++ b/src/main/java/eu/mulk/aendggner/gesetz/Superskript.java
@@ -46,9 +46,9 @@ public final class Superskript {
}
/**
- * Wahr, wenn {@code text} mindestens eine amtliche Satznummer am Satzanfang trägt. Dient dazu, die
- * Schreibweise eines Stammgesetzes zu erkennen (Landesrecht mit amtlicher Satzzählung behält seine
- * Superskripte, Bundesrecht ohne solche verwirft sie).
+ * Wahr, wenn {@code text} mindestens eine amtliche Satznummer am Satzanfang trägt. Dient dazu,
+ * die Schreibweise eines Stammgesetzes zu erkennen (Landesrecht mit amtlicher Satzzählung behält
+ * seine Superskripte, Bundesrecht ohne solche verwirft sie).
*/
public static boolean traegtSatznummern(String text) {
var m = LAUF.matcher(text);
diff --git a/src/main/java/eu/mulk/aendggner/gesetz/land/LandesRechtLoader.java b/src/main/java/eu/mulk/aendggner/gesetz/land/LandesRechtLoader.java
index ecb10f8..c64ca21 100644
--- a/src/main/java/eu/mulk/aendggner/gesetz/land/LandesRechtLoader.java
+++ b/src/main/java/eu/mulk/aendggner/gesetz/land/LandesRechtLoader.java
@@ -6,17 +6,17 @@ import eu.mulk.aendggner.aenderung.parse.TextBereiniger;
import eu.mulk.aendggner.gesetz.Gesetz;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
-import java.text.Normalizer;
import java.nio.file.Files;
import java.nio.file.Path;
+import java.text.Normalizer;
import org.apache.tika.Tika;
import org.jboss.logging.Logger;
/**
* Liest ein Stammgesetz des Landesrechts aus der konsolidierten Fassung — als PDF oder als
* kanonischer Klartext. Deckt bayerisches Landesrecht (Gliederung in {@code Art.}, amtliche
- * Satznummern) ebenso ab wie die {@code §}-gegliederten Gesetze der übrigen Länder; das Sigel
- * folgt je Norm aus dem Text (siehe {@link LandesRechtTextParser}).
+ * Satznummern) ebenso ab wie die {@code §}-gegliederten Gesetze der übrigen Länder; das Sigel folgt
+ * je Norm aus dem Text (siehe {@link LandesRechtTextParser}).
*
* <p>PDFs durchlaufen dieselbe Aufbereitung wie Änderungsgesetze (Fontgrößen-Filter mit
* Superskript-Erhalt, Textbereinigung); der bereinigte Lineartext ist zugleich das dokumentierte
@@ -56,7 +56,7 @@ public final class LandesRechtLoader {
/**
* Stellt einen vom Zeilen-Reflow an das Satzende der Vornorm geklebten Normkopf („… verlangen.
- * Art. 17 Jagderlaubnis“) wieder auf eine eigene Zeile. Das doppelte Leerzeichen zwischen
+ * Art. 17 Jagderlaubnis“) wieder auf eine eigene Zeile. Das doppelte Leerzeichen zwischen
* Norm-Nummer und Titel unterscheidet den Normkopf von gewöhnlichen Querverweisen.
*/
private static String nachSatzendeGetrennteNormkoepfe(String text) {
diff --git a/src/main/java/eu/mulk/aendggner/gesetz/land/LandesRechtTextParser.java b/src/main/java/eu/mulk/aendggner/gesetz/land/LandesRechtTextParser.java
index 6c58c49..a256243 100644
--- a/src/main/java/eu/mulk/aendggner/gesetz/land/LandesRechtTextParser.java
+++ b/src/main/java/eu/mulk/aendggner/gesetz/land/LandesRechtTextParser.java
@@ -57,20 +57,22 @@ final class LandesRechtTextParser {
// nachgestelltem Schlüsselwort („I. Abschnitt“, Muster GLIEDERUNG). Der Titel steht — nach der
// kanonischen Aufbereitung — mit doppeltem Leerzeichen auf derselben Zeile.
private static final Pattern GLIEDERUNG_ARABISCH =
- Pattern.compile("^(Buch|Teil|Kapitel|Abschnitt|Unterabschnitt|Titel) (\\d+[a-z]?)\\s+(\\S.*)$");
+ Pattern.compile(
+ "^(Buch|Teil|Kapitel|Abschnitt|Unterabschnitt|Titel) (\\d+[a-z]?)\\s+(\\S.*)$");
// Römische Gliederung ohne Schlüsselwort („I. Rechtsform und Aufgaben“, NRW). Sie ist nur an der
// Stellung erkennbar, deshalb gilt dieselbe Absicherung wie für UNTER_GLIEDERUNG: kurzer,
// großgeschriebener, satzzeichenfreier Titel und ein Normkopf oder eine weitere Überschrift als
// nächste nicht-leere Zeile.
- private static final Pattern GLIEDERUNG_ROEMISCH = Pattern.compile("^([IVXLCDM]+)\\.\\s+(\\S.*)$");
+ private static final Pattern GLIEDERUNG_ROEMISCH =
+ Pattern.compile("^([IVXLCDM]+)\\.\\s+(\\S.*)$");
private static final Pattern UNTER_GLIEDERUNG = Pattern.compile("^(\\d+[a-z]?)\\.\\s+(\\S.*)$");
/**
* Die Inhaltsübersicht ist eine Norm ohne Sigel; Angabe-Befehle adressieren sie unter genau
- * diesem Namen (siehe {@code InhaltsuebersichtAnwender}). Ihre Zeilen tragen das
- * Übersichtsformat „§ N | Titel“.
+ * diesem Namen (siehe {@code InhaltsuebersichtAnwender}). Ihre Zeilen tragen das Übersichtsformat
+ * „§ N | Titel“.
*/
private static final String INHALTSUEBERSICHT = "Inhaltsübersicht";
@@ -81,12 +83,14 @@ final class LandesRechtTextParser {
Pattern.compile(
"^(§|Art\\.)\\s+(\\d+[a-z]?)\\s+"
// Querverweis-Schlüsselwörter nur als ganzes Wort ausschließen: „§ 4 Satz 2“ ist ein
- // Verweis, „§ 4 Satzungen“ dagegen ein Normtitel. Der Schutz „(?![a-zäöüß])“ verhindert,
+ // Verweis, „§ 4 Satzungen“ dagegen ein Normtitel. Der Schutz „(?![a-zäöüß])“
+ // verhindert,
// dass „Satz“ auch „Satzungen“, „Nummer“ auch „Nummerierung“ trifft.
+ "(?!(?:Absatz|Abs\\.|Satz|Sätze|Nummer|Nr\\.|Buchstabe|Buchst\\."
+ "|und|bis|oder|sowie|des|der|dieses)(?![a-zäöüß]))"
// Der Titel endet nicht auf einen Punkt: ein Normkopf trägt eine Überschrift, keinen
- // ganzen Satz. So wird ein am Zeilenanfang stehender Querverweis-Satz („§ 7 GAPInVeKoSG
+ // ganzen Satz. So wird ein am Zeilenanfang stehender Querverweis-Satz („§ 7
+ // GAPInVeKoSG
// findet entsprechend Anwendung.“) nicht fälschlich als Normkopf „§ 7“ gelesen.
+ "((?:\\p{Lu}|\\().*[^.])\\s*$");
@@ -210,8 +214,7 @@ final class LandesRechtTextParser {
gliederungsZaehler++;
elternKennzahl = String.format("%03d", gliederungsZaehler);
aktuelleGliederung =
- new Gliederung(
- elternKennzahl, roemisch.group(1) + ".", roemisch.group(2).strip());
+ new Gliederung(elternKennzahl, roemisch.group(1) + ".", roemisch.group(2).strip());
gliederungen.add(aktuelleGliederung);
} else {
var kennzahl =
@@ -278,8 +281,8 @@ final class LandesRechtTextParser {
}
/**
- * Ein Normkopf eröffnet nur dann eine neue Norm, wenn seine Nummer hinter der letzten liegt —
- * das fängt Querverweise ab, die die Negativliste nicht ausschließt.
+ * Ein Normkopf eröffnet nur dann eine neue Norm, wenn seine Nummer hinter der letzten liegt — das
+ * fängt Querverweise ab, die die Negativliste nicht ausschließt.
*/
private static boolean istNeuerNormKopf(String nummer, int letzteNormNummer) {
return numerisch(nummer) >= letzteNormNummer;
@@ -315,10 +318,7 @@ final class LandesRechtTextParser {
}
private static Norm baueNorm(
- String enbez,
- @Nullable String titel,
- @Nullable Gliederung gliederung,
- List<String> zeilen) {
+ String enbez, @Nullable String titel, @Nullable Gliederung gliederung, List<String> zeilen) {
boolean weggefallen = titel != null && WEGGEFALLEN_TITEL.matcher(titel).matches();
var absaetze = new ArrayList<Absatz>();
diff --git a/src/main/java/eu/mulk/aendggner/synopse/SynopseBuilder.java b/src/main/java/eu/mulk/aendggner/synopse/SynopseBuilder.java
index 1568aa9..ce4f1a1 100644
--- a/src/main/java/eu/mulk/aendggner/synopse/SynopseBuilder.java
+++ b/src/main/java/eu/mulk/aendggner/synopse/SynopseBuilder.java
@@ -50,13 +50,13 @@ public final class SynopseBuilder {
var manuell =
anwendung.protokoll().stream().filter(a -> a.status() == Status.MANUELL_PRUEFEN).toList();
- return new Synopse(alt, neu, eintraege, gliederungsAenderungen(alt, neu), manuell, parseWarnungen);
+ return new Synopse(
+ alt, neu, eintraege, gliederungsAenderungen(alt, neu), manuell, parseWarnungen);
}
/**
- * Paart die Gliederungseinheiten nach Kennzahl und sammelt die mit geänderter Überschrift.
- * Neu eingefügte Einheiten (ohne Kennzahl und ohne Alt-Pendant) erscheinen mit {@code alt ==
- * null}.
+ * Paart die Gliederungseinheiten nach Kennzahl und sammelt die mit geänderter Überschrift. Neu
+ * eingefügte Einheiten (ohne Kennzahl und ohne Alt-Pendant) erscheinen mit {@code alt == null}.
*/
private static List<Synopse.GliederungsAenderung> gliederungsAenderungen(Gesetz alt, Gesetz neu) {
var aenderungen = new ArrayList<Synopse.GliederungsAenderung>();
diff --git a/src/main/java/eu/mulk/aendggner/web/Multipart.java b/src/main/java/eu/mulk/aendggner/web/Multipart.java
index 3e5a059..745443b 100644
--- a/src/main/java/eu/mulk/aendggner/web/Multipart.java
+++ b/src/main/java/eu/mulk/aendggner/web/Multipart.java
@@ -17,7 +17,8 @@ final class Multipart {
private static final Pattern BOUNDARY_PATTERN = Pattern.compile("boundary=\"?([^\";]+)\"?");
private static final Pattern NAME_PATTERN = Pattern.compile("name=\"([^\"]*)\"");
private static final Pattern FILENAME_PATTERN = Pattern.compile("filename=\"([^\"]*)\"");
- private static final byte[] HEADER_BODY_SEPARATOR = "\r\n\r\n".getBytes(StandardCharsets.ISO_8859_1);
+ private static final byte[] HEADER_BODY_SEPARATOR =
+ "\r\n\r\n".getBytes(StandardCharsets.ISO_8859_1);
private Multipart() {}
@@ -33,7 +34,9 @@ final class Multipart {
var delimiter = ("--" + boundary).getBytes(StandardCharsets.ISO_8859_1);
var positions = new ArrayList<Integer>();
- for (int i = indexOf(body, delimiter, 0); i >= 0; i = indexOf(body, delimiter, i + delimiter.length)) {
+ for (int i = indexOf(body, delimiter, 0);
+ i >= 0;
+ i = indexOf(body, delimiter, i + delimiter.length)) {
positions.add(i);
}
diff --git a/src/main/java/eu/mulk/aendggner/web/StaticHandler.java b/src/main/java/eu/mulk/aendggner/web/StaticHandler.java
index 8cdf6e5..24a6e41 100644
--- a/src/main/java/eu/mulk/aendggner/web/StaticHandler.java
+++ b/src/main/java/eu/mulk/aendggner/web/StaticHandler.java
@@ -7,7 +7,10 @@ import java.io.InputStream;
import java.io.UncheckedIOException;
import java.nio.charset.StandardCharsets;
-/** Liefert eine einzelne, beim Start einmal geladene statische Ressource aus (Formular, Impressum, CSS, …). */
+/**
+ * Liefert eine einzelne, beim Start einmal geladene statische Ressource aus (Formular, Impressum,
+ * CSS, …).
+ */
final class StaticHandler implements HttpHandler {
private final byte[] content;
@@ -48,7 +51,8 @@ final class StaticHandler implements HttpHandler {
}
}
- private static void sendText(HttpExchange exchange, int status, String message) throws IOException {
+ private static void sendText(HttpExchange exchange, int status, String message)
+ throws IOException {
var body = message.getBytes(StandardCharsets.UTF_8);
exchange.getResponseHeaders().set("Content-Type", "text/plain; charset=utf-8");
exchange.sendResponseHeaders(status, body.length);
diff --git a/src/main/java/eu/mulk/aendggner/web/UploadHandler.java b/src/main/java/eu/mulk/aendggner/web/UploadHandler.java
index 8765ac3..efcb512 100644
--- a/src/main/java/eu/mulk/aendggner/web/UploadHandler.java
+++ b/src/main/java/eu/mulk/aendggner/web/UploadHandler.java
@@ -21,19 +21,20 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
/**
- * {@code POST /synopse} — nimmt Stammgesetz- und Änderungsgesetz-Datei(en) per
- * {@code multipart/form-data} entgegen, ruft {@link Pipeline#erzeugeSynopse} auf und liefert das
- * erzeugte HTML zurück.
+ * {@code POST /synopse} — nimmt Stammgesetz- und Änderungsgesetz-Datei(en) per {@code
+ * multipart/form-data} entgegen, ruft {@link Pipeline#erzeugeSynopse} auf und liefert das erzeugte
+ * HTML zurück.
*
- * <p>Hochgeladene Dateien landen ausschließlich als temporäre Dateien für die Dauer der Anfrage
- * und werden danach in jedem Fall gelöscht — es wird nichts dauerhaft gespeichert. Die eigentliche
+ * <p>Hochgeladene Dateien landen ausschließlich als temporäre Dateien für die Dauer der Anfrage und
+ * werden danach in jedem Fall gelöscht — es wird nichts dauerhaft gespeichert. Die eigentliche
* Verarbeitung läuft auf einem auf die Kernzahl begrenzten Thread-Pool mit fester Warteschlange;
* bei Überlast wird sofort mit {@code 503} abgelehnt, statt unbegrenzt Arbeit anzunehmen.
*/
final class UploadHandler implements HttpHandler {
private static final long MAX_PART_BYTES = 15L * 1024 * 1024; // 15 MB je Datei
- private static final long MAX_BODY_BYTES = 40L * 1024 * 1024; // Sicherheitsnetz für die gesamte Anfrage
+ private static final long MAX_BODY_BYTES =
+ 40L * 1024 * 1024; // Sicherheitsnetz für die gesamte Anfrage
private static final long TIMEOUT_SECONDS = 30;
private final ExecutorService pipelinePool;
@@ -77,7 +78,8 @@ final class UploadHandler implements HttpHandler {
try {
Files.deleteIfExists(path);
} catch (IOException ignored) {
- // Aufräumen ist best effort; ein verwaistes Temp-File blockiert die Antwort nicht.
+ // Aufräumen ist best effort; ein verwaistes Temp-File blockiert die Antwort
+ // nicht.
}
});
} catch (IOException ignored) {
@@ -169,7 +171,8 @@ final class UploadHandler implements HttpHandler {
var future = pipelinePool.submit(job);
ergebnis = future.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
} catch (RejectedExecutionException e) {
- sendText(exchange, 503, "Der Dienst ist gerade ausgelastet. Bitte in Kürze erneut versuchen.");
+ sendText(
+ exchange, 503, "Der Dienst ist gerade ausgelastet. Bitte in Kürze erneut versuchen.");
return;
} catch (TimeoutException e) {
sendText(exchange, 504, "Die Verarbeitung hat zu lange gedauert und wurde abgebrochen.");
@@ -215,7 +218,8 @@ final class UploadHandler implements HttpHandler {
return filename.replaceAll("[^A-Za-z0-9._-]", "_");
}
- private static void sendText(HttpExchange exchange, int status, String message) throws IOException {
+ private static void sendText(HttpExchange exchange, int status, String message)
+ throws IOException {
var body = message.getBytes(StandardCharsets.UTF_8);
exchange.getResponseHeaders().set("Content-Type", "text/plain; charset=utf-8");
exchange.sendResponseHeaders(status, body.length);
diff --git a/src/main/java/eu/mulk/aendggner/web/WebMain.java b/src/main/java/eu/mulk/aendggner/web/WebMain.java
index 9d71558..815f0db 100644
--- a/src/main/java/eu/mulk/aendggner/web/WebMain.java
+++ b/src/main/java/eu/mulk/aendggner/web/WebMain.java
@@ -34,7 +34,8 @@ public final class WebMain {
"/datenschutz",
new StaticHandler("/eu/mulk/aendggner/web/datenschutz.html", "text/html; charset=utf-8"));
server.createContext(
- "/style.css", new StaticHandler("/eu/mulk/aendggner/web/style.css", "text/css; charset=utf-8"));
+ "/style.css",
+ new StaticHandler("/eu/mulk/aendggner/web/style.css", "text/css; charset=utf-8"));
server.createContext("/synopse", new UploadHandler());
server.start();