Sanjay007 / jcsv

Automatically exported from code.google.com/p/jcsv
0 stars 0 forks source link

Exception when handling null field in the object #5

Open GoogleCodeExporter opened 8 years ago

GoogleCodeExporter commented 8 years ago
What steps will reproduce the problem?
1. Try to generate a CSV list with 3 fields-(field1, field2, field3) with a 
empty filed, for example "3,null,1"
2. Then the code will throw a NullPointerException

This is because there is a bug  when library dealing with null fields in the 
object, it throws a NullPointerException because in the highlighted areas 
below, it should check if data[i] is null or not first, before it jumps the gun 
trying to access it's content via contains...

A easy fix see below: check if data[i] is null or not first, before it jumps 
the gun trying to access it's content via contains.

public class CSVColumnJoinerImpl implements CSVColumnJoiner {

    @Override
    public String joinColumns(String[] data, CSVStrategy strategy) {
        final String delimiter = String.valueOf(strategy.getDelimiter());
        final String quote = String.valueOf(strategy.getQuoteCharacter());
        final String doubleQuote = quote + quote;

        // check each column for delimiter or quote characters
        // and escape them if neccessary
        for (int i = 0; i < data.length; i++) {
            if (data[i].contains(delimiter) || data[i].contains(quote)) {
                if (data[i].contains(quote)) {
                    data[i] = data[i].replaceAll(Pattern.quote(quote), doubleQuote);
                }

                data[i] = quote + data[i] + quote;
            }
        }

        return CSVUtil.implode(data, delimiter);
    }

}

What is the expected output? What do you see instead?
A CSV with empty for null field.
Exception.

What version of the product are you using? On what operating system?
Version: 1.4.0
OS: windows

Please provide any additional information below.

Original issue reported on code.google.com by i.albert...@gmail.com on 20 Mar 2013 at 12:15

GoogleCodeExporter commented 8 years ago
I am using the AnnotationsImplememtation  to parse the CSV and populate the 
objects. How to handle the null values of CSV ?

My code is like :

public static List<ExistingCustomer> readCSV(File exictingCustomerCsv)
            throws Exception {
        Reader csvFile = new FileReader(exictingCustomerCsv);
        List<ExistingCustomer> existingCustomerList = null;
        ValueProcessorProvider vpp = registerProcessor();

    CSVReader<ExistingCustomer> existingCustomerReader = new CSVReaderBuilder<ExistingCustomer>(csvFile).strategy(CSVStrategy.UK_DEFAULT).entryParser(
                    new AnnotationEntryParser<ExistingCustomer>(ExistingCustomer.class, vpp)).build();

        try {
            existingCustomerList = existingCustomerReader.readAll();
             printObjectValues(existingCustomerList);
        } catch (Exception ex) {
            System.out.println("Exception" + ex);
            Log.debug("Exception in readCSV" + ex);
        }
        return existingCustomerList;
    }

private static ValueProcessorProvider registerProcessor() {
        ValueProcessorProvider vpp = new ValueProcessorProvider();
        vpp.registerValueProcessor(List.class, new ListValueProcessor());
        vpp.registerValueProcessor(Date.class, new DateValueProcessor(
                new SimpleDateFormat("dd/MM/yyyy")));
        vpp.registerValueProcessor(Double.class,new DoubleValueProcessor(new DoubleProcessor()));
        return vpp;
    }

Original comment by vibha.jo...@gmail.com on 8 Jun 2015 at 7:23

GoogleCodeExporter commented 8 years ago
vpp.registerValueProcessor(Double.class,new DoubleValueProcessor(new 
DoubleProcessor())); line gives exception as the doubleProcessor already 
exists. I wanted to write a DoubleValueProcessor that handles null

Original comment by vibha.jo...@gmail.com on 8 Jun 2015 at 7:25

GoogleCodeExporter commented 8 years ago
one way is to remove the registered parser , write your own parser and add it 
to the hashmap. Ex.

vpp.removeValueProcessor(Double.class);
        vpp.registerValueProcessor(Double.class,new DoubleValueProcessor(new DoubleProcessor()));

in your own custom parser you can put the null check .Ex

public class DoubleValueProcessor implements ValueProcessor<Double> {

    private DoubleProcessor doubleProcessor;

    public DoubleValueProcessor(DoubleProcessor doubleProcessor) {
        this.doubleProcessor = doubleProcessor;
    }

    @Override
    public Double processValue(String value) {
        if (!StringUtils.isEmpty(value)) {
            return doubleProcessor.processValue(value);
        }
        return null;
    }

}

Original comment by vibha.jo...@gmail.com on 9 Jun 2015 at 3:10