I came up with a quick pair of implementations to make this process easier:
1. LineFormatFactoryBean
Using a FactoryBean, you can split up the format into individual parts to make it clearer:
Code:
<bean id="lineAggregator" class="...FormatterLineAggregator">
<property name="fieldExtractor">
<bean class="org.springframework.batch.item.file.transform.BeanWrapperFieldExtractor">
<property name="names" value="name,credit" />
</bean>
</property>
<property name="format">
<bean class="org.springframework.batch.item.file.transform.LineFormatFactoryBean">
<property name="fields">
<list>
<value>%-9s</value> <!-- name -->
<value>%-2.0f</value> <!-- credit -->
</list>
</property>
</bean>
</property>
</bean>
Code:
public class LineFormatFactoryBean implements FactoryBean {
private String[] fields;
public Object getObject() throws Exception {
StringBuilder sb = new StringBuilder();
for (String field : fields) {
sb.append(field);
}
return sb.toString();
}
public Class<String> getObjectType() {
return String.class;
}
public boolean isSingleton() {
return false;
}
public void setFields(String[] fields) {
this.fields = fields;
}
}
2. BeanWrapperLineAggregator
If you're using a BeanWrapperLineExtractor, then you can simplify the configuration of the LineAggregator by just passing in a map of field names and their individual formats. The BeanWrapperLineAggregator will extract the properties and format them in the specified order:
Code:
<bean id="lineAggregator" class="...BeanWrapperLineAggregator">
<property name="fields">
<map>
<entry key="name" value="%-9s"/>
<entry key="credit" value="%-2.0f"/>
</map>
</property>
</bean>
Code:
public class BeanWrapperLineAggregator<T> implements LineAggregator<T>, InitializingBean {
private FormatterLineAggregator<T> formatterLineAggregator = new FormatterLineAggregator<T>();
private Map<String, String> fields;
public void afterPropertiesSet() throws Exception {
String[] fieldNames = new String[fields.size()];
String[] formats = new String[fields.size()];
int i = 0;
for (Entry<String, String> field : fields.entrySet()) {
fieldNames[i] = field.getKey();
formats[i] = field.getValue();
i++;
}
BeanWrapperFieldExtractor<T> fieldExtractor = new BeanWrapperFieldExtractor<T>();
fieldExtractor.setNames(fieldNames);
formatterLineAggregator.setFieldExtractor(fieldExtractor);
LineFormatFactoryBean lineFormat = new LineFormatFactoryBean();
lineFormat.setFields(formats);
formatterLineAggregator.setFormat((String) lineFormat.getObject());
}
public String aggregate(T item) {
return this.formatterLineAggregator.aggregate(item);
}
/**
* @param fields A map of fields where the name of the field is the key and
* the format is the value
*/
public void setFields(Map<String, String> fields) {
this.fields = fields;
}
}