John Douglass created CAMEL-7142:
------------------------------------

             Summary: CsvDataFormat unmarshal overwrites delimiter in static 
CSVStrategy strategies
                 Key: CAMEL-7142
                 URL: https://issues.apache.org/jira/browse/CAMEL-7142
             Project: Camel
          Issue Type: Bug
          Components: camel-csv
    Affects Versions: 2.12.2
            Reporter: John Douglass
            Priority: Minor


The unmarshal function in CsvDataFormat contains the following line:

{code}
strategy.setDelimiter(config.getDelimiter());
{code}

This can cause problems when multiple CsvDataFormats are used which rely on the 
default CSVStrategy or one of the other static CSVStrategy objects.

Here is sample code to demonstrate the problem:
 
{code}
final CsvDataFormat csv = new CsvDataFormat();
final CsvDataFormat tsv = new CsvDataFormat();
tsv.setDelimiter("\t");

context.addRoutes(new RouteBuilder() {
    @Override
    public void configure() throws Exception {
        from("file:///tmp/?include=.*.csv")
                .unmarshal(csv)
                .process(new MyProcessor());
        from("file:///tmp/?include=.*.tsv")
                .unmarshal(tsv)
                .process(new MyProcessor());
    }
});
{code}

Running the code above with several files with 2 lines, 9 columns per line and 
comma or tab delimiters returns the following (the exact values may be 
different from run to run):

{code}
File: 0.tsv, lines: 2
  Line 1 columns: 9
  Line 2 columns: 9
File: 0.csv, lines: 2
  Line 1 columns: 1
  Line 2 columns: 1
File: 1.csv, lines: 2
  Line 1 columns: 2
  Line 2 columns: 1
File: 1.tsv, lines: 2
  Line 1 columns: 9
  Line 2 columns: 9
{code}

These should all show 9 columns.

Adding the following lines corrects the problem, because each DataFormat has 
its own CSVStrategy:

{code}
csv.setStrategy(new CSVStrategy(',', '"', '#'));
tsv.setStrategy(new CSVStrategy('\t', '"', '#'));
{code}

The suggested fix would be for the CsvDataFormat to have its own copy of its 
CSVStrategy instead of using what amounts to a pointer to another CSVStrategy. 
Perhaps setStrategy should be changed to do that. This is tedious because 
CSVStrategy has no copy constructor and has many properties, but would be a 
defensive way to do it.

Note also that the example at http://camel.apache.org/csv.html under 
"Unmarshalling with a pipe as delimiter" actually alters the 
CSVStrategy.DEFAULT_STRATEGY, so any subsequent CsvDataFormat objects created 
would have a pipe as the delimiter.




--
This message was sent by Atlassian JIRA
(v6.1.5#6160)

Reply via email to