danw
danw

Reputation: 1648

Mule - how to pad rows in a CSV file with extra delimiters

I have a CSV file coming into my Mule application that looks as follows:

1,Item,Item,Item
2,Field,Field,Field,Field
2,Field,Field,Field,Field
3,Text

Is there a way I can transform this file in Mule to something like the below:

1,Item,Item,Item,,,,,,
2,Field,Field,Field,Field,,,,,
2,Field,Field,Field,Field,,,,,
3,Text,,,,,,,,

Essentially, what I need to do here is append a string (containing x occurrences of a delimiter) to the end of each row. The number of delimiters I need to append to each row can be determined by the first character of that row e.g. if row[0]='1' then (append ",,,,,,") else if row[0]='2' then (append ",,,,,"etc.

The reason I have this rather annoying problem is because the system providing the input to my Mule application produces a file where the number of columns in each row may vary. I'm trying to pad this file so that the number of columns in each row is equal, so that I can pass it on to a Java transformer like the one explained here that is using FlatPack (which expects x columns, it won't accept a file that has a varying number of columns in each row).

Does anyone have any ideas on how I could approach this? Thanks in advance.

UPDATE

Based on @Learner's recommendation and @EdC's answer - I've achieved this in Mule using the below:

<flow name="testFlow1" doc:name="testFlow1">
    <file:inbound-endpoint .../>
    <file:file-to-string-transformer doc:name="File to String"/>
    <component doc:name="Java" class="package.etc.etc.MalformData"/>
</flow>

Upvotes: 0

Views: 900

Answers (2)

EdC
EdC

Reputation: 194

Try this based on @Learner 's answer.

import org.mule.api.MuleEventContext;
import org.mule.api.MuleMessage;

public class MalformData implements org.mule.api.lifecycle.Callable {
  private String[] strTempArray;

  public String findMalformRow(String strInput) {
    String strOutput = "";
    String strFix = "";
    int intArrayLength = 0;
    char charFirst = ' ';
    String strControl = "";
    strTempArray = strInput.split("\\n");
    intArrayLength = strTempArray.length;
    for (int i = 0; i < intArrayLength; i++) {
        charFirst = strTempArray[i].charAt(0);
        strFix = strTempArray[i];
        String missingDelimiter = "";

        if (charFirst == '1') {
            missingDelimiter = ",,,,,,";
            strFix += missingDelimiter;
        } else if (charFirst == '2') {
            missingDelimiter = ",,,,,";
            strFix += missingDelimiter;
        } else if (charFirst == '3') {
            missingDelimiter = ",,,,,,,,";
            strFix += missingDelimiter;
        } else {
            strFix = "Good";
        }

        if (strControl != "Good") {
            strTempArray[i] = strFix;
        } else {
            charFirst = ' ';
            strFix = "";
        }
    }

    for(int i=0; i < intArrayLength; i++){
        strOutput += strTempArray[i] + "\n";
    }

    return strOutput;
}

@Override
  public Object onCall(MuleEventContext eventContext) throws Exception {
    MuleMessage message = eventContext.getMessage();
    String newPayload = this.findMalformRow(message.getPayloadAsString());
    message.setPayload(newPayload);
    return message;
  }
}

Upvotes: 2

Charu Khurana
Charu Khurana

Reputation: 4551

You could write a custom java component that reads your CSV file line by line, write to another file and add , based on your logic at the end of each line

Upvotes: 1

Related Questions