fixedformat4j api - bring on your feedback!
Posted by Jacob von Eyben on March 17th, 2008
Earlier I wrote about reading and writing fixed formatted text files. Fortunately you all were eager to comment and provide suggestions on how to do this.
Inspired by your suggestions I decided to write an open source api to manipulate these fixed formatted data and promised to get back when I had code that was releasable.
That time is now!
I have deliberately not released a version yet as I would like some feedback before I commit myself to an api.
Please take a look at the documentation at http://fixedformat4j.ancientprogramming.com/ and let me know your thoughts on the api.
The sourcecode can be browsed here.
I hope you will bring me some feedback before I do a final release.
March 18th, 2008 at 11:27 am
For EDI it must support BigDecimal (you can ditch Double and Float).
March 18th, 2008 at 11:32 am
I think it is an absolutely brilliant idea. Very simple - and that is a good thing! Now for my comments:
Annotations - naming: Instead of @FixedFormatField, @FixedFormatPattern etc. why not settle for @Field and @Pattern? The package name of the annotations com.ancientprogramming.fixedformat4j… should surely be enough to signify that we are dealing with fixed formats?
A more important point for me, though, is the interface Record which has one method, String export()
As I understand the API a record is supposed to implement the interface. In your examples you declare your record classes as abstract so you won’t have to implement an empty export() method.
I can see why it is syntactically nice to be able to write
myRecord.export();However, having to implement an empty method (or declare your entire class abstract) is in my view a very severe restriction to put on record classes - mostly because it is not really needed.
What I would prefer would be remove the interface Record and replace it with an annotation, much like the JPA @Entity
@Recordpublic class MyFixedRecord {
@Field(offset = 1, length = 10)
String getMyField() {
...
}
...
}
Furthermore I would like to have the option of putting @Field and @Pattern annotations on getters rather than fields. This would give more flexibility, e.g. the fixed format record could wrap another class and delegate its properties.
All this would of course require your FixedFormat helper classes to do a bit more work - you would need something like a FixedFormatManager (just as JPA makes use of an EntityManager).
However, the advantage of this approach is that there will be very few restrictions on the Record class. It can be a POJO or it can be something else entirely. In fact, you could have a class that is both a JPA @Entity and a FixedFormat @Record
@Entity@Record
public class MyEntityWhichCanAlsoBeExportedInFixedFormat {
... yada yada yada
}
Now that would be rather cool, wouldn’t it?
March 18th, 2008 at 7:44 pm
Bob: Ok, I will include a BigDecimal formatter in the default “ByTypeFormatter”, but as I can’t be sure how data is prefered to be formatted, I have made it easy to implement your own formatters. Just implement the interface:
public interface FixedFormatter {
Object parse(String value, FixedFormatData data) throws FixedFormatException;
String format(Object value, FixedFormatData data) throws FixedFormatException;
}
Ex: on my current project a number like 100.50 is to be formatted like this in string representation: 000010050+, where the signing is prepended.
Niels: I agree with the record implementation dependency and I will remove it.
To fully be able to do what you suggest I have to change the api a bit more.
Today a record modifies a StringBuffer behind the scenes as you manipulate the data through setters. That gives the user the posibility to hand in a StringBuffer and still hold a reference to an always updated buffer. We took that approach on my current project. That was neat when we had a text file with 50 different records and only had to load in and modify 10 of those before exporting the data. It was easy to export the data as we held a reference to all the stringbuffers, both those modified by record ojects and those we kept unmodifed.
It will not be a bit more hardwork (if not impossible) to keep a reference to an updated stringbuffer in your suggested POJO approach - but I like the idea of being able to export any object. The stringbuffer will suffer probably suffer then
My suggestions to api changes:
- To create an “empty” record you just create an instance like any other pojo. That makes it possible to load such objects through, say JPA.
- Do you want to create one from an existing text you have to go through the RecordManager (former RecordManager) as I dont want to force a interface implementation.
- The same goes for exporting, you have to go through the RecordManager.
The API will look Something like this:
//Empty record
MyRecord record = new MyRecord();
//A record instance loaded with text
MyRecord record = RecordManager.create(MyRecord.class, "This is a record foobar 00004200");
//export of record data
String export = RecordManager.export(record);
About adding annotations to the setters and getters it is actually possible today as well. I just included the possibility to add those to properties as well, to reduce duplication of annotation data on setter getter pairs.
March 19th, 2008 at 8:53 am
Where can i download the JAR-File?
March 19th, 2008 at 12:13 pm
Martin: I haven’t released a version yet, as the api is to unstable.
Niels came with a bunch of good suggestions on how to change the api and I will go in that direction.
But of course you are free to download the source and compile your own version. Just execute the following svn command:
svn checkout http://fixedformat4j.googlecode.com/svn/trunk/ fixedformat4j-read-onlyThe api is tested and works as described on fixedformat4j.ancientprogramming.com, but keep in mind that the first final version will vary a bit in usage from the current trunk version.
March 20th, 2008 at 12:32 pm
Many years ago I worked on jPOS. This library processes ISO-8583 records. This format has all sorts of interesting ideas. It would be great if your library could parse these types of records. Some ideas:
1. Allow conditional fields. E.g. If field1 has value x, then field 2 exists.
2. Support inheritance ala discriminator fields in JPA. This is a different way to support conditional fields.
3. Your idea of annotating fields is a great idea. How about using the same idea to support reading fixed-column CSV files.
Have fun!
March 21st, 2008 at 12:31 am
Hey jeyben,
I have a great, working library that does what you intend on doing with your library. Wouldn’t you like to join forces instead or splitting in two different ways?
Take a look:
http://tinyurl.com/32cybz
And for code refer the original version, in Portuguese:
http://blog.felipecoury.com/jep/2008/02/java-text-import-export.html
Please e-mail me if you think it’s a good idea to join forces.
Best regards,
Felipe Coury.
May 25th, 2008 at 10:11 pm
[...] fixedformat4j api - bring on your feedback! [...]
May 30th, 2008 at 3:58 pm
Hey jeyben, I have got the following run time exception when I run your tutorial:
C:\Documents and Settings\gusaros\Desktop\fixformat>java FixedTesting
Exception in thread “main” java.lang.NoClassDefFoundError: org/apache/commons/lo
gging/LogFactory
at com.ancientprogramming.fixedformat4j.format.impl.FixedFormatManagerIm
pl.(FixedFormatManagerImpl.java:48)
at FixedTesting.main(FixedTesting.java:30)
Thank you.
May 30th, 2008 at 5:00 pm
Att: Shakir.
You get the exception because you do not have the required dependencies for using fixedformat4j.
Fixedformat4j depends on commons-lang and commons-logging at runtime.
See the list of the dependencies here: http://fixedformat4j.ancientprogramming.com/dependencies.html
If you aren’t building with maven, you can download both from here:
commons-lang: http://commons.apache.org/lang/
commons-logging: http://commons.apache.org/logging/
And remember to use the latest release of fixedformat4j as various bugs was found and fixed in 1.1.1:
http://code.google.com/p/fixedformat4j/downloads/list