Erste fachliche Strukturregel ergänzen: UNH-/UNT-Referenznummer prüfen

This commit is contained in:
2026-03-26 08:21:13 +01:00
parent 1b4b22b073
commit 6a7d150007
6 changed files with 222 additions and 47 deletions

View File

@@ -13,15 +13,16 @@ import de.gecheckt.asv.validation.model.ValidationResult;
import de.gecheckt.asv.validation.model.ValidationSeverity;
/**
* Default implementation of StructureValidator that checks general structural rules.
* Standardimplementierung des StructureValidator, die allgemeine Strukturregeln prüft.
*
* Rules checked:
* 1. InputFile must contain at least one Message
* 2. Each Message must contain at least one Segment
* 3. Segment names must not be empty
* 4. Field positions within a Segment must be unique and positive
* 5. Segment positions within a Message must be unique and positive
* 6. Message positions within an InputFile must be unique and positive
* Geprüfte Regeln:
* 1. Die Eingabedatei muss mindestens eine Nachricht enthalten
* 2. Jede Nachricht muss mindestens ein Segment enthalten
* 3. Segmentnamen dürfen nicht leer sein
* 4. Feldpositionen innerhalb eines Segments müssen eindeutig und positiv sein
* 5. Segmentpositionen innerhalb einer Nachricht müssen eindeutig und positiv sein
* 6. Nachrichtenpositionen innerhalb einer Eingabedatei müssen eindeutig und positiv sein
* 7. UNH- und UNT-Referenznummern müssen innerhalb einer Nachricht übereinstimmen
*/
public class DefaultStructureValidator implements StructureValidator {
@@ -44,10 +45,10 @@ public class DefaultStructureValidator implements StructureValidator {
"",
0,
"",
"At least one message required"
"Mindestens eine Nachricht erforderlich"
));
} else {
// Process messages if they exist
// Verarbeite Nachrichten, wenn sie vorhanden sind
validateMessages(inputFile.messages(), errors);
}
@@ -55,10 +56,10 @@ public class DefaultStructureValidator implements StructureValidator {
}
/**
* Validates all messages in the input file.
* Validiert alle Nachrichten in der Eingabedatei.
*
* @param messages the list of messages to validate
* @param errors the list to add validation errors to
* @param messages die Liste der zu validierenden Nachrichten
* @param errors die Liste zum Hinzufügen von Validierungsfehlern
*/
private void validateMessages(List<Message> messages, List<ValidationError> errors) {
var messagePositions = new HashSet<Integer>();
@@ -66,35 +67,83 @@ public class DefaultStructureValidator implements StructureValidator {
for (var message : messages) {
var messagePosition = message.messagePosition();
// Rule 6: Message positions must be unique and positive
// Regel 6: Nachrichtenpositionen müssen eindeutig und positiv sein
if (!messagePositions.add(messagePosition)) {
errors.add(createError(
"STRUCTURE_006",
"Duplicate message position: " + messagePosition,
"Doppelte Nachrichtenposition: " + messagePosition,
ValidationSeverity.ERROR,
"",
messagePosition,
"",
0,
String.valueOf(messagePosition),
"Unique positive message positions required"
"Einzigartige positive Nachrichtenpositionen erforderlich"
));
}
// Validate segments in this message
// Validiere Segmente in dieser Nachricht
validateSegments(message.segments(), messagePosition, errors);
// Regel 7: UNH- und UNT-Referenznummern müssen übereinstimmen
validateUnhUntReferenceNumbers(message, errors);
}
}
/**
* Validates all segments in a message.
* Validiert, dass die Referenznummern in UNH und UNT übereinstimmen.
*
* @param segments the list of segments to validate
* @param messagePosition the position of the parent message
* @param errors the list to add validation errors to
* @param message die zu validierende Nachricht
* @param errors die Liste zum Hinzufügen von Validierungsfehlern
*/
private void validateUnhUntReferenceNumbers(Message message, List<ValidationError> errors) {
var unhSegment = message.getFirstSegment("UNH");
var untSegment = message.getFirstSegment("UNT");
// Prüft, ob beide Segmente vorhanden sind, bevor eine Validierung erfolgt
if (unhSegment.isPresent() && untSegment.isPresent()) {
var unhFields = unhSegment.get().fields();
var untFields = untSegment.get().fields();
// UNH-Referenznummer ist im 1. Feld (erstes Feld nach dem Segmentnamen)
// UNT-Referenznummer ist im 2. Feld (zweites Feld nach dem Segmentnamen)
if (!unhFields.isEmpty() && untFields.size() >= 2) {
var unhReference = unhFields.get(0).rawValue();
var untReference = untFields.get(1).rawValue();
// Entferne möglicherweise vorhandenes abschließendes Hochkomma bei untReference
String normalizedUntReference = untReference;
if (untReference.endsWith("'")) {
normalizedUntReference = untReference.substring(0, untReference.length() - 1);
}
// Vergleiche die Referenznummern
if (!unhReference.equals(normalizedUntReference)) {
errors.add(createError(
"STRUCTURE_007",
"UNH and UNT reference numbers do not match",
ValidationSeverity.ERROR,
"UNH/UNT",
message.messagePosition(),
"",
0,
unhReference + " != " + normalizedUntReference,
"Reference numbers in UNH and UNT must match"
));
}
}
}
}
/**
* Validiert alle Segmente einer Nachricht.
*
* @param segments die Liste der zu validierenden Segmente
* @param messagePosition die Position der übergeordneten Nachricht
* @param errors die Liste zum Hinzufügen von Validierungsfehlern
*/
private void validateSegments(List<Segment> segments, int messagePosition, List<ValidationError> errors) {
// Rule 2: Each Message must contain at least one Segment
// Regel 2: Jede Nachricht muss mindestens ein Segment enthalten
if (segments.isEmpty()) {
errors.add(createError(
"STRUCTURE_002",
@@ -105,9 +154,9 @@ public class DefaultStructureValidator implements StructureValidator {
"",
0,
"",
"At least one segment required per message"
"Mindestens ein Segment pro Nachricht erforderlich"
));
return; // No need to validate segments if there are none
return; // Keine Validierung der Segmente notwendig, wenn keine vorhanden sind
}
var segmentPositions = new HashSet<Integer>();
@@ -116,22 +165,22 @@ public class DefaultStructureValidator implements StructureValidator {
var segmentName = segment.segmentName();
var segmentPosition = segment.segmentPosition();
// Rule 3: Segment names must not be empty
// Regel 3: Segmentnamen dürfen nicht leer sein
if (segmentName == null || segmentName.isEmpty()) {
errors.add(createError(
"STRUCTURE_003",
"Segment name must not be empty",
"Segmentname darf nicht leer sein",
ValidationSeverity.ERROR,
segmentName != null ? segmentName : "",
segmentPosition,
"",
0,
segmentName != null ? segmentName : "null",
"Non-empty segment name required"
"Nicht-leerer Segmentname erforderlich"
));
}
// Rule 5: Segment positions must be unique and positive
// Regel 5: Segmentpositionen müssen eindeutig und positiv sein
if (!segmentPositions.add(segmentPosition)) {
errors.add(createError(
"STRUCTURE_005",
@@ -142,7 +191,7 @@ public class DefaultStructureValidator implements StructureValidator {
"",
0,
String.valueOf(segmentPosition),
"Unique positive segment positions required"
"Einzigartige positive Segmentpositionen erforderlich"
));
}
@@ -152,12 +201,12 @@ public class DefaultStructureValidator implements StructureValidator {
}
/**
* Validates all fields in a segment.
* Validiert alle Felder eines Segments.
*
* @param fields the list of fields to validate
* @param segmentName the name of the parent segment
* @param segmentPosition the position of the parent segment
* @param errors the list to add validation errors to
* @param fields die Liste der zu validierenden Felder
* @param segmentName der Name des übergeordneten Segments
* @param segmentPosition die Position des übergeordneten Segments
* @param errors die Liste zum Hinzufügen von Validierungsfehlern
*/
private void validateFields(List<Field> fields, String segmentName, int segmentPosition, List<ValidationError> errors) {
var fieldPositions = new HashSet<Integer>();
@@ -165,7 +214,7 @@ public class DefaultStructureValidator implements StructureValidator {
for (var field : fields) {
var fieldPosition = field.fieldPosition();
// Rule 4: Field positions must be unique and positive
// Regel 4: Feldpositionen müssen eindeutig und positiv sein
if (!fieldPositions.add(fieldPosition)) {
errors.add(createError(
"STRUCTURE_004",
@@ -176,25 +225,25 @@ public class DefaultStructureValidator implements StructureValidator {
field.getFieldName().orElse(""),
fieldPosition,
String.valueOf(fieldPosition),
"Unique positive field positions required"
"Einzigartige positive Feldpositionen erforderlich"
));
}
}
}
/**
* Helper method to create a ValidationError with consistent parameters.
* Hilfsmethode zur Erstellung eines ValidationError mit konsistenten Parametern.
*
* @param errorCode the error code
* @param description the error description
* @param severity the validation severity
* @param segmentName the segment name
* @param segmentPosition the segment position
* @param fieldName the field name
* @param fieldPosition the field position
* @param actualValue the actual value
* @param expectedRule the expected rule
* @return a new ValidationError instance
* @param errorCode der Fehlercode
* @param description die Fehlerbeschreibung
* @param severity die Validierungsschweregrad
* @param segmentName der Segmentname
* @param segmentPosition die Segmentposition
* @param fieldName der Feldname
* @param fieldPosition die Feldposition
* @param actualValue der tatsächliche Wert
* @param expectedRule die erwartete Regel
* @return eine neue ValidationError-Instanz
*/
private ValidationError createError(String errorCode,
String description,