From fff07478fdb9611968ea7fb00c32199f65fbced8 Mon Sep 17 00:00:00 2001 From: Michael Edgar Date: Sun, 28 Nov 2021 13:17:56 -0500 Subject: [PATCH] Deprecate retrieval of reference code via text for structural events --- .../stream/StaEDIFilteredStreamReader.java | 5 ++ .../internal/stream/StaEDIInputFactory.java | 2 + .../internal/stream/StaEDIStreamReader.java | 67 ++++++++++++++++--- .../stream/StaEDIXMLStreamReader.java | 10 ++- .../stream/json/StaEDIJsonParser.java | 7 +- .../internal/stream/tokenization/Lexer.java | 7 ++ .../tokenization/ProxyEventHandler.java | 23 ++++--- .../io/xlate/edi/stream/EDIInputFactory.java | 22 +++++- .../io/xlate/edi/stream/EDIStreamReader.java | 17 +++++ .../stream/SegmentValidationTest.java | 62 +++++++++-------- .../stream/StaEDIStreamReaderTest.java | 34 ++++------ .../io/xlate/edi/test/StaEDITestEvent.java | 2 +- 12 files changed, 183 insertions(+), 75 deletions(-) diff --git a/src/main/java/io/xlate/edi/internal/stream/StaEDIFilteredStreamReader.java b/src/main/java/io/xlate/edi/internal/stream/StaEDIFilteredStreamReader.java index b225bc45..2fca429e 100644 --- a/src/main/java/io/xlate/edi/internal/stream/StaEDIFilteredStreamReader.java +++ b/src/main/java/io/xlate/edi/internal/stream/StaEDIFilteredStreamReader.java @@ -211,4 +211,9 @@ public InputStream getBinaryData() { public EDIReference getSchemaTypeReference() { return delegate.getSchemaTypeReference(); } + + @Override + public boolean hasText() { + return delegate.hasText(); + } } diff --git a/src/main/java/io/xlate/edi/internal/stream/StaEDIInputFactory.java b/src/main/java/io/xlate/edi/internal/stream/StaEDIInputFactory.java index 92cda8d6..12c240bc 100644 --- a/src/main/java/io/xlate/edi/internal/stream/StaEDIInputFactory.java +++ b/src/main/java/io/xlate/edi/internal/stream/StaEDIInputFactory.java @@ -35,11 +35,13 @@ public class StaEDIInputFactory extends EDIInputFactory { private EDIInputErrorReporter reporter; + @SuppressWarnings("deprecation") public StaEDIInputFactory() { supportedProperties.add(EDI_VALIDATE_CONTROL_STRUCTURE); supportedProperties.add(EDI_VALIDATE_CONTROL_CODE_VALUES); supportedProperties.add(EDI_IGNORE_EXTRANEOUS_CHARACTERS); supportedProperties.add(EDI_NEST_HIERARCHICAL_LOOPS); + supportedProperties.add(EDI_ENABLE_LOOP_TEXT); supportedProperties.add(XML_DECLARE_TRANSACTION_XMLNS); supportedProperties.add(XML_WRAP_TRANSACTION_CONTENTS); diff --git a/src/main/java/io/xlate/edi/internal/stream/StaEDIStreamReader.java b/src/main/java/io/xlate/edi/internal/stream/StaEDIStreamReader.java index 7ea912a7..f0affef7 100644 --- a/src/main/java/io/xlate/edi/internal/stream/StaEDIStreamReader.java +++ b/src/main/java/io/xlate/edi/internal/stream/StaEDIStreamReader.java @@ -47,6 +47,8 @@ public class StaEDIStreamReader implements EDIStreamReader, Configurable { private static final Logger LOGGER = Logger.getLogger(StaEDIStreamReader.class.getName()); + private static final CharBuffer GROUP_TEXT = CharBuffer.wrap(ProxyEventHandler.LOOP_CODE_GROUP); + private static final CharBuffer TRANSACTION_TEXT = CharBuffer.wrap(ProxyEventHandler.LOOP_CODE_TRANSACTION); private Schema controlSchema; private final Map properties; @@ -57,6 +59,7 @@ public class StaEDIStreamReader implements EDIStreamReader, Configurable { private boolean complete = false; private boolean closed = false; + private boolean deprecationLogged = false; public StaEDIStreamReader( InputStream stream, @@ -102,9 +105,38 @@ void requireEvent(String message, EDIStreamEvent... events) { throw new IllegalStateException(message); } + private void logDeprecation(EDIStreamEvent event) { + if (!deprecationLogged) { + deprecationLogged = true; + + LOGGER.warning(() -> "DEPRECATION - Retrieving text for event " + event + " will not be supported in a future release. " + + "Use `getReferenceCode` or `getSchemaTypeReference` to retrieve additional information for non-textual event types."); + } + } + private CharBuffer getBuffer() { checkTextState(); - return proxy.getCharacters(); + EDIStreamEvent event = getEventType(); + + switch (event) { + case START_GROUP: + case END_GROUP: + logDeprecation(event); + return GROUP_TEXT; + + case START_TRANSACTION: + case END_TRANSACTION: + logDeprecation(event); + return TRANSACTION_TEXT; + + case START_LOOP: + case END_LOOP: + logDeprecation(event); + return CharBuffer.wrap(proxy.getSchemaTypeReference().getReferencedType().getCode()); + + default: + return proxy.getCharacters(); + } } @Override @@ -187,6 +219,7 @@ private EDIStreamEvent nextEvent() throws EDIStreamException { try { this.setBinaryDataLength(Long.parseLong(getText())); } catch (NumberFormatException e) { + lexer.invalidate(); throw new EDIStreamException("Failed to parse binary element length", location, e); } } @@ -339,28 +372,36 @@ public EDIStreamValidationError getErrorType() { } private void checkTextState() { + if (!hasText()) { + throw new IllegalStateException("not a valid text state [" + getEventType() + ']'); + } + } + + @Override + public boolean hasText() { EDIStreamEvent event = getEventType(); if (event == null) { - throw new IllegalStateException("not a valid text state [" + event + ']'); + return false; } switch (event) { - case START_GROUP: - case START_TRANSACTION: - case START_LOOP: case START_SEGMENT: - case END_GROUP: - case END_TRANSACTION: - case END_LOOP: case END_SEGMENT: case ELEMENT_DATA: case ELEMENT_DATA_ERROR: case ELEMENT_OCCURRENCE_ERROR: case SEGMENT_ERROR: - break; + return true; + case START_GROUP: + case START_TRANSACTION: + case START_LOOP: + case END_GROUP: + case END_TRANSACTION: + case END_LOOP: + return enableLoopText(); default: - throw new IllegalStateException("not a valid text state [" + event + ']'); + return false; } } @@ -477,4 +518,10 @@ boolean ignoreExtraneousCharacters() { boolean nestHierarchicalLoops() { return getProperty(EDIInputFactory.EDI_NEST_HIERARCHICAL_LOOPS, Boolean::parseBoolean, true); } + + @SuppressWarnings("deprecation") + boolean enableLoopText() { + return getProperty(EDIInputFactory.EDI_ENABLE_LOOP_TEXT, Boolean::parseBoolean, true); + } + } diff --git a/src/main/java/io/xlate/edi/internal/stream/StaEDIXMLStreamReader.java b/src/main/java/io/xlate/edi/internal/stream/StaEDIXMLStreamReader.java index b634bc41..71f2b7d2 100644 --- a/src/main/java/io/xlate/edi/internal/stream/StaEDIXMLStreamReader.java +++ b/src/main/java/io/xlate/edi/internal/stream/StaEDIXMLStreamReader.java @@ -35,6 +35,7 @@ import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamReader; +import io.xlate.edi.internal.stream.tokenization.ProxyEventHandler; import io.xlate.edi.schema.EDIComplexType; import io.xlate.edi.schema.EDIReference; import io.xlate.edi.stream.EDIInputFactory; @@ -47,7 +48,7 @@ final class StaEDIXMLStreamReader implements XMLStreamReader { private static final Logger LOGGER = Logger.getLogger(StaEDIXMLStreamReader.class.getName()); private static final QName DUMMY_QNAME = new QName("DUMMY"); private static final QName INTERCHANGE = new QName(EDINamespaces.LOOPS, "INTERCHANGE", prefixOf(EDINamespaces.LOOPS)); - private static final QName TRANSACTION = new QName(EDINamespaces.LOOPS, "TRANSACTION", prefixOf(EDINamespaces.LOOPS)); + private static final QName TRANSACTION = new QName(EDINamespaces.LOOPS, ProxyEventHandler.LOOP_CODE_TRANSACTION, prefixOf(EDINamespaces.LOOPS)); private final EDIStreamReader ediReader; private final Map properties; @@ -206,7 +207,8 @@ private void enqueueEvent(EDIStreamEvent ediEvent) throws XMLStreamException { case START_TRANSACTION: withinTransaction = true; - readerText = ediReader.getText(); + // Use `text` if the deprecated property is in use + readerText = ediReader.hasText() ? ediReader.getText() : ediReader.getReferenceCode(); name = buildName(elementStack.getFirst(), EDINamespaces.LOOPS, readerText); enqueueEvent(START_ELEMENT, name, true); determineTransactionSegments(); @@ -214,7 +216,9 @@ private void enqueueEvent(EDIStreamEvent ediEvent) throws XMLStreamException { case START_GROUP: case START_LOOP: - name = buildName(elementStack.getFirst(), EDINamespaces.LOOPS, ediReader.getText()); + // Use `text` if the deprecated property is in use + readerText = ediReader.hasText() ? ediReader.getText() : ediReader.getReferenceCode(); + name = buildName(elementStack.getFirst(), EDINamespaces.LOOPS, readerText); enqueueEvent(START_ELEMENT, name, true); break; diff --git a/src/main/java/io/xlate/edi/internal/stream/json/StaEDIJsonParser.java b/src/main/java/io/xlate/edi/internal/stream/json/StaEDIJsonParser.java index f5a8661f..5795ca5b 100644 --- a/src/main/java/io/xlate/edi/internal/stream/json/StaEDIJsonParser.java +++ b/src/main/java/io/xlate/edi/internal/stream/json/StaEDIJsonParser.java @@ -231,7 +231,12 @@ void enqueueEvent(EDIStreamEvent ediEvent) { case START_GROUP: case START_TRANSACTION: case START_LOOP: - enqueueStructureBegin("loop", ediReader.getText()); + if (ediReader.hasText()) { + // The deprecated property is in use + enqueueStructureBegin("loop", ediReader.getText()); + } else { + enqueueStructureBegin("loop", ediReader.getReferenceCode()); + } break; case START_SEGMENT: enqueueStructureBegin("segment", ediReader.getText()); diff --git a/src/main/java/io/xlate/edi/internal/stream/tokenization/Lexer.java b/src/main/java/io/xlate/edi/internal/stream/tokenization/Lexer.java index c0f2b808..e1239ce9 100644 --- a/src/main/java/io/xlate/edi/internal/stream/tokenization/Lexer.java +++ b/src/main/java/io/xlate/edi/internal/stream/tokenization/Lexer.java @@ -145,6 +145,13 @@ public Dialect getDialect() { return dialect; } + public void invalidate() { + if (state != State.INVALID) { + previous = state; + state = State.INVALID; + } + } + public void setBinaryLength(long binaryLength) { this.binaryRemain = binaryLength; diff --git a/src/main/java/io/xlate/edi/internal/stream/tokenization/ProxyEventHandler.java b/src/main/java/io/xlate/edi/internal/stream/tokenization/ProxyEventHandler.java index 4d47b4ea..a09078f1 100644 --- a/src/main/java/io/xlate/edi/internal/stream/tokenization/ProxyEventHandler.java +++ b/src/main/java/io/xlate/edi/internal/stream/tokenization/ProxyEventHandler.java @@ -40,6 +40,9 @@ public class ProxyEventHandler implements EventHandler { + public static final String LOOP_CODE_GROUP = EDIType.Type.GROUP.toString(); + public static final String LOOP_CODE_TRANSACTION = EDIType.Type.TRANSACTION.toString(); + private final StaEDIStreamLocation location; private final boolean nestHierarchicalLoops; @@ -200,17 +203,17 @@ public void interchangeEnd() { public void loopBegin(EDIReference typeReference) { final String loopCode = typeReference.getReferencedType().getCode(); - if (EDIType.Type.TRANSACTION.toString().equals(loopCode)) { + if (LOOP_CODE_TRANSACTION.equals(loopCode)) { transaction = true; transactionSchemaAllowed = true; - enqueueEvent(EDIStreamEvent.START_TRANSACTION, EDIStreamValidationError.NONE, loopCode, typeReference, location); + enqueueEvent(EDIStreamEvent.START_TRANSACTION, EDIStreamValidationError.NONE, null, typeReference, location); if (transactionValidator != null) { transactionValidator.reset(); } - } else if (EDIType.Type.GROUP.toString().equals(loopCode)) { - enqueueEvent(EDIStreamEvent.START_GROUP, EDIStreamValidationError.NONE, loopCode, typeReference, location); + } else if (LOOP_CODE_GROUP.equals(loopCode)) { + enqueueEvent(EDIStreamEvent.START_GROUP, EDIStreamValidationError.NONE, null, typeReference, location); } else { - enqueueEvent(EDIStreamEvent.START_LOOP, EDIStreamValidationError.NONE, loopCode, typeReference, location); + enqueueEvent(EDIStreamEvent.START_LOOP, EDIStreamValidationError.NONE, null, typeReference, location); if (nestHierarchicalLoops && isHierarchicalLoop(typeReference.getReferencedType())) { EDILoopType loop = (EDILoopType) typeReference.getReferencedType(); @@ -229,17 +232,17 @@ public void loopEnd(EDIReference typeReference) { // Validator can not be null when a loopEnd event has been signaled. validator().validateLoopSyntax(this); - if (EDIType.Type.TRANSACTION.toString().equals(loopCode)) { + if (LOOP_CODE_TRANSACTION.equals(loopCode)) { transaction = false; dialect.transactionEnd(); - enqueueEvent(EDIStreamEvent.END_TRANSACTION, EDIStreamValidationError.NONE, loopCode, typeReference, location); - } else if (EDIType.Type.GROUP.toString().equals(loopCode)) { + enqueueEvent(EDIStreamEvent.END_TRANSACTION, EDIStreamValidationError.NONE, null, typeReference, location); + } else if (LOOP_CODE_GROUP.equals(loopCode)) { dialect.groupEnd(); - enqueueEvent(EDIStreamEvent.END_GROUP, EDIStreamValidationError.NONE, loopCode, typeReference, location); + enqueueEvent(EDIStreamEvent.END_GROUP, EDIStreamValidationError.NONE, null, typeReference, location); } else if (nestHierarchicalLoops && isHierarchicalLoop(typeReference.getReferencedType())) { levelCheckPending = true; } else { - enqueueEvent(EDIStreamEvent.END_LOOP, EDIStreamValidationError.NONE, loopCode, typeReference, location); + enqueueEvent(EDIStreamEvent.END_LOOP, EDIStreamValidationError.NONE, null, typeReference, location); } } diff --git a/src/main/java/io/xlate/edi/stream/EDIInputFactory.java b/src/main/java/io/xlate/edi/stream/EDIInputFactory.java index c219ca59..9aa147c0 100644 --- a/src/main/java/io/xlate/edi/stream/EDIInputFactory.java +++ b/src/main/java/io/xlate/edi/stream/EDIInputFactory.java @@ -66,15 +66,33 @@ public abstract class EDIInputFactory extends PropertySupport { * When set to true, hierarchical loops will be nested in the EDI input * stream. The nesting structure is determined by the linkage specified by * the EDI data itself using pointers given in the EDI schema for a loop. - * + * * For example, the hierarchical information given by the X12 HL segment. - * + * * Default value: true * * @since 1.18 */ public static final String EDI_NEST_HIERARCHICAL_LOOPS = "io.xlate.edi.stream.EDI_NEST_HIERARCHICAL_LOOPS"; + /** + * When set to true, functional group, transaction, and loop start/end + * events will allow for {@link EDIStreamReader#getText()} to be called, + * which is the legacy behavior. + * + * The default value is `true` and this property is deprecated. In the next + * major release, the property's default value will be `false`. + * + * Default value: true + * + * @since 1.19 + * @deprecated use {@link EDIStreamReader#getReferenceCode()} and + * {@link EDIStreamReader#getSchemaTypeReference()} to retrieve + * additional information for non-textual event types. + */ + @Deprecated + public static final String EDI_ENABLE_LOOP_TEXT = "io.xlate.edi.stream.EDI_ENABLE_LOOP_TEXT"; //NOSONAR + /** * When set to true, simple data elements not containing data will be * represented via the JSON parsers as a null value. diff --git a/src/main/java/io/xlate/edi/stream/EDIStreamReader.java b/src/main/java/io/xlate/edi/stream/EDIStreamReader.java index 96dd24f0..7b99f2ff 100644 --- a/src/main/java/io/xlate/edi/stream/EDIStreamReader.java +++ b/src/main/java/io/xlate/edi/stream/EDIStreamReader.java @@ -446,4 +446,21 @@ int getTextCharacters(int sourceStart, * @since 1.9 */ EDIReference getSchemaTypeReference(); + + /** + * Return true if the current event has text, false otherwise. + * The following events have text: + *
    + *
  • START_SEGMENT + *
  • END_SEGMENT + *
  • ELEMENT_DATA + *
  • ELEMENT_DATA_ERROR + *
  • ELEMENT_OCCURRENCE_ERROR + *
  • SEGMENT_ERROR + *
+ * + * @return true if the current event has text, false otherwise + * @since 1.19 + */ + boolean hasText(); } diff --git a/src/test/java/io/xlate/edi/internal/stream/SegmentValidationTest.java b/src/test/java/io/xlate/edi/internal/stream/SegmentValidationTest.java index 587f8360..a24c3828 100644 --- a/src/test/java/io/xlate/edi/internal/stream/SegmentValidationTest.java +++ b/src/test/java/io/xlate/edi/internal/stream/SegmentValidationTest.java @@ -475,9 +475,11 @@ void testImplementationValidSequence() throws EDISchemaException, EDIStreamExcep assertTrue(!reader.hasNext(), "Unexpected segment errors exist"); } + @SuppressWarnings("deprecation") @Test void testImplementationValidAlternateSequence() throws EDISchemaException, EDIStreamException { EDIInputFactory factory = EDIInputFactory.newFactory(); + factory.setProperty(EDIInputFactory.EDI_ENABLE_LOOP_TEXT, "false"); InputStream stream = new ByteArrayInputStream(("" + "ISA*00* *00* *ZZ*ReceiverID *ZZ*Sender *050812*1953*^*00501*508121953*0*P*:~" + "S01*X~" @@ -510,22 +512,22 @@ void testImplementationValidAlternateSequence() throws EDISchemaException, EDISt reader.setTransactionSchema(schemaFactory.createSchema(getClass().getResource("/x12/EDISchemaSegmentValidationImpl.xml"))); List expected = Arrays.asList( - StaEDITestEvent.forEvent(EDIStreamEvent.START_TRANSACTION, "TRANSACTION", "TRANSACTION"), + StaEDITestEvent.forEvent(EDIStreamEvent.START_TRANSACTION, null, "TRANSACTION"), // Loop A - StaEDITestEvent.forEvent(EDIStreamEvent.START_LOOP, "L0000", "0000A"), - StaEDITestEvent.forEvent(EDIStreamEvent.END_LOOP, "L0000", "0000A"), + StaEDITestEvent.forEvent(EDIStreamEvent.START_LOOP, null, "0000A"), + StaEDITestEvent.forEvent(EDIStreamEvent.END_LOOP, null, "0000A"), // Loop C - Occurrence 1 - StaEDITestEvent.forEvent(EDIStreamEvent.START_LOOP, "L0000", "0000C"), - StaEDITestEvent.forEvent(EDIStreamEvent.END_LOOP, "L0000", "0000C"), + StaEDITestEvent.forEvent(EDIStreamEvent.START_LOOP, null, "0000C"), + StaEDITestEvent.forEvent(EDIStreamEvent.END_LOOP, null, "0000C"), // Loop B - StaEDITestEvent.forEvent(EDIStreamEvent.START_LOOP, "L0000", "0000B"), - StaEDITestEvent.forEvent(EDIStreamEvent.END_LOOP, "L0000", "0000B"), + StaEDITestEvent.forEvent(EDIStreamEvent.START_LOOP, null, "0000B"), + StaEDITestEvent.forEvent(EDIStreamEvent.END_LOOP, null, "0000B"), // Loop D - StaEDITestEvent.forEvent(EDIStreamEvent.START_LOOP, "L0000", "0000D"), - StaEDITestEvent.forEvent(EDIStreamEvent.END_LOOP, "L0000", "0000D"), + StaEDITestEvent.forEvent(EDIStreamEvent.START_LOOP, null, "0000D"), + StaEDITestEvent.forEvent(EDIStreamEvent.END_LOOP, null, "0000D"), // Loop C - Occurrence 2 - StaEDITestEvent.forEvent(EDIStreamEvent.START_LOOP, "L0000", "0000C"), - StaEDITestEvent.forEvent(EDIStreamEvent.END_LOOP, "L0000", "0000C"), + StaEDITestEvent.forEvent(EDIStreamEvent.START_LOOP, null, "0000C"), + StaEDITestEvent.forEvent(EDIStreamEvent.END_LOOP, null, "0000C"), StaEDITestEvent.forError(EDIStreamValidationError.MANDATORY_SEGMENT_MISSING, "S20", "S20")); @@ -588,9 +590,11 @@ void testImplementationValidSequenceAllMissing() throws EDISchemaException, EDIS assertTrue(!reader.hasNext(), "Unexpected segment errors exist"); } + @SuppressWarnings("deprecation") @Test void testImplementationValidSequenceWithCompositeDiscr() throws EDISchemaException, EDIStreamException { EDIInputFactory factory = EDIInputFactory.newFactory(); + factory.setProperty(EDIInputFactory.EDI_ENABLE_LOOP_TEXT, "false"); SchemaFactory schemaFactory = SchemaFactory.newFactory(); InputStream stream = new ByteArrayInputStream(("" + "ISA*00* *00* *ZZ*ReceiverID *ZZ*Sender *050812*1953*^*00501*508121953*0*P*:~" @@ -622,18 +626,18 @@ void testImplementationValidSequenceWithCompositeDiscr() throws EDISchemaExcepti reader.setTransactionSchema(schemaFactory.createSchema(getClass().getResource("/x12/EDISchemaSegmentValidationImpl2.xml"))); List expected = Arrays.asList( - StaEDITestEvent.forEvent(EDIStreamEvent.START_TRANSACTION, "TRANSACTION", "TRANSACTION"), + StaEDITestEvent.forEvent(EDIStreamEvent.START_TRANSACTION, null, "TRANSACTION"), // Loop A - StaEDITestEvent.forEvent(EDIStreamEvent.START_LOOP, "L0000", "0000A"), + StaEDITestEvent.forEvent(EDIStreamEvent.START_LOOP, null, "0000A"), // Loop AXX - StaEDITestEvent.forEvent(EDIStreamEvent.START_LOOP, "L0002", "0002AXX"), - StaEDITestEvent.forEvent(EDIStreamEvent.END_LOOP, "L0002", "0002AXX"), + StaEDITestEvent.forEvent(EDIStreamEvent.START_LOOP, null, "0002AXX"), + StaEDITestEvent.forEvent(EDIStreamEvent.END_LOOP, null, "0002AXX"), // Loop AYY - StaEDITestEvent.forEvent(EDIStreamEvent.START_LOOP, "L0002", "0002AYY"), + StaEDITestEvent.forEvent(EDIStreamEvent.START_LOOP, null, "0002AYY"), StaEDITestEvent.forError(EDIStreamValidationError.SEGMENT_EXCEEDS_MAXIMUM_USE, "S31", "S31"), StaEDITestEvent.forError(EDIStreamValidationError.IMPLEMENTATION_SEGMENT_BELOW_MINIMUM_USE, "S31", "S31B"), - StaEDITestEvent.forEvent(EDIStreamEvent.END_LOOP, "L0002", "0002AYY"), - StaEDITestEvent.forEvent(EDIStreamEvent.END_LOOP, "L0000", "0000A")); + StaEDITestEvent.forEvent(EDIStreamEvent.END_LOOP, null, "0002AYY"), + StaEDITestEvent.forEvent(EDIStreamEvent.END_LOOP, null, "0000A")); List events = new ArrayList<>(); events.add(StaEDITestEvent.from(reader, false)); @@ -645,9 +649,11 @@ void testImplementationValidSequenceWithCompositeDiscr() throws EDISchemaExcepti assertEquals(expected, events); } + @SuppressWarnings("deprecation") @Test void testImplementation_Only_BHT_HL_Valid() throws EDISchemaException, EDIStreamException { EDIInputFactory factory = EDIInputFactory.newFactory(); + factory.setProperty(EDIInputFactory.EDI_ENABLE_LOOP_TEXT, "false"); SchemaFactory schemaFactory = SchemaFactory.newFactory(); InputStream stream = getClass().getResourceAsStream("/x12/sample837-small.edi"); @@ -664,24 +670,24 @@ void testImplementation_Only_BHT_HL_Valid() throws EDISchemaException, EDIStream reader.setTransactionSchema(schemaFactory.createSchema(getClass().getResource("/x12/005010X222/837.xml"))); List expected = Arrays.asList( - StaEDITestEvent.forEvent(EDIStreamEvent.START_TRANSACTION, "TRANSACTION", "TRANSACTION"), + StaEDITestEvent.forEvent(EDIStreamEvent.START_TRANSACTION, null, "TRANSACTION"), // Occurrence 1 - StaEDITestEvent.forEvent(EDIStreamEvent.START_LOOP, "L0001", "L0001"), + StaEDITestEvent.forEvent(EDIStreamEvent.START_LOOP, null, "L0001"), StaEDITestEvent.forError(EDIStreamValidationError.IMPLEMENTATION_UNUSED_SEGMENT_PRESENT, "NM1", "NM1"), StaEDITestEvent.forError(EDIStreamValidationError.IMPLEMENTATION_UNUSED_SEGMENT_PRESENT, "PER", "PER"), - StaEDITestEvent.forEvent(EDIStreamEvent.END_LOOP, "L0001", "L0001"), + StaEDITestEvent.forEvent(EDIStreamEvent.END_LOOP, null, "L0001"), // Occurrence 2 - StaEDITestEvent.forEvent(EDIStreamEvent.START_LOOP, "L0001", "L0001"), + StaEDITestEvent.forEvent(EDIStreamEvent.START_LOOP, null, "L0001"), StaEDITestEvent.forError(EDIStreamValidationError.IMPLEMENTATION_UNUSED_SEGMENT_PRESENT, "NM1", "NM1"), - StaEDITestEvent.forEvent(EDIStreamEvent.END_LOOP, "L0001", "L0001"), + StaEDITestEvent.forEvent(EDIStreamEvent.END_LOOP, null, "L0001"), // Loop 2010A - StaEDITestEvent.forEvent(EDIStreamEvent.START_LOOP, "L0002", "2010A"), + StaEDITestEvent.forEvent(EDIStreamEvent.START_LOOP, null, "2010A"), StaEDITestEvent.forError(EDIStreamValidationError.IMPLEMENTATION_UNUSED_SEGMENT_PRESENT, "PRV", "PRV"), - StaEDITestEvent.forEvent(EDIStreamEvent.END_LOOP, "L0002", "2010A"), - StaEDITestEvent.forEvent(EDIStreamEvent.START_TRANSACTION, "TRANSACTION", "TRANSACTION"), + StaEDITestEvent.forEvent(EDIStreamEvent.END_LOOP, null, "2010A"), + StaEDITestEvent.forEvent(EDIStreamEvent.START_TRANSACTION, null, "TRANSACTION"), // Loop 2010A - StaEDITestEvent.forEvent(EDIStreamEvent.START_LOOP, "L0002", "2010A"), - StaEDITestEvent.forEvent(EDIStreamEvent.END_LOOP, "L0002", "2010A")); + StaEDITestEvent.forEvent(EDIStreamEvent.START_LOOP, null, "2010A"), + StaEDITestEvent.forEvent(EDIStreamEvent.END_LOOP, null, "2010A")); List events = new ArrayList<>(); events.add(StaEDITestEvent.from(reader, false)); diff --git a/src/test/java/io/xlate/edi/internal/stream/StaEDIStreamReaderTest.java b/src/test/java/io/xlate/edi/internal/stream/StaEDIStreamReaderTest.java index 52ab6340..2f191131 100644 --- a/src/test/java/io/xlate/edi/internal/stream/StaEDIStreamReaderTest.java +++ b/src/test/java/io/xlate/edi/internal/stream/StaEDIStreamReaderTest.java @@ -1215,7 +1215,6 @@ void testGetBinaryDataInvalid() throws Exception { EDIStreamReader reader = factory.createEDIStreamReader(stream); EDIStreamEvent event; - String tag = null; EDIStreamException thrown = null; try { @@ -1226,9 +1225,7 @@ void testGetBinaryDataInvalid() throws Exception { break; } - tag = reader.getText(); - - if ("BIN".equals(tag)) { + if (reader.getEventType() == EDIStreamEvent.START_SEGMENT && "BIN".equals(reader.getText())) { reader.next(); long binaryDataLength = Long.parseLong(reader.getText()); assertEquals(1839, binaryDataLength); @@ -1255,33 +1252,33 @@ void testGetBinaryDataInvalidLength() throws Exception { Schema schema = schemaFactory.createSchema(getClass().getResource("/x12/EDISchemaBinarySegment.xml")); EDIStreamEvent event; - String tag = null; - EDIStreamException thrown = null; + EDIStreamException bin01ParseException = null; + EDIStreamException inconsistentParser = null; try { while (reader.hasNext()) { try { - reader.nextTag(); + event = reader.nextTag(); } catch (NoSuchElementException e) { break; } - if (reader.getEventType() == EDIStreamEvent.START_TRANSACTION) { + if (event == EDIStreamEvent.START_TRANSACTION) { reader.setTransactionSchema(schema); assertThrows(IllegalStateException.class, () -> reader.setBinaryDataLength(1L)); - } else { - tag = reader.getText(); - - if ("BIN".equals(tag)) { - thrown = assertThrows(EDIStreamException.class, () -> reader.nextTag()); - break; - } + } else if (event == EDIStreamEvent.START_SEGMENT && "BIN".equals(reader.getText())) { + // BIN01 is non-numeric + bin01ParseException = assertThrows(EDIStreamException.class, () -> reader.nextTag()); + inconsistentParser = assertThrows(EDIStreamException.class, () -> reader.nextTag()); + break; } } } finally { reader.close(); } - assertNotNull(thrown); + + assertNotNull(bin01ParseException); + assertNotNull(inconsistentParser); } @Test @@ -1295,7 +1292,6 @@ void testGetBinaryDataValid() EDIStreamReader reader = factory.createEDIStreamReader(stream); EDIStreamEvent event; - String tag = null; try { while (reader.hasNext()) { @@ -1305,9 +1301,7 @@ void testGetBinaryDataValid() break; } - tag = reader.getText(); - - if ("BIN".equals(tag)) { + if (reader.getEventType() == EDIStreamEvent.START_SEGMENT && "BIN".equals(reader.getText())) { reader.next(); long binaryDataLength = Long.parseLong(reader.getText()); assertEquals(2768, binaryDataLength); diff --git a/src/test/java/io/xlate/edi/test/StaEDITestEvent.java b/src/test/java/io/xlate/edi/test/StaEDITestEvent.java index ab920de1..565b361f 100644 --- a/src/test/java/io/xlate/edi/test/StaEDITestEvent.java +++ b/src/test/java/io/xlate/edi/test/StaEDITestEvent.java @@ -41,7 +41,7 @@ public static StaEDITestEvent from(EDIStreamReader reader, boolean includeLocati return new StaEDITestEvent(reader.getEventType(), error ? reader.getErrorType() : null, - reader.getText(), + reader.hasText() ? reader.getText() : null, reader.getReferenceCode(), includeLocation ? reader.getLocation().copy() : null); }