Skip to content

Commit

Permalink
Skip validation for EDIFACT UNA; validate empty elements from syntax
Browse files Browse the repository at this point in the history
  • Loading branch information
MikeEdgar committed Jan 23, 2021
1 parent a3c58c0 commit e110aaa
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 28 deletions.
66 changes: 39 additions & 27 deletions src/main/java/io/xlate/edi/internal/stream/StaEDIStreamWriter.java
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ public class StaEDIStreamWriter implements EDIStreamWriter, ElementDataHandler,
private CharBuffer elementBuffer = CharBuffer.allocate(500);
private final StringBuilder formattedElement = new StringBuilder();
private List<EDIValidationException> errors = new ArrayList<>();
private CharArraySequence elementHolder = new CharArraySequence();

private char segmentTerminator;
private char segmentTagTerminator;
Expand Down Expand Up @@ -403,12 +404,6 @@ public EDIStreamWriter endInterchange() throws EDIStreamException {
public EDIStreamWriter writeStartSegment(String name) throws EDIStreamException {
ensureLevel(LEVEL_INTERCHANGE);
location.incrementSegmentPosition(name);
validate(validator -> validator.validateSegment(this, name));

if (exitTransaction(name)) {
transaction = false;
validate(validator -> validator.validateSegment(this, name));
}

if (state == State.INITIAL) {
dialect = DialectFactory.getDialect(name);
Expand All @@ -422,19 +417,24 @@ public EDIStreamWriter writeStartSegment(String name) throws EDIStreamException
*/
dialect = DialectFactory.getDialect(EDIFACTDialect.UNA);
writeServiceAdviceString();
segmentValidation(name);
// Now write the UNB
writeString(name);
} else {
writeString(name);

if (EDIFACTDialect.UNA.equals(name)) {
writeString(name);
writeServiceAdviceCharacters();
} else {
segmentValidation(name);
writeString(name);
}
}
} else {
segmentValidation(name);
writeString(name);
}
} else {
segmentValidation(name);
writeString(name);
}

Expand All @@ -445,6 +445,15 @@ public EDIStreamWriter writeStartSegment(String name) throws EDIStreamException
return this;
}

void segmentValidation(String name) {
validate(validator -> validator.validateSegment(this, name));

if (exitTransaction(name)) {
transaction = false;
validate(validator -> validator.validateSegment(this, name));
}
}

void terminateSegmentTag() throws EDIStreamException {
if (this.segmentTagTerminator != '\0') {
write(this.segmentTagTerminator);
Expand Down Expand Up @@ -820,7 +829,14 @@ public boolean binaryData(InputStream binary) {

@Override
public boolean elementData(char[] text, int start, int length) {
// No operation
elementHolder.set(text, start, length);
dialect.elementData(elementHolder, location);
Validator validator = validator();

if (validator != null && !validator.validateElement(dialect, location, elementHolder, null)) {
reportElementErrors(validator, elementHolder);
}

return true;
}

Expand Down Expand Up @@ -899,15 +915,7 @@ private void validateCompositeOccurrence() {
errors.clear();

if (!validator.validCompositeOccurrences(dialect, location)) {
for (UsageError error : validator.getElementErrors()) {
elementError(error.getError().getCategory(),
error.getError(),
error.getTypeReference(),
"",
location.getElementPosition(),
location.getComponentPosition(),
location.getElementOccurrence());
}
reportElementErrors(validator, "");
}

if (!errors.isEmpty()) {
Expand All @@ -933,15 +941,7 @@ private CharSequence validateElement(Runnable setupCommand, CharSequence data) {
setupCommand.run();

if (!validator.validateElement(dialect, location, data, this.formattedElement)) {
for (UsageError error : validator.getElementErrors()) {
elementError(error.getError().getCategory(),
error.getError(),
error.getTypeReference(),
result,
location.getElementPosition(),
location.getComponentPosition(),
location.getElementOccurrence());
}
reportElementErrors(validator, result);
}

if (!errors.isEmpty()) {
Expand All @@ -956,6 +956,18 @@ private CharSequence validateElement(Runnable setupCommand, CharSequence data) {
return result;
}

void reportElementErrors(Validator validator, CharSequence data) {
for (UsageError error : validator.getElementErrors()) {
elementError(error.getError().getCategory(),
error.getError(),
error.getTypeReference(),
data,
location.getElementPosition(),
location.getComponentPosition(),
location.getElementOccurrence());
}
}

EDIValidationException validationExceptionChain(List<EDIValidationException> errors) {
Iterator<EDIValidationException> iter = errors.iterator();
EDIValidationException first = iter.next();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
import io.xlate.edi.stream.EDIOutputFactory;
import io.xlate.edi.stream.EDIStreamConstants;
import io.xlate.edi.stream.EDIStreamConstants.Delimiters;
import io.xlate.edi.stream.EDIStreamConstants.Standards;
import io.xlate.edi.stream.EDIStreamEvent;
import io.xlate.edi.stream.EDIStreamException;
import io.xlate.edi.stream.EDIStreamReader;
Expand Down Expand Up @@ -2026,7 +2027,7 @@ void testOutputCompositeMissingSyntax() throws Exception {
write(writer, "UNH", "1", new String[] { "CONTRL", "4", "2", "UN" });
write(writer, "UCI", "1", "SENDER", "RECEIVER", "7");

writer.writeStartSegment("UCM").writeElement("1");
writer.writeStartSegment("UCM").writeElement("1").writeEmptyElement().writeElement("7");
EDIValidationException thrown = assertThrows(EDIValidationException.class, () -> writer.writeEndSegment());
EDIStreamValidationError error = thrown.getError();
assertEquals(EDIStreamValidationError.CONDITIONAL_REQUIRED_DATA_ELEMENT_MISSING, error);
Expand Down Expand Up @@ -2117,4 +2118,36 @@ void testIncompleteUNB() throws IOException, EDIStreamException, EDISchemaExcept

assertEquals("UNA:+.? 'UNB+UNOA:3'UNH", new String(stream.toByteArray()));
}

@Test
void testIncompleteUNBValidated() throws IOException, EDIStreamException, EDISchemaException {
final EDIOutputFactory factory = EDIOutputFactory.newFactory();
ByteArrayOutputStream stream = new ByteArrayOutputStream(4096);
EDIValidationException thrown = null;

try (EDIStreamWriter writer = factory.createEDIStreamWriter(stream)) {
Schema schema = SchemaFactory.newFactory().getControlSchema(Standards.EDIFACT, new String[] { "UNOA", "3" });
writer.setControlSchema(schema);

writer.startInterchange();
writer.writeStartSegment("UNA")
.writeEndSegment();
writer.writeStartSegment("UNB")
.writeStartElement()
.writeComponent("UNOA")
.writeComponent("3")
.endElement();

thrown = assertThrows(EDIValidationException.class, () -> writer.writeEndSegment());
}

for (int position : Arrays.asList(2, 3, 4, 5)) {
assertEquals(EDIStreamEvent.ELEMENT_OCCURRENCE_ERROR, thrown.getEvent());
assertEquals(EDIStreamValidationError.REQUIRED_DATA_ELEMENT_MISSING, thrown.getError());
assertEquals("UNB", thrown.getLocation().getSegmentTag());
assertEquals(2, thrown.getLocation().getSegmentPosition());
assertEquals(position, thrown.getLocation().getElementPosition());
thrown = thrown.getNextException();
}
}
}

0 comments on commit e110aaa

Please sign in to comment.