You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@camel.apache.org by "Babak Vahdat (JIRA)" <ji...@apache.org> on 2014/01/18 12:45:20 UTC

[jira] [Commented] (CAMEL-7142) CsvDataFormat unmarshal overwrites delimiter in static CSVStrategy strategies

    [ https://issues.apache.org/jira/browse/CAMEL-7142?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13875633#comment-13875633 ] 

Babak Vahdat commented on CAMEL-7142:
-------------------------------------

Luckily {{CSVStrategy}} has widen the visibility of {{Object#clone()}} method from {{protected}} to {{public}}, so that we can easily make a safe copy of a given {{CSVStrategy}} object when necessary.

> 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
>            Assignee: Babak Vahdat
>            Priority: Minor
>              Labels: easyfix
>   Original Estimate: 1h
>  Remaining Estimate: 1h
>
> 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)