Skip to content

Commit e3c0cda

Browse files
authored
Merge pull request #39 from imsweb/fix-ambiguous-loop-bug-38
Fix ambiguous loop bug (#38)
2 parents d363fed + 0e0a962 commit e3c0cda

File tree

4 files changed

+281
-34
lines changed

4 files changed

+281
-34
lines changed

src/main/java/com/imsweb/x12/reader/X12Reader.java

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import com.imsweb.x12.mapping.SegmentDefinition;
2929
import com.imsweb.x12.mapping.TransactionDefinition;
3030
import com.imsweb.x12.mapping.TransactionDefinition.Usage;
31+
3132
import com.thoughtworks.xstream.XStream;
3233
import com.thoughtworks.xstream.io.xml.StaxDriver;
3334
import com.thoughtworks.xstream.security.NoTypePermission;
@@ -200,7 +201,7 @@ public List<String> getErrors() {
200201
public List<String> getFatalErrors() {
201202
return _fatalErrors;
202203
}
203-
204+
204205
public Separators getSeparators() {
205206
return _separators;
206207
}
@@ -423,23 +424,23 @@ private Separators getSeparators(Reader reader) throws IOException {
423424
char[] firstLine = new char[_ISA_LENGTH];
424425
int ret = reader.read(firstLine);
425426
boolean isAlphaNumeric = Character.isDigit(firstLine[_SEGMENT_SEPARATOR_POS]) ||
426-
Character.isDigit(firstLine[_ELEMENT_SEPARATOR_POS]) ||
427-
Character.isDigit(firstLine[_COMPOSITE_SEPARATOR_POS]) ||
428-
Character.isLetter(firstLine[_SEGMENT_SEPARATOR_POS]) ||
429-
Character.isLetter(firstLine[_ELEMENT_SEPARATOR_POS]) ||
430-
Character.isLetter(firstLine[_COMPOSITE_SEPARATOR_POS]);
427+
Character.isDigit(firstLine[_ELEMENT_SEPARATOR_POS]) ||
428+
Character.isDigit(firstLine[_COMPOSITE_SEPARATOR_POS]) ||
429+
Character.isLetter(firstLine[_SEGMENT_SEPARATOR_POS]) ||
430+
Character.isLetter(firstLine[_ELEMENT_SEPARATOR_POS]) ||
431+
Character.isLetter(firstLine[_COMPOSITE_SEPARATOR_POS]);
431432

432433
boolean isWhiteSpace = Character.isWhitespace(firstLine[_SEGMENT_SEPARATOR_POS]) ||
433-
Character.isWhitespace(firstLine[_ELEMENT_SEPARATOR_POS]) ||
434-
Character.isWhitespace(firstLine[_COMPOSITE_SEPARATOR_POS]);
434+
Character.isWhitespace(firstLine[_ELEMENT_SEPARATOR_POS]) ||
435+
Character.isWhitespace(firstLine[_COMPOSITE_SEPARATOR_POS]);
435436
if (ret != _ISA_LENGTH || (isAlphaNumeric || isWhiteSpace)) {
436437
_errors.add("Error getting separators");
437438
return null;
438439
}
439440
// don't need to reset the reader---we need to check the version on the next line
440441
return new Separators(firstLine[_SEGMENT_SEPARATOR_POS],
441-
firstLine[_ELEMENT_SEPARATOR_POS],
442-
firstLine[_COMPOSITE_SEPARATOR_POS]);
442+
firstLine[_ELEMENT_SEPARATOR_POS],
443+
firstLine[_COMPOSITE_SEPARATOR_POS]);
443444
}
444445

445446
/**
@@ -710,7 +711,7 @@ private LoopConfig getMatchedLoop(String[] tokens, String previousLoopID) {
710711
// starting a new loop but we aren't quite sure which one yet. Remove loops where the segment is known to be the last segment of that loop - clearly we aren't in a new loop then
711712
matchedLoops = matchedLoops.stream().filter(lc -> !(lc.getLastSegmentXid().getXid().equals(tokens[0]) && codesValidatedForLoopId(tokens, lc.getLastSegmentXid()))).collect(
712713
Collectors.toList());
713-
result = matchedLoops.isEmpty() ? null : getFinalizedMatch(previousLoopID, matchedLoops);
714+
result = matchedLoops.isEmpty() ? null : (matchedLoops.size() == 1 ? matchedLoops.get(0) : getFinalizedMatch(previousLoopID, matchedLoops));
714715
}
715716
else if (matchedLoops.size() == 1)
716717
result = matchedLoops.get(0);
@@ -750,17 +751,20 @@ private boolean isChildSegment(String previousLoopId, String[] tokens) {
750751
* @return the finalized loop match
751752
*/
752753
private LoopConfig getFinalizedMatch(String previousLoopId, List<LoopConfig> matchedLoops) {
753-
LoopConfig result = matchedLoops.get(0);
754+
LoopConfig result = null;
754755
for (LoopConfig lc : _config) {
755756
if (lc.getLoopId().equals(previousLoopId)) {
756-
for (LoopConfig s1 : matchedLoops) {
757+
// if one of the ambiguous loops is a child loop of the previous loop then we should use that one
758+
if (lc.getChildList() != null)
759+
result = matchedLoops.stream().filter(matchedLoop -> lc.getChildList().contains(matchedLoop.getLoopId())).findFirst().orElse(null);
760+
761+
// otherwise, if one of the ambiguous loops has the same parent as the previous loop's parent then we should use that loop
762+
if (result == null) {
757763
String parentLoop = getParentLoop(previousLoopId, null);
758-
if ((lc.getChildList() != null && lc.getChildList().contains(s1.getLoopId()))
759-
|| (parentLoop != null && parentLoop.equals(getParentLoop(s1.getLoopId(), null)))) {
760-
result = s1;
761-
break;
762-
}
764+
if (parentLoop != null)
765+
result = matchedLoops.stream().filter(matchedLoop -> parentLoop.equals(getParentLoop(matchedLoop.getLoopId(), null))).findFirst().orElse(null);
763766
}
767+
break;
764768
}
765769
}
766770
return result;

0 commit comments

Comments
 (0)