Skip to content

Commit

Permalink
Merge pull request #35 from imsweb/x12_string_from_loop-33
Browse files Browse the repository at this point in the history
X12 string from loop (#33)
  • Loading branch information
ctmay4 committed Jun 22, 2020
2 parents dfc5eb4 + b5016d3 commit 2279931
Show file tree
Hide file tree
Showing 7 changed files with 554 additions and 146 deletions.
1 change: 1 addition & 0 deletions src/main/java/com/imsweb/x12/Separators.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ public Separators(Character segment, Character element, Character composite) {
setSegment(segment);
setElement(element);
setCompositeElement(composite);
setLineBreak(LineBreak.NONE);
}

/**
Expand Down
58 changes: 8 additions & 50 deletions src/main/java/com/imsweb/x12/reader/X12Reader.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import com.imsweb.x12.LineBreak;
import com.imsweb.x12.Loop;
import com.imsweb.x12.Segment;
import com.imsweb.x12.Separators;
Expand All @@ -36,10 +35,10 @@

public class X12Reader {

private static int _ISA_LENGTH = 106;
private static int _ELEMENT_SEPARATOR_POS = 3; // array position
private static int _COMPOSITE_SEPARATOR_POS = 104; // array position
private static int _SEGMENT_SEPARATOR_POS = 105; // array position
private static final int _ISA_LENGTH = 106;
private static final int _ELEMENT_SEPARATOR_POS = 3; // array position
private static final int _COMPOSITE_SEPARATOR_POS = 104; // array position
private static final int _SEGMENT_SEPARATOR_POS = 105; // array position

private static final String _X091_ANSI_VERSION = "004010X091A1";
private static final String _X221_ANSI_VERSION = "005010X221A1";
Expand All @@ -59,6 +58,7 @@ public class X12Reader {
private Map<String, List<Set<String>>> _childLoopTracker = new HashMap<>();
private Separators _separators;
TransactionDefinition _definition;
private FileType _type;

/**
* All supported X12 file definitions
Expand Down Expand Up @@ -86,7 +86,7 @@ public enum FileType {
* Load definition from file
* @return a TransactionDefinition
*/
protected synchronized TransactionDefinition getDefinition() {
public synchronized TransactionDefinition getDefinition() {
if (!_DEFINITIONS.containsKey(_mapping)) {
XStream xstream = new XStream(new StaxDriver());
xstream.autodetectAnnotations(true);
Expand All @@ -104,8 +104,6 @@ protected synchronized TransactionDefinition getDefinition() {
}
}

private FileType _type;

static {
_TYPES.put(FileType.ANSI835_4010_X091, _X091_ANSI_VERSION);
_TYPES.put(FileType.ANSI837_4010_X096, _X096_ANSI_VERSION);
Expand Down Expand Up @@ -178,40 +176,9 @@ public X12Reader(FileType type, Reader reader) throws IOException {
else
parse(reader);
}

/**
* Gets an X12 formatted string representing this X12 reader. Will use no line
* breaks after separators.
*
* @return X12 formatted string representing this X12 reader.
*/
public String toX12String() {
_separators.setLineBreak(LineBreak.NONE);
return toX12StringImpl();
}

/**
* Gets an X12 formatted string representing this X12 reader.
*
* @param lineBreak Line break to use for separators.
* @return X12 formatted string representing this X12 reader.
*/
public String toX12String(LineBreak lineBreak) {
_separators.setLineBreak(lineBreak);
return toX12StringImpl();
}

/**
* To HTML string will create an HTML segment from this X12 file.
*
* @return Human readable html segment representation of the X12 file.
*/
public String toHtml() {
StringBuilder builder = new StringBuilder();
for (Loop loop : _dataLoops) {
builder.append(loop.toHtml(_definition.getLoop(), new ArrayList<>()));
}
return builder.toString();
public TransactionDefinition getDefinition() {
return _definition;
}

/**
Expand Down Expand Up @@ -1072,13 +1039,4 @@ private List<Integer> getRequiredCompositePositions(SegmentDefinition seg) {

return requiredPositions;
}

private String toX12StringImpl() {
StringBuilder builder = new StringBuilder();
for (Loop loop : _dataLoops) {
builder.append(loop.toX12String(_definition.getLoop()));
builder.append(_separators.getLineBreak().getLineBreakString());
}
return builder.toString();
}
}
83 changes: 83 additions & 0 deletions src/main/java/com/imsweb/x12/writer/X12Writer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/*
* Copyright (C) 2020 Information Management Services, Inc.
*/
package com.imsweb.x12.writer;

import java.util.ArrayList;
import java.util.List;

import com.imsweb.x12.LineBreak;
import com.imsweb.x12.Loop;
import com.imsweb.x12.Separators;
import com.imsweb.x12.mapping.TransactionDefinition;
import com.imsweb.x12.reader.X12Reader;
import com.imsweb.x12.reader.X12Reader.FileType;

public class X12Writer {

private final List<Loop> _dataLoops;
private final Separators _separators;
private final TransactionDefinition _definition;

public X12Writer(FileType fileType, List<Loop> loops, Separators separators) {
_dataLoops = loops;
_definition = fileType.getDefinition();
_separators = separators;
}

public X12Writer(FileType fileType, List<Loop> loops) {
_dataLoops = loops;
_definition = fileType.getDefinition();
_separators = new Separators();
}

public X12Writer(X12Reader reader) {
_dataLoops = reader.getLoops();
_definition = reader.getDefinition();
_separators = reader.getSeparators();
}


/**
* Gets an X12 formatted string representing this X12 reader. Will use no line
* breaks after separators.
*
* @return X12 formatted string representing this X12 reader.
*/
public String toX12String() {
return toX12String(LineBreak.NONE);
}

/**
* Gets an X12 formatted string representing this X12 reader.
*
* @param lineBreak Line break to use for separators.
* @return X12 formatted string representing this X12 reader.
*/
public String toX12String(LineBreak lineBreak) {
_separators.setLineBreak(lineBreak);
return toX12StringImpl();
}

private String toX12StringImpl() {
StringBuilder builder = new StringBuilder();
for (Loop loop : _dataLoops) {
builder.append(loop.toX12String(_definition.getLoop()));
builder.append(_separators.getLineBreak().getLineBreakString());
}
return builder.toString();
}

/**
* To HTML string will create an HTML segment from this X12 file.
*
* @return Human readable html segment representation of the X12 file.
*/
public String toHtml() {
StringBuilder builder = new StringBuilder();
for (Loop loop : _dataLoops) {
builder.append(loop.toHtml(_definition.getLoop(), new ArrayList<>()));
}
return builder.toString();
}
}
110 changes: 15 additions & 95 deletions src/test/java/com/imsweb/x12/reader/X12ReaderTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,10 @@
import java.nio.charset.StandardCharsets;
import java.util.List;

import org.apache.commons.io.IOUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;
import org.junit.Assert;
import org.junit.Test;

import com.imsweb.x12.Element;
import com.imsweb.x12.LineBreak;
import com.imsweb.x12.Loop;
import com.imsweb.x12.mapping.TransactionDefinition;
import com.imsweb.x12.reader.X12Reader.FileType;
Expand Down Expand Up @@ -52,81 +47,6 @@ public void testConstructors() throws IOException {
assertEquals(fromFileUtf8.getLoops().get(0).toString(), fromReaderUtf8.getLoops().get(0).toString());
}

/**
* Here we will test that you can go from x12, make changes, then serialize the
* x12 once again.
*/
@Test
public void testSerializeBasic() throws IOException {
URL url = this.getClass().getResource("/837_5010/x12_valid.txt");

X12Reader fromFileUtf8 = new X12Reader(FileType.ANSI837_5010_X222, new File(url.getFile()),
StandardCharsets.UTF_8);

String expected = IOUtils
.toString(this.getClass().getResourceAsStream("/837_5010/x12_valid.txt"), StandardCharsets.UTF_8)
.trim();
LineBreak lineBreak;
if (expected.contains(LineBreak.CRLF.getLineBreakString())) {
lineBreak = LineBreak.CRLF;
}
else {
lineBreak = LineBreak.LF;
}
Assert.assertEquals(expected, fromFileUtf8.toX12String(lineBreak).trim());
}

/**
* Tests the toHtml method that
*/
@Test
public void testToHtmlBasic() throws IOException {
URL url = this.getClass().getResource("/837_5010/x12_valid.txt");

X12Reader fromFileUtf8 = new X12Reader(FileType.ANSI837_5010_X222, new File(url.getFile()),
StandardCharsets.UTF_8);

String x12Template = IOUtils.toString(getClass().getResourceAsStream("/html/x12-template.html"), StandardCharsets.UTF_8);

String x12HtmlSegment = fromFileUtf8.toHtml();

String fullX12Html = String.format(x12Template, x12HtmlSegment);

Document doc = Jsoup.parse(fullX12Html);
Elements loops = doc.select(".x12-loop");
Assert.assertEquals(20, loops.size());

Elements segments = doc.select(".x12-segment");
Assert.assertEquals(38, segments.size());

Elements elements = doc.select(".x12-element");
Assert.assertEquals(216, elements.size());
}

/**
* Test a more complex x12 doc and see if we can serialize it.
*/
@Test
public void testSerializeComplex() throws IOException {
URL url = this.getClass().getResource("/837_5010/x12_complex.txt");

X12Reader fromFileUtf8 = new X12Reader(FileType.ANSI837_5010_X222, new File(url.getFile()),
StandardCharsets.UTF_8);

String expected = IOUtils
.toString(this.getClass().getResourceAsStream("/837_5010/x12_complex.txt"), StandardCharsets.UTF_8)
.trim();

LineBreak lineBreak;
if (expected.contains(LineBreak.CRLF.getLineBreakString())) {
lineBreak = LineBreak.CRLF;
}
else {
lineBreak = LineBreak.LF;
}
Assert.assertEquals(expected, fromFileUtf8.toX12String(lineBreak).trim());
}

@Test
public void testMultipleGSLoops() throws Exception {
URL url = this.getClass().getResource("/837_5010/x12_multiple_gs.txt");
Expand Down Expand Up @@ -219,7 +139,7 @@ public void testWithInputStreamConstructor() throws Exception {

validate837Valid(reader.getLoops().get(0));
}

@Test
public void testBadValidCode() throws Exception {
URL url = this.getClass().getResource("/837_5010/x12_bad_valid_code.txt");
Expand Down Expand Up @@ -1017,14 +937,14 @@ public void testComplex() throws Exception {
assertNotNull(loop.getLoop("ST_LOOP", 0).getSegment("ST"));
assertEquals("837", loop.getLoop("ST_LOOP", 0).getSegment("ST").getElementValue("ST01"));
assertEquals("987654", loop.getLoop("ST_LOOP", 0).getSegment("ST").getElementValue("ST02"));
assertNotNull(loop.getLoop("ST_LOOP",0).getSegment("SE"));
assertNotNull(loop.getLoop("ST_LOOP", 0).getSegment("SE"));
assertEquals("25", loop.getLoop("ST_LOOP", 0).getSegment("SE").getElementValue("SE01"));
assertEquals("987654", loop.getLoop("ST_LOOP", 0).getSegment("SE").getElementValue("SE02"));

assertNotNull(loop.getLoop("ST_LOOP", 1).getSegment("ST"));
assertEquals("837", loop.getLoop("ST_LOOP", 1).getSegment("ST").getElementValue("ST01"));
assertEquals("987655", loop.getLoop("ST_LOOP", 1).getSegment("ST").getElementValue("ST02"));
assertNotNull(loop.getLoop("ST_LOOP",1).getSegment("SE"));
assertNotNull(loop.getLoop("ST_LOOP", 1).getSegment("SE"));
assertEquals("26", loop.getLoop("ST_LOOP", 1).getSegment("SE").getElementValue("SE01"));
assertEquals("987655", loop.getLoop("ST_LOOP", 1).getSegment("SE").getElementValue("SE02"));

Expand Down Expand Up @@ -1368,14 +1288,14 @@ public void testX223Repeated2320() throws Exception {
Assert.assertEquals(1, loop.getLoop("2000B").getLoop("2320", 0).findLoop("2330B").size());
Assert.assertEquals(1, loop.getLoop("2000B").getLoop("2320", 1).findLoop("2330A").size());
Assert.assertEquals(1, loop.getLoop("2000B").getLoop("2320", 1).findLoop("2330B").size());
Assert.assertEquals("S", loop.getLoop("2320",0).getSegment(0).getElement("SBR01").getValue());
Assert.assertEquals("T", loop.getLoop("2320",1).getSegment(0).getElement("SBR01").getValue());
Assert.assertEquals("JOHN", loop.getLoop("2320",0).getLoop("2330A").getSegment(0).getElement("NM104").getValue());
Assert.assertEquals("JANE", loop.getLoop("2320",1).getLoop("2330A").getSegment(0).getElement("NM104").getValue());
Assert.assertEquals("AETNA", loop.getLoop("2320",0).getLoop("2330B").getSegment(0).getElement("NM103").getValue());
Assert.assertEquals("ANOTHER NAME", loop.getLoop("2320",1).getLoop("2330B").getSegment(0).getElement("NM103").getValue());
Assert.assertEquals("S", loop.getLoop("2320", 0).getSegment(0).getElement("SBR01").getValue());
Assert.assertEquals("T", loop.getLoop("2320", 1).getSegment(0).getElement("SBR01").getValue());
Assert.assertEquals("JOHN", loop.getLoop("2320", 0).getLoop("2330A").getSegment(0).getElement("NM104").getValue());
Assert.assertEquals("JANE", loop.getLoop("2320", 1).getLoop("2330A").getSegment(0).getElement("NM104").getValue());
Assert.assertEquals("AETNA", loop.getLoop("2320", 0).getLoop("2330B").getSegment(0).getElement("NM103").getValue());
Assert.assertEquals("ANOTHER NAME", loop.getLoop("2320", 1).getLoop("2330B").getSegment(0).getElement("NM103").getValue());
}

@Test
public void test277CAAccepted() throws Exception {
URL url = this.getClass().getResource("/837_5010/x12_277CA_accepted.txt");
Expand Down Expand Up @@ -1404,7 +1324,7 @@ public void test277CAAccepted() throws Exception {
Assert.assertEquals("Should be able to see a approval status code - CSCC", "A2", statusCodeElement.getSubValues().get(0));
Assert.assertEquals("Should be able to see a approval status code - CSC", "20", statusCodeElement.getSubValues().get(1));
}

@Test
public void test277CARejected() throws Exception {
URL url = this.getClass().getResource("/837_5010/x12_277CA_rejected.txt");
Expand All @@ -1426,7 +1346,7 @@ public void test277CARejected() throws Exception {
Assert.assertEquals("Should be able to see a approval status code - CSC", "562", statusCodeElement.getSubValues().get(1));
Assert.assertEquals("Should be able to see a approval status code - EIC", "85", statusCodeElement.getSubValues().get(2));
}

@Test
public void test999Accepted() throws Exception {
URL url = this.getClass().getResource("/837_5010/x12_999_accepted.txt");
Expand All @@ -1437,9 +1357,9 @@ public void test999Accepted() throws Exception {
Loop loop = reader.getLoops().get(0);
assertEquals(1, loop.getLoops().size());
Assert.assertEquals("A", loop.getLoop("GS_LOOP").getLoop("ST_LOOP").getLoop("HEADER").getLoop("2000").getSegment("IK5").getElement("IK501").getValue());

}

@Test
public void test999Rejected() throws Exception {
URL url = this.getClass().getResource("/837_5010/x12_999_rejected.txt");
Expand All @@ -1450,6 +1370,6 @@ public void test999Rejected() throws Exception {
Loop loop = reader.getLoops().get(0);
assertEquals(1, loop.getLoops().size());
Assert.assertEquals("R", loop.getLoop("GS_LOOP").getLoop("ST_LOOP").getLoop("HEADER").getLoop("2000").getSegment("IK5").getElement("IK501").getValue());

}
}
Loading

0 comments on commit 2279931

Please sign in to comment.