Skip to content

Commit

Permalink
Improve dialect rejection messages, additional tests
Browse files Browse the repository at this point in the history
  • Loading branch information
MikeEdgar committed Feb 20, 2021
1 parent ad78d7b commit bf75262
Show file tree
Hide file tree
Showing 8 changed files with 89 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public abstract class Dialect {
protected char elementRepeater;

protected boolean initialized;
protected boolean rejected;
protected String rejectionMessage;

protected String transactionType;
protected String transactionVersionString;
Expand Down Expand Up @@ -90,7 +90,11 @@ public boolean isConfirmed() {
}

public boolean isRejected() {
return rejected;
return rejectionMessage != null;
}

public String getRejectionMessage() {
return rejectionMessage;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ boolean initialize(CharacterSet characters) {
characters.setClass(segmentDelimiter, CharacterClass.SEGMENT_DELIMITER);
initialized = true;
} else {
rejectionMessage = "Unable to obtain version from EDIFACT header segment";
initialized = false;
}

Expand Down Expand Up @@ -189,7 +190,7 @@ boolean processInterchangeHeader(CharacterSet characters, char value) {
*/
characters.setClass(elementDelimiter, CharacterClass.ELEMENT_DELIMITER);
} else if (segmentDelimiter == value) {
rejected = !initialize(characters);
initialize(characters);
return isConfirmed();
}

Expand Down Expand Up @@ -232,7 +233,7 @@ boolean processServiceStringAdvice(CharacterSet characters, char value) {
header.deleteCharAt(index--);
} else if (isIndexBeyondUNBFirstElement()) {
if (value == elementDelimiter || value == segmentDelimiter) {
rejected = !initialize(characters);
initialize(characters);
proceed = isConfirmed();
}
} else if (value == 'B') {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ public void parse() throws IOException, EDIException {
CharacterClass clazz = characters.getClass(input);
previous = state;
state = State.transition(state, dialect, clazz);
LOGGER.finer(() -> String.format("State %s(%s, %s) -> %s", previous, clazz, Dialect.getStandard(dialect), state));
LOGGER.finer(() -> String.format("%s + (%s, '%s', %s) -> %s", previous, Dialect.getStandard(dialect), (char) input, clazz, state));

switch (state) {
case INITIAL:
Expand Down Expand Up @@ -418,9 +418,10 @@ private boolean dialectConfirmed(State confirmed) throws EDIException {
} else if (dialect.isRejected()) {
buffer.clear();
clearQueues();
String rejectionMessage = dialect.getRejectionMessage();
dialect = null;
state = State.INITIAL;
throw error(EDIException.INVALID_STATE, "Invalid header segment");
throw error(EDIException.INVALID_STATE, rejectionMessage);
}

return false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ public class TradacomsDialect extends Dialect {
public static final String MHD = "MHD";

private static final String[] EMPTY = new String[0];
private static final int TRADACOMS_ELEMENT_OFFSET = 3;

static final char DFLT_SEGMENT_TERMINATOR = '\'';
static final char DFLT_DATA_ELEMENT_SEPARATOR = '+';
Expand Down Expand Up @@ -62,6 +63,7 @@ boolean initialize(CharacterSet characters) {
initialized = true;
characters.setClass(segmentDelimiter, CharacterClass.SEGMENT_DELIMITER);
} else {
rejectionMessage = "Unable to obtain version from TRADACOMS header segment";
initialized = false;
}

Expand Down Expand Up @@ -97,7 +99,11 @@ public boolean appendHeader(CharacterSet characters, char value) {
case 0:
header = new StringBuilder();
break;
case 3:
case TRADACOMS_ELEMENT_OFFSET:
if (value != segmentTagTerminator) {
rejectionMessage = String.format("Expected TRADACOMS segment tag delimiter '%s', but found '%s'", segmentTagTerminator, value);
return false;
}
/*
* TRADACOMS delimiters are fixed. Do not set the element delimiter
* until after the segment tag has been passed to prevent triggering
Expand All @@ -124,7 +130,7 @@ public boolean appendHeader(CharacterSet characters, char value) {

boolean processInterchangeHeader(CharacterSet characters, char value) {
if (segmentDelimiter == value) {
rejected = !initialize(characters);
initialize(characters);
return isConfirmed();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ boolean initialize(CharacterSet characters) {

for (int i = 0, m = X12_ISA_LENGTH; i < m; i++) {
if (ELEMENT == header[i] && X12_ISA_TOKENS[e++] != i) {
rejectionMessage = String.format("Unexpected element delimiter value '%s' in X12 header position %d", ELEMENT, i + 1);
return false;
}
}
Expand Down Expand Up @@ -150,7 +151,7 @@ public boolean appendHeader(CharacterSet characters, char value) {
boolean proceed = true;

if (index == X12_SEGMENT_OFFSET) {
rejected = !initialize(characters);
initialize(characters);
proceed = isConfirmed();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1939,4 +1939,47 @@ void testDecimalScaleAvailableFromSchema() throws EDISchemaException, IOExceptio

assertEquals(new BigDecimal("2554.38"), tds01);
}

/**
* Original issue: https://github.com/xlate/staedi/issues/174
*
* @throws Exception
*/
@Test
void testOtherDialectTerminalSegmentsIgnored_Issue174() throws Exception {
EDIInputFactory factory = EDIInputFactory.newFactory();
factory.setProperty(EDIInputFactory.EDI_VALIDATE_CONTROL_STRUCTURE, true);
factory.setProperty(EDIInputFactory.EDI_VALIDATE_CONTROL_CODE_VALUES, false);
EDIStreamReader reader = factory.createEDIStreamReader(getClass().getResourceAsStream("/EDIFACT/issue174/other_dialect_term_segments.edi"));
List<Object> unexpected = new ArrayList<>();

try {
while (reader.hasNext()) {
switch (reader.next()) {
case SEGMENT_ERROR:
case ELEMENT_OCCURRENCE_ERROR:
case ELEMENT_DATA_ERROR:
unexpected.add(reader.getErrorType());
break;
default:
break;
}
}
} catch (Exception e) {
unexpected.add(e);
} finally {
reader.close();
}

assertEquals(0, unexpected.size());
}

@Test
void testTRADACOMS_IncorrectSegmentTagDelimiterIsInvalid() throws Exception {
EDIInputFactory factory = EDIInputFactory.newFactory();
EDIStreamReader reader = factory.createEDIStreamReader(getClass().getResourceAsStream("/TRADACOMS/order-wrong-segment-tag-delimiter.edi"));
List<Object> unexpected = new ArrayList<>();
EDIStreamException thrown = assertThrows(EDIStreamException.class, () -> reader.next());
assertTrue(thrown.getMessage().contains("Expected TRADACOMS segment tag delimiter"));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
UNB+UNOA:3+005435656:1+006415160:1+210220:1605+00000000000001'
UNH+00000000000001+CUSTOM:D:97B:UN'
IEA+1:525'
END+1:525'
UNT+24+00000000000001'
UNZ+1+00000000000001'
18 changes: 18 additions & 0 deletions src/test/resources/TRADACOMS/order-wrong-segment-tag-delimiter.edi
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
STX+ANA:1+5000000000000:SOME STORES LTD+5010000000000:SUPPLIER UK LTD+070315:130233+000007+PASSW+ORDHDR+B'
MHD+1+ORDHDR:9'
TYP+0430+NEW-ORDERS'
SDT+5010000000000:000030034'
CDT+5000000000000'
FIL+1630+1+070315'
MTR+6'
MHD+2+ORDERS:9'
CLO+5000000000283:89828+EAST SOMEWHERE DEPOT'
ORD+70970::070315'
DIN+070321++0000'
OLD+1+5010210000000++:00893592+12+60++++CRUSTY ROLLS:4 PACK'
OTR+1'
MTR+7'
MHD+3+ORDTLR:9'
OFT+1'
MTR+3'
END+3'

0 comments on commit bf75262

Please sign in to comment.