Dynamically create IS doc From CSV File In webMethods

This post describe how to create IS doc From CSV File structure at runtime in webMethods. Generated IS doc confirmed to csv column structure. This method comes very handy to when source can send any format file and can’t confirm structure at runtime. Most of the cases CSV file structure at design time is confirmed and designer can create FlatFile schema\dictionary to parse CSV File using WmFlatFile inbuilt services. however if you want to keep your flow service more adaptive and open to any structure then this method can be very useful.

Code written is in java and use opencsv.

IS doc From CSV File

Code given in this post will help you to create an IS doc from CSV File structure. the only requirement for this code to work is that csv file have at least one record at 0th location and work amazingly if those are the name of columns you want to keep for your field names in IS doc type.

This post have two java service. First one just creates IS Doc from CSV file structure and second one has ability to create IS doc and then parse entire record set as well. you are free to modify java code as it please you.

PS – Please download opencsv jar file from opencsv referral link given above and place in your IS package code\jars folder.

generateISDocType

this java service takes path for csv file and name to be give to generated IS doc and spits out IS doc type in output.

below is screen shot for input\output.

IS doc From CSV File
IS doc From CSV File

Java Code


import com.opencsv.CSVReader;
import com.opencsv.CSVWriter;
import java.io.FileReader;
import java.io.IOException;
import java.io.StringWriter;
import java.util.List;
import java.util.ArrayList;

Actual java service code


// pipeline
IDataCursor pipelineCursor = pipeline.getCursor();
String    nameOfGeneratedDoc = IDataUtil.getString( pipelineCursor, "nameOfGeneratedDoc" );
String    csvFilePath = IDataUtil.getString( pipelineCursor, "csvFilePath" );

if(nameOfGeneratedDoc == null || nameOfGeneratedDoc.equals(""))
nameOfGeneratedDoc = "document";
if(csvFilePath == null || csvFilePath.equals(""))
throw new ServiceException("CSV File Path Can't be empty");

try{
CSVReader reader = new CSVReader(new FileReader(csvFilePath));
String[] nextLine = reader.readNext();
// document
IData    document = IDataFactory.create();
IDataCursor documentCursor = document.getCursor();
int i = 0;
while(i < nextLine.length){
IDataUtil.put( documentCursor, nextLine[i], "" );
i++;
}
documentCursor.destroy();
IDataUtil.put( pipelineCursor, nameOfGeneratedDoc, document );
IDataUtil.remove( pipelineCursor, "csvFilePath");
IDataUtil.remove( pipelineCursor, "nameOfGeneratedDoc");
reader.close();
}
catch(Exception e)
{
throw new ServiceException("Error in reading csv " + e);
}
pipelineCursor.destroy();

parseCSV

This service accepts path of csv file, other parse related parameters. screen shot below

IS doc From CSV File
IS doc From CSV File

if skipFirstRecord is set to true, then service assume that first record is name of columns and use them to name fields in IS document. if set to false then file is treated as having only data (no column names).

delimiter is what is used to separate column in file. hence this service supports not only comma separated value but any delimiter.

quoteCharacter by default is double-quoted. you can provide anything here if you have used something else.

use same import statement as for other java service. (these will be automatically present if both java services are created in same folder)

Java Code


// pipeline
IDataCursor pipelineCursor = pipeline.getCursor();
boolean    skipFirstRecord = IDataUtil.getBoolean( pipelineCursor, "skipFirstRecord" );
String    csvFilePath = IDataUtil.getString( pipelineCursor, "csvFilePath" );
String    delimiter = IDataUtil.getString( pipelineCursor, "delimiter" );
String    quoteCharacter = IDataUtil.getString( pipelineCursor, "quoteCharacter" );
int lineNumber =0;
ArrayList parseList = new ArrayList();
String[] columnName = {""};

if(delimiter == null || delimiter.equals(""))
delimiter = ",";
if(quoteCharacter == null || quoteCharacter.equals(""))
quoteCharacter = "\"";

try{
//If skipFirstRecord is true then use first record for column names
if(skipFirstRecord)
{
lineNumber = 1; // to use for second reader
CSVReader reader1 = new CSVReader(new FileReader(csvFilePath));
columnName = reader1.readNext();
reader1.close();
}
CSVReader reader = new CSVReader(new FileReader(csvFilePath), delimiter.charAt(0), quoteCharacter.charAt(0), lineNumber);
String[] nextLine;
while ((nextLine = reader.readNext()) != null)
{
IData parseRecord = IDataFactory.create();
IDataCursor parseRecordCursor = parseRecord.getCursor();
int i = 0;
while(i < nextLine.length)
{
if(skipFirstRecord)
IDataUtil.put( parseRecordCursor, columnName[i], nextLine[i] );
else
IDataUtil.put( parseRecordCursor, "column" + (i+1), nextLine[i] );
i++;
}
parseRecordCursor.destroy();
parseList.add(parseRecord);
}
reader.close();
}
catch(Exception e)
{
System.out.println("Error in reading csv " + e);
}
// document
IData    document = IDataFactory.create();
IDataCursor documentCursor = document.getCursor();
IDataUtil.put( documentCursor, "record", (IData[]) parseList.toArray(new IData[parseList.size()]));
documentCursor.destroy();
IDataUtil.put( pipelineCursor, "document", document );

//remove input
IDataUtil.remove( pipelineCursor, "csvFilePath");
IDataUtil.remove( pipelineCursor, "delimiter");
IDataUtil.remove( pipelineCursor, "quoteCharacter");
IDataUtil.remove( pipelineCursor, "skipFirstRecord");
pipelineCursor.destroy();
parseList.clear();

It is pretty simple and straight forward code. Please feel free to modify or improve this code as it suits you.

Please do leave your feedback comments. It help us greatly to improve our post quality.

 

 

Please follow and like us:

Questions? Comments? Suggestions? Let us know!! Like / Subscribe / Follow for more updates.