2

I am currently using Spring batch for reading a file. There is a possibility that certain columns in my file may have empty values. For example, a row in my file may look like this :

110045,,,50000

Here, column 2 and 3 have empty values. Column 2 will be mapped to a double and column 3 will be mapped to a char in my domain object. The FieldSetMapper will be implemented as follows :

public class MyFieldSetMapper implements FieldSetMapper<SomeDomain> {

    public SomeDomain mapFieldSet(FieldSet fs) {
        final SomeDomain someDomain = new SomeDomain();
        someDomain.setAmount(fs.readDouble(1));
        someDomain.setIndividualFlag(fs.readChar(2));
        someDomain.setBalance(fs.readInt(3,0));
        return someDomain;
    }
}

The FieldSetMapperimplementation above will result in an exception at runtime because an empty String cannot be convered to a double or a character.

While a FieldSet has methods such as readBigDecimal(int,BigDecimal) or readInt(int,int) that allow you to specify a default value if a string can't be parsed to a particular type, it does not provide similar methods for char or double. I am not sure what was the motivation behind leaving the defaulting options out for char and double types.

What I need is a way to provide a default value for char and double datatypes in a FieldSetMapper per field. That is, I don't want to define a global strategy for defaulting char and double datatypes but I want to be able to default these types just like I can default an int or a BigDecimal.

I thought of using a FieldSetFactory to plugin a custom FieldSet implementation that extends DefaultFieldSet and provides two more methods namely readDouble(int,double) and readChar(int,char)

public class CustomFieldSet extends DefaultFieldSet {

    public CustomFieldSet(String[] tokens, String[] names) {
        super(tokens, names);
    }

    public CustomFieldSet(String[] tokens) {
        super(tokens);
    }

    public char readChar(int index, char defaultValue) {
        String value = readAndTrim(index);
        return StringUtils.hasLength(value) ? value.charAt(0) : defaultValue;
    }

    public int readChar(String name, char defaultValue) {
        return readChar(indexOf(name), defaultValue);
    }
}

I could then cast the FieldSet argument that the mapFieldSet method takes into a CustomFieldSet implementation

public class MyFieldSetMapper implements FieldSetMapper<SomeDomain> {

  public SomeDomain mapFieldSet(FieldSet fs) {
       CustomFieldSet cs = (CustomFieldSet)fs;
       final SomeDomain someDomain = new SomeDomain();
       someDomain.setAmount(cs.readDouble(1));
       someDomain.setIndividualFlag(cs.readChar(2,'\0'));
       someDomain.setBalance(cs.readInt(3,0));
       return someDomain;
   }
}

This somehow doesn't feel like the right thing to do even though it integrates seamlessly with the spring batch FieldSet API.,

What are my options if I want to default char and double types in an elegant way rather than reading them as String, checking if they are not empty and converting them to the specific type manually.

Ping
  • 587
  • 5
  • 27

0 Answers0