package ext.spring.smooks;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.milyn.Smooks;
import org.milyn.container.ExecutionContext;
import org.milyn.payload.StringResult;
import org.milyn.payload.StringSource;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class SmookEDITest {
public static String parseStreamToString(InputStream in) {
StringBuffer sb = new StringBuffer();
if (in != null) {
byte[] b = new byte[128];
int c = -1;
try {
while ((c=in.read(b)) != -1) {
for (int i = 0;i < c;i++) {
sb.append((char)b[i]);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
return sb.toString();
}
public static void testEdi2Smook(String cfgInStr, String orderInStr) {
InputStream cfgIn = null;
InputStream orderIn=null;
try {
cfgIn = new FileInputStream(cfgInStr);
orderIn = new FileInputStream(orderInStr);
String msgIn = SmookEDITest.parseStreamToString(orderIn);
System.out.println(msgIn);
Smooks smooks1 = new Smooks(cfgIn);
/*
* Create a Smook Validator
*/
// SmooksResourceConfiguration pojoConf = new SmooksResourceConfiguration("", Profile.DEFAULT_PROFILE, "");
ExecutionContext executionContext = smooks1.createExecutionContext();
StringResult stringRs = new StringResult();
smooks1.filterSource(executionContext, newStringSource(msgIn), stringRs);
System.out.println(stringRs.getResult());
} catch (Exception e) {
e.printStackTrace();
} finally {
if (cfgIn != null) {
try {
cfgIn.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (orderIn != null) {
try {
orderIn.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
private static XPathExpression EXP_TRANSACTION_TABLE= null;
private static XPathExpression EXP_NODE_DATA_ELEMENT = null;
static {
XPathFactory factory = XPathFactory.newInstance();
XPath xpath = factory.newXPath();
try {
EXP_TRANSACTION_TABLE = xpath.compile("/transactionSet/table");
EXP_NODE_DATA_ELEMENT = xpath.compile("dataElement");
} catch (Exception e) {
e.printStackTrace();
}
}
public Document transDoc(InputStream in) {
Document doc = null;
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
dbf.setIgnoringElementContentWhitespace(true);
try {
DocumentBuilder db = dbf.newDocumentBuilder();
doc = db.parse(in);
} catch (Exception e) {
e.printStackTrace();
}
return doc;
}
public void TranslateOBOE2Smook(String oboeIn) {
File oboeCfgFile = new File(oboeIn);
String tabs="\t";
InputStream in = null;
try {
System.out.println(this.appendix);
in = new FileInputStream(oboeCfgFile);
Document doc = transDoc(in);
NodeList topNodes = (NodeList) EXP_TRANSACTION_TABLE.evaluate(doc, XPathConstants.NODESET);
int topLen = topNodes.getLength();
System.out.println(tabs+"<medi:segmentGroup maxOccurs=\"1\" xmltag=\"" + "TransactionSet" + "\">");
for (int i=0;i<topLen;i++) {
//transactionSet
Node tranNode = topNodes.item(i);
// String tblSecName = tranNode.getAttributes().getNamedItem("section").getNodeValue();
// Smook Group for
// Do loop
NodeList segNodes = tranNode.getChildNodes();
for (int j=0;j<segNodes.getLength();j++) {
doLoop(segNodes.item(j),tabs+"\t", false, false);
}
}
System.out.println(tabs+"</medi:segmentGroup>");
System.out.println(this.suffix);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public static String mapAttrOboe2Smook(Node node, String oboeAttr, String smookAttr) {
StringBuffer preSb = new StringBuffer();
Node segCodeAttr = node.getAttributes().getNamedItem(oboeAttr);
if (segCodeAttr != null) {
preSb.append(" " + smookAttr + "=\"").append(segCodeAttr.getNodeValue()).append("\"");
}
return preSb.toString();
}
public static void doLoop(Node node, String tabs, booleanisTop, boolean isPreLoop) {
String nodeName = node.getNodeName();
if ("segment".equals(nodeName)) {
String occurs = node.getAttributes().getNamedItem("occurs").getNodeValue();
String segGroupOrSeg = "";
StringBuffer preSb = new StringBuffer();
String required = node.getAttributes().getNamedItem("required").getNodeValue();
String toDup = "";
if("M".equals(required)) {
preSb.append(" minOccurs=\"1\"");
toDup = " minOccurs=\"1\"";
} else if ("O".equals(required)) {
preSb.append(" minOccurs=\"0\"");
toDup = " minOccurs=\"0\"";
} else {
System.out.println(required+"<!------------------------------------------------------------------------>");
}
if (isPreLoop) {
segGroupOrSeg = "segment";
preSb.append(mapAttrOboe2Smook(node, "id", "segcode")).append(mapAttrOboe2Smook(node, "xmlTag", "xmltag"));
preSb.append(" truncatable=\"true\"");
} else {
if (!(occurs == null || "".equals(occurs))) {
if ("1".equals(occurs)) {
segGroupOrSeg = "segment";
preSb.append(mapAttrOboe2Smook(node, "id", "segcode")).append(mapAttrOboe2Smook(node, "xmlTag", "xmltag"));
preSb.append(" truncatable=\"true\"");
} else {
segGroupOrSeg = "segmentGroup";
preSb.append(mapAttrOboe2Smook(node, "xmlTag", "xmltag")).append(mapAttrOboe2Smook(node, "occurs", "maxOccurs"));
}
} else {
segGroupOrSeg = "segment";
preSb.append(mapAttrOboe2Smook(node, "id", "segcode")).append(mapAttrOboe2Smook(node, "xmlTag", "xmltag"));
preSb.append(" truncatable=\"true\"");
}
}
System.out.println(tabs+"<medi:" + segGroupOrSeg + preSb.toString() + ">");
NodeList dataEleNodes;
try {
dataEleNodes = (NodeList) EXP_NODE_DATA_ELEMENT.evaluate(node, XPathConstants.NODESET);
if (!(dataEleNodes == null || dataEleNodes.getLength() < 1)) {
if ("segmentGroup".equals(segGroupOrSeg)) {
String tt = tabs+"<medi:segment " + mapAttrOboe2Smook(node, "xmlTag", "xmltag") + mapAttrOboe2Smook(node, "id", "segcode") + toDup + " truncatable=\"true\"" + ">";
System.out.println(tt);
}
for (int i=0;i<dataEleNodes.getLength();i++) {
// process data elements
Node dataEleNode = dataEleNodes.item(i);
if ("dataElement".equals(dataEleNode.getNodeName())) {
System.out.println(tabs+"\t<medi:field xmltag=\"" + dataEleNode.getAttributes().getNamedItem("xmlTag").getNodeValue() + "\"/>");
}
}
if ("segmentGroup".equals(segGroupOrSeg)) {
System.out.println(tabs+"</medi:segment>");
}
}
} catch (XPathExpressionException e) {
e.printStackTrace();
}
System.out.println(tabs+"</medi:" + segGroupOrSeg + ">");
} else if ("loop".equals(nodeName)) {
String occurs = node.getAttributes().getNamedItem("occurs").getNodeValue();
String xmltag = node.getAttributes().getNamedItem("xmlTag").getNodeValue();
String required = node.getAttributes().getNamedItem("required").getNodeValue();
String toDup = "";
if("M".equals(required)) {
toDup = " minOccurs=\"1\"";
} else if ("O".equals(required)) {
toDup = " minOccurs=\"0\"";
} else {
System.out.println(required+"<!------------------------------------------------------------------------>");
}
boolean isLoop = false;
String tt ="";
if (isTop) {
} else {
tt = tabs+"<medi:segmentGroup xmltag=\"" + xmltag + "\" maxOccurs=\"" + occurs + "\""+ toDup + ">";
isLoop=true;
//tt = tabs+"<medi:segment" + mapAttrOboe2Smook(node, "xmlTag", "xmltag") + mapAttrOboe2Smook(node, "id", "segcode") + " truncatable=\"true\"" + " maxOccurs=\"" + occurs + "\""+ toDup + ">";
}
System.out.println(tt);
NodeList childNodes = node.getChildNodes();
for(int i=0;i<childNodes.getLength();i++) {
doLoop(childNodes.item(i),tabs+"\t", false, isLoop);
}
if (isTop) {
} else {
//System.out.println(tabs+"</medi:segment>");
System.out.println(tabs+"</medi:segmentGroup>");
}
} else if ("compositeDE".equals(nodeName)) {
String occurs = node.getAttributes().getNamedItem("occurs").getNodeValue();
String xmltag = node.getAttributes().getNamedItem("xmlTag").getNodeValue();
String required = node.getAttributes().getNamedItem("required").getNodeValue();
Integer minLength = Integer.valueOf(node.getAttributes().getNamedItem("minLength").getNodeValue());
Integer maxLength = Integer.valueOf(node.getAttributes().getNamedItem("maxLength").getNodeValue());
boolean isRequired = false;
if("M".equals(required)) {
isRequired = true;
} else if ("O".equals(required)) {
isRequired = false;
}
if (isPreLoop) {
System.out.println(tabs + "<medi:field xmltag=\"" + xmltag + "\" required=\"" + isRequired + "\" minLength=\"" + minLength + "\" maxLength=\"" + maxLength + "\"/>");
} else {
System.out.println(tabs+"<medi:component xmltag=\"" + xmltag+ "\" required=\"" + isRequired + "\" minLength=\"" + minLength + "\" maxLength=\"" + maxLength + "\">");
NodeList childNodes = node.getChildNodes();
for(int i=0;i<childNodes.getLength();i++) {
doLoop(childNodes.item(i),tabs+"\t", false, true);
}
}
System.out.println("</medi:component>");
} else {
// do nothing
}
}
private String appendix="";
private String suffix="";
public void readAppendix(String fileloc) {
InputStream in = null;
try {
in = new FileInputStream(fileloc);
this.appendix = parseStreamToString(in);
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public void readSuffix(String fileloc) {
InputStream in = null;
try {
in = new FileInputStream(fileloc);
this.suffix = parseStreamToString(in);
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public static int findChar(int c, String pattern, int step) {
int strLen = pattern.length();
++step;
if (step < strLen) {
if (pattern.charAt(step) == c) {
} else {
step = -1;
}
}
return step;
}
public static void tryToFindUnknown(String strSource, String defination, String pattern) {
Map<String, Boolean> segments = checkUnknownSegmentsPattern(strSource, pattern);
for (String keyPattern : segments.keySet()) {
System.out.println("Key:\t" + keyPattern + "\t\t\t ?Exists:\t" + findAsPattern(defination, "\"" + keyPattern + "\""));
}
}
public static Map<String, Boolean> checkUnknownSegmentsPattern(String strSource, String pattern) {
// search segments in ediFile
Map<String, Boolean> result = new HashMap<String, Boolean>();
FileReader reader = null;
BufferedReader br = null;
try {
reader = new FileReader(strSource);
br = new BufferedReader(reader);
Pattern p = Pattern.compile(pattern);
int c = -1;
StringBuffer sb = new StringBuffer();
while ((c = br.read()) != -1) {
sb.append((char) c);
}
Matcher m = p.matcher(sb.toString());
while (m.find()) {
result.put(m.group().substring(1, m.group().length()-1), false);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return result;
}
public static boolean findAsPattern(String strSource, String pattern) {
// search segments in ediFile
FileReader reader = null;
BufferedReader br = null;
boolean rs =false;
try {
reader = new FileReader(strSource);
br = new BufferedReader(reader);
int c = -1;
int step = -1;
int count = 0;
int pos = -1;
StringBuffer sb = new StringBuffer();
while ((c = br.read()) != -1) {
pos++;
count++;
sb.append((char) c);
step = findChar(c, pattern, step);
if (step == pattern.length()-1) {
step = -1;
String ss =sb.toString().substring(1);
pos-=ss.length();
br.mark(pos);
count = 0;
sb = new StringBuffer();
rs = true;
break;
} else if (step == -1 ) {
if( count > 1) {
String ss =sb.toString().substring(1);
pos-=ss.length();
br.mark(pos);
count = 0;
} else if (count == 1) {
}
sb = new StringBuffer();
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return rs;
}
public static void main(String[] args) {
String regex = "~...?\\*";
Pattern p =Pattern.compile(regex);
String str = "ISA*00* *00* *ZZ*DHIWAL *....IEA*1*000000000~";
Matcher m = p.matcher(str);
while(m.find()) {
System.out.println(m.group());
}
String ediPath = SmookEDITest.class.getResource("order.edi").getPath();
String defPath = SmookEDITest.class.getResource("edi-mapping-856-test.xml").getPath();
tryToFindUnknown(ediPath, defPath, regex);
SmookEDITest t = new SmookEDITest();
t.readAppendix(SmookEDITest.class.getResource("appendix").getPath());
t.readSuffix(SmookEDITest.class.getResource("suffix").getPath());
t.TranslateOBOE2Smook(SmookEDITest.class.getResource("856.xml").getPath());
testEdi2Smook(SmookEDITest.class.getResource("edi-smook-config.xml").getPath(), SmookEDITest.class.getResource("oboe_order.edi").getPath());
}
}