1

I am using BeanIO to write a fixed format file, which should contain some custom fields. These fields should use the same basic handler class, but they have slightly different parameters.

I have created a custom @Record that stores the data. Example:

@Record(minOccurs = 0, maxOccurs = -1)
@Fields({
    @Field(name = "recordType", ordinal = 1, length = 2, rid = true, literal = "00")})         
public class CustomField{
    @Field(ordinal = 2, length = 8, padding = '0', align = Align.RIGHT, handlerclass = AmountHandler.class)
    private BigDecimal firstAmount;

    @Field(ordinal = 3, length = 8, padding = '0', align = Align.RIGHT, handlerclass = AmountHandler.class)
    private BigDecimal secondAmount;
}

I now want to customize the handlerclass based on the field that is going to use it. So I created this class:

public class AmountHandler implements ConfigurableTypeHandler{
    private int fraction, length;

    public AmountHandler (int length, int fraction){
        this.length = length;
        this.fraction = fraction;
    }

    @Override
    public TypeHandler newInstance(Properties properties) throws IllegalArgumentException {
        length = Integer.parseInt(properties.getProperty("length"));
        fraction = Integer.parseInt(properties.getProperty("fraction"));
        return new CustomHandler(length, fraction);;
    }
    //parse and format are not yet implemented. 
    @Override
    public Object parse(String text) throws TypeConversionException { return null;}

    @Override
    public String format(Object value) { return null; }

    @Override
    public Class<?> getType() { return BigDecimal.class; }
}

However, I can't seem to find any way to set the properties for each field. How can I do this? Is there a way to define properties on a @Field type? Is there a better way to define a handler class for Objects with custom parameters?

Kurt Du Bois
  • 7,550
  • 4
  • 25
  • 33
Maraider
  • 11
  • 6

1 Answers1

0

You can do the following:

Create an instance of your AmountHandler for every variation you require in the same place where you define your StreamBuilder, for example:

AmountHandler amountHandler10_2 = new AmountHandler(10, 2);
AmountHandler amountHandler3_1 = new AmountHandler(3, 1);

You then register each instance with the StreamBuilder:

final StreamBuilder builder = new StreamBuilder("builder_name")
  .format("xml")
  .addTypeHandler("amountHandler10_2", amountHandler10_2)
  .addTypeHandler("amountHandler3_1", amountHandler3_1)
  .addRecord(CustomField.class);

Then you reference the appropriate type handler on each @Field, using the name you have given the instance when registering it with the StreamBuilder and using the handlerName property instead of handlerClass:

@Field(ordinal = 2, length = 8, padding = '0', align = Align.RIGHT, handlerName = "amountHandler10_2")
private BigDecimal firstAmount;
@Field(ordinal = 3, length = 8, padding = '0', align = Align.RIGHT, handlerName = "amountHandler3_1")
private BigDecimal secondAmount;

PS: I see this was asked several years ago, somehow it showed up on my RSS feed as a question today. So, I thought, let me answer it in any case, should someone else come across this question.

A similar question and answer: BeanIO: Format number with fixed length for integer and decimal places without separator

nicoschl
  • 2,346
  • 1
  • 17
  • 17