1 package org.opensync.engine.server.adapter;
2
3 /***
4 * Title: OpenSync
5 * Description: This class implements a part of the translation of the EDI X12
6 * message 840 to XML.
7 * The X12 EDI standard is the US standard for Edi.
8 * An XML/EDI group has been formed to propose an XML DTD.
9 * For more information, see http://www.xmledi-group.org
10 * and http://www.eidx.org/publications/business_models
11 * Description of the 840 message:
12 * http://www.eidx.org/publications/guidelines/arq4010.pdf
13 */
14
15 import java.io.BufferedReader;
16 import java.io.File;
17 import java.io.FileNotFoundException;
18 import java.io.FileReader;
19 import java.io.IOException;
20 import java.io.Reader;
21 import java.io.StreamTokenizer;
22 import java.io.StringReader;
23 import java.io.StringWriter;
24 import java.util.Vector;
25
26 import javax.xml.parsers.ParserConfigurationException;
27 import javax.xml.parsers.SAXParser;
28 import javax.xml.parsers.SAXParserFactory;
29
30 import org.opensync.engine.util.FileHelper;
31 import org.xml.sax.SAXException;
32
33 class EdiAttributes {
34
35 /****/
36 public String code;
37 /****/
38 public String name;
39 /****/
40 public boolean descriptor;
41
42 /***
43 * @param code
44 * @param name
45 * @param descriptor
46 */
47 public EdiAttributes(String code, String name, boolean descriptor) {
48 this.code = code;
49 this.name = name;
50 this.descriptor = descriptor;
51 }
52 };
53
54 /***
55 * @author xwarzee
56 */
57 public class EdiX128402Xml extends Translator {
58
59 private DescriptorParser descriptorParser;
60 private int tok = -1;
61 private Vector header_elementNames = new Vector(16);
62 private Vector functional_elementNames = new Vector(8);
63 private Vector headingArea_elementNames = new Vector(2);
64 private Vector trailer_elementNames;
65
66 /***/
67 /****/
68 public EdiX128402Xml() {
69
70 header_elementNames.add(new EdiAttributes("I01", "Authorization Information Qualifier", true));
71 header_elementNames.add(new EdiAttributes("I02", "Authorization Information", false));
72 header_elementNames.add(new EdiAttributes("I03", "Security Inform Qualifier", true));
73 header_elementNames.add(new EdiAttributes("I04", "Security Information", false));
74 header_elementNames.add(new EdiAttributes("I05", "Interchange ID Qualifier", true));
75 header_elementNames.add(new EdiAttributes("I06", "Interchange Sender ID", false));
76 header_elementNames.add(new EdiAttributes("I05", "Interchange ID Qualifier", true));
77 header_elementNames.add(new EdiAttributes("I07", "Interchange Receiver ID", false));
78 header_elementNames.add(new EdiAttributes("I08", "Interchange Date", false));
79 header_elementNames.add(new EdiAttributes("I09", "Interchange Time", false));
80 header_elementNames.add(new EdiAttributes("I10", "Interchange Control Standards", true));
81 header_elementNames.add(new EdiAttributes("I11", "Interchange Control Version", false));
82 header_elementNames.add(new EdiAttributes("I12", "Interchange Control Number", false));
83 header_elementNames.add(new EdiAttributes("I13", "Acknowledgment Requested", true));
84 header_elementNames.add(new EdiAttributes("I14", "Test Indicator", true));
85 header_elementNames.add(new EdiAttributes("I15", "Subelement Separator", false));
86
87 functional_elementNames.add(new EdiAttributes("479", "Functional Identifier Code", true));
88 functional_elementNames.add(new EdiAttributes("142", "Application Senders Code", false));
89 functional_elementNames.add(new EdiAttributes("124", "Application Receivers Code", true));
90 functional_elementNames.add(new EdiAttributes("373", "Date", false));
91 functional_elementNames.add(new EdiAttributes("337", "Time", false));
92 functional_elementNames.add(new EdiAttributes("I12", "Group Control", false));
93 functional_elementNames.add(new EdiAttributes("455", "Responsability Agency Code", true));
94 functional_elementNames.add(new EdiAttributes("480", "Version Release Industry", false));
95
96 headingArea_elementNames.add(new EdiAttributes("143", "Transaction Set Identifier Code", true));
97 headingArea_elementNames.add(new EdiAttributes("329", "Transaction Set Control Number", false));
98 headingArea_elementNames.add(new EdiAttributes("353", "Transaction Set Purpose Code", true));
99 headingArea_elementNames.add(new EdiAttributes("586", "Request for Quote Reference Number", false));
100 headingArea_elementNames.add(new EdiAttributes("373", "Date", false));
101 headingArea_elementNames.add(new EdiAttributes("374", "Date/Time Qualifier", true));
102 headingArea_elementNames.add(new EdiAttributes("373", "Date", false));
103 }
104
105 /***
106 * @param descriptorFileName
107 * @exception IOException
108 * @exception FileNotFoundException
109 * @exception SAXException
110 * @exception ParserConfigurationException
111 */
112 public void readDescriptor(String descriptorFileName)
113 throws ParserConfigurationException, SAXException,FileNotFoundException,IOException {
114 descriptorParser = new DescriptorParser(this);
115
116 SAXParserFactory factory = SAXParserFactory.newInstance();
117 factory.setValidating(true);
118 SAXParser parser = factory.newSAXParser();
119 parser.parse( new File(descriptorFileName).toURL().toExternalForm(),
120 descriptorParser);
121 }
122
123 private boolean buildHeader(StreamTokenizer st, StringWriter fw) throws IOException {
124 boolean tokenWasDelimiter = false;
125
126 if (!st.sval.equals("ISA")) return false;
127
128
129
130 int i = 1;
131 String descriptor = "";
132 while (st.ttype != StreamTokenizer.TT_EOF && i < 16)
133 {
134
135 while (st.ttype != StreamTokenizer.TT_EOL &&
136 st.ttype != StreamTokenizer.TT_EOF)
137 {
138 if (st.ttype != StreamTokenizer.TT_EOL &&
139 st.ttype != StreamTokenizer.TT_EOF)
140 {
141 if (tok == StreamTokenizer.TT_WORD && st.sval != null) {
142 if (st.sval.equals("ISA")) {
143 fw.write("<segment code=\"ISA\" name=\"Interchange Control Header\">");
144 } else {
145 fw.write("<element code=\"" + ((EdiAttributes)header_elementNames.get(i-1)).code + "\" name=\""
146 +((EdiAttributes)header_elementNames.get(i-1)).name + "\">");
147
148 if (((EdiAttributes)header_elementNames.get(i-1)).descriptor)
149 descriptor="descriptor=\"" + st.sval + "\"";
150 else
151 descriptor="";
152 if (!st.sval.trim().equals("")) {
153 if (st.sval.trim().equals("<"))
154 fw.write(" <value><</value>");
155 else
156 fw.write(" <value " + descriptor + ">" + st.sval + "</value>");
157 }
158 else
159 fw.write("<value/>");
160 fw.write("</element>");
161 i++;
162 }
163
164 tokenWasDelimiter = false;
165 }
166 else if (tok == '*' && tokenWasDelimiter) {
167 fw.write(" ");
168 } else if (tok == '*')
169 tokenWasDelimiter = true;
170 }
171 tok = st.nextToken();
172 }
173 tok = st.nextToken();
174 }
175 fw.write("</segment>");
176
177
178
179 return true;
180 }
181
182 private boolean buildFunctionalGroup(StreamTokenizer st, StringWriter fw) throws IOException {
183
184 boolean tokenWasDelimiter = false;
185 boolean status = false;
186
187
188
189 if (!st.sval.equals("GS")) return false;
190
191 int i = 1;
192 String descriptor = "";
193 while (st.ttype != StreamTokenizer.TT_EOF && i < 8)
194 {
195
196 while (st.ttype != StreamTokenizer.TT_EOL &&
197 st.ttype != StreamTokenizer.TT_EOF)
198 {
199 if (st.ttype != StreamTokenizer.TT_EOL &&
200 st.ttype != StreamTokenizer.TT_EOF)
201 {
202 if (tok == StreamTokenizer.TT_WORD && st.sval != null) {
203 if (st.sval.equals("GS")) {
204 fw.write("<functionalgroup>");
205 fw.write("<segment code=\"GS\" name=\"Functional Group Header\">");
206 } else {
207 fw.write("<element code=\"" + ((EdiAttributes)functional_elementNames.get(i-1)).code + "\" name=\""
208 +((EdiAttributes)functional_elementNames.get(i-1)).name + "\">");
209
210 if (((EdiAttributes)functional_elementNames.get(i-1)).descriptor)
211 descriptor="descriptor=\"" + st.sval + "\"";
212 else
213 descriptor="";
214 if (!st.sval.trim().equals("")) {
215 if (st.sval.trim().equals("<"))
216 fw.write(" <value><</value>");
217 else
218 fw.write(" <value " + descriptor + ">" + st.sval + "</value>");
219 }
220 else
221 fw.write("<value/>");
222 fw.write("</element>");
223 i++;
224 }
225
226 tokenWasDelimiter = false;
227 }
228 else if (tok == '*' && tokenWasDelimiter) {
229 fw.write(" ");
230 } else if (tok == '*')
231 tokenWasDelimiter = true;
232 }
233 tok = st.nextToken();
234 }
235 tok = st.nextToken();
236 }
237 fw.write("</segment>");
238 status = buildTransaction(st, fw);
239 fw.write("</functionalgroup>");
240
241
242 return status;
243 }
244
245 private boolean buildHeadingArea(StreamTokenizer st, StringWriter fw) throws IOException {
246
247 boolean tokenWasDelimiter = false;
248
249 if (!st.sval.equals("ST")) return false;
250
251
252
253 int i = 1;
254 String descriptor = "";
255 while (st.ttype != StreamTokenizer.TT_EOF && i < 8 && !st.sval.equals("PO1"))
256 {
257
258 while (st.ttype != StreamTokenizer.TT_EOL &&
259 st.ttype != StreamTokenizer.TT_EOF)
260 {
261 if (st.ttype != StreamTokenizer.TT_EOL &&
262 st.ttype != StreamTokenizer.TT_EOF)
263 {
264 if (tok == StreamTokenizer.TT_WORD && st.sval != null) {
265 if (st.sval.equals("ST")) {
266 fw.write("<table section=\"header\">");
267 fw.write("<segment code=\"" +st.sval+ "\" name=\"Transaction Set Header\">");
268 } else if (st.sval.equals("BQT")) {
269 fw.write("</segment>");
270 fw.write("<segment code=\"" +st.sval+ "\" name=\"Beginning Segment for Request for Quotation\">");
271 } else {
272 fw.write("<element code=\"" + ((EdiAttributes)headingArea_elementNames.get(i-1)).code + "\" name=\""
273 +((EdiAttributes)headingArea_elementNames.get(i-1)).name + "\">");
274
275 if (((EdiAttributes)headingArea_elementNames.get(i-1)).descriptor)
276 descriptor="descriptor=\"" + st.sval + "\"";
277 else
278 descriptor="";
279 if (!st.sval.trim().equals("")) {
280 if (st.sval.trim().equals("<"))
281 fw.write(" <value><</value>");
282 else
283 fw.write(" <value " + descriptor + ">" + st.sval + "</value>");
284 }
285 else
286 fw.write("<value/>");
287 fw.write("</element>");
288 i++;
289 }
290
291 tokenWasDelimiter = false;
292 }
293 else if (tok == '*' && tokenWasDelimiter) {
294 fw.write(" ");
295 } else if (tok == '*')
296 tokenWasDelimiter = true;
297 }
298 tok = st.nextToken();
299 }
300 tok = st.nextToken();
301 }
302 fw.write("</segment>");
303 fw.write("</table>");
304
305
306 return true;
307 }
308
309 private boolean buildItems(StreamTokenizer st, StringWriter fw) throws IOException {
310
311
312
313
314 return true;
315 }
316 private boolean buildSummaryArea(StreamTokenizer st, StringWriter fw) throws IOException {
317
318
319
320
321 return true;
322 }
323
324 private boolean buildTransaction(StreamTokenizer st, StringWriter fw) throws IOException {
325
326 boolean status = false;
327
328
329
330 if (st.sval.equals("ST")) {
331 fw.write("<transactionset code=\"840\" name=\"Request for Quotation\">");
332 status = buildHeadingArea(st, fw);
333 if (status) status = buildItems(st, fw);
334 if (status) status = buildSummaryArea(st, fw);
335 fw.write("</transactionset>");
336 } else
337 status=false;
338
339 return status;
340 }
341
342 private boolean buildTrailer(StreamTokenizer st, StringWriter fw) {
343
344
345
346
347 return true;
348 }
349
350 /***
351 * @param input
352 * @exception IOException
353 */
354 public String parse(Reader input)
355 throws java.io.IOException
356
357 {
358 BufferedReader br = new BufferedReader(input);
359
360 if (skipfirstlines > 0) {
361 int linesToSkip = skipfirstlines;
362 while (linesToSkip > 0) {
363 br.readLine();
364 linesToSkip--;
365 }
366 }
367 StreamTokenizer st = new StreamTokenizer(br);
368 st.resetSyntax();
369 st.wordChars('0', '9');
370 st.wordChars('a', 'z');
371 st.wordChars('A', 'Z');
372 st.wordChars(128 + 32, 255);
373 st.wordChars('!','@');
374 st.wordChars(' ', ' ');
375
376
377 if (!suppressquotes) {
378
379 st.wordChars('"', '"');
380 st.wordChars('\'', '\'');
381 } else {
382
383
384 st.quoteChar('"');
385 st.quoteChar('\'');
386 }
387
388
389
390
391
392
393
394
395 st.eolIsSignificant(true);
396
397
398
399
400
401
402
403 st.ordinaryChar('*');
404
405 StringWriter fw = new StringWriter();
406
407
408 fw.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
409 fw.write("<!DOCTYPE envelope SYSTEM \"edi_X12_envelope.dtd\">");
410 fw.write("<envelope format=\"X12\">\n");
411
412 tok = st.nextToken();
413
414 buildHeader(st, fw);
415 buildFunctionalGroup(st, fw);
416 buildTrailer(st,fw);
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449 fw.write("</envelope>\n");
450 fw.flush();
451 fw.close();
452 return fw.toString();
453 }
454
455 /***
456 * @param txt
457 * @exception SAXException
458 * @exception IOException
459 * @exception ParserConfigurationException
460 */
461 public String parseTxt(String txt)
462 throws java.io.IOException, SAXException, ParserConfigurationException
463 {
464 StringReader input = new StringReader(txt);
465 return parse(input);
466
467 }
468
469 /***
470 * @param argv
471 * @exception SAXException
472 * @exception IOException
473 * @exception ParserConfigurationException
474 */
475 public static void main(String argv[])
476 throws java.io.IOException, SAXException, ParserConfigurationException
477 {
478
479 String fileSeparator = System.getProperty("file.separator");
480 String configFolder = System.getProperty("opensync.configfolder");
481 configFolder = (configFolder == null ? "" : configFolder);
482
483 String fullDescriptorFileName = System.getProperty("opensync.home") +
484 fileSeparator+ "etc"+fileSeparator+configFolder+fileSeparator+"descript"+fileSeparator +
485 argv[0];
486
487 FileReader input = null;
488
489 if (argv.length == 3)
490 {
491 EdiX128402Xml cp = new EdiX128402Xml();
492 try {
493 cp.readDescriptor(fullDescriptorFileName);
494 } catch (Exception e) {
495 System.err.println("Exception caught: " + e.getMessage());
496 }
497
498 try {
499 input = new FileReader(argv[1]);
500 cp.saveString(argv[2], cp.parse(input));
501 }
502 catch (IOException e) {
503 System.err.println("Exception caught: " + e.getMessage());
504 }
505 finally {
506 if (input != null) {
507 input.close();
508 input = null;
509 }
510 }
511 } else {
512 System.out.println("\nUsage: java EdiX128402Xml configFile.xml csv-file xml-file");
513 System.out.println(" where csv-file is the comma-separated file, and ");
514 System.out.println(" xml-file is the XML file to be generated.");
515 }
516 }
517
518 /***
519 * @param filename
520 * @param string
521 * @exception IOException
522 */
523 public void saveString(String filename, String string) throws IOException {
524 FileHelper.stringToFile(string,filename);
525 }
526 }