Open robross0606 opened 9 years ago
I've used https://github.com/FasterXML/jackson-dataformat-csv for this before and I agree it's quite nice to have a CSV-specific DTO with annotations.
Some thoughts:
CsvBeanReader
and CsvBeanWriter
@CellProcessor(new Optional(new FmtDate())
to keep things simple, instead of specific annotations like the super-csv-annotation project).Despite the limitations/problems @jamesbassett mentions, I think it'd be cool if someone makes a PR for this.
Yeah I agree - and that's not a list of problems, more of an idea of how it could be implemented :)
I was thinking how to create a generic annotation that would allow to use any CellProcessor including custom or chained ones. The problem is that CellProcessor object cannot be an annotation member.
This is what I came up with.
1) For really simple cases:
@CellProcessor(NotNull.class)
2) For cell processors with arguments (including chained processors).
@CellProcessor(value=Optional.class, args={@CellProcessor(value=FmtDate.class, args ={“DD-MM-YYYY”})})
Limitation: will not be possible to use something other than allowed annotation member types or other cell processors as cell processor constructor arguments.
3) For use with any processors, but not typesafe:
@CellProcessor(cellProcString="new Optional(new FmtDate(\”DD-MM-YYYY\”))")
CellProcessor will be created by building a String containing its source code (a wrapper around a cell processor which is defined in cellProcString) and compiling it into actual class using the JavaCompiler class.
In case of custom/third-party cell processors one will need to supply package name:
@CellProcessor(cellProcString=”new MyCustomProcessor(new AnotherProcessor())”, customProcessorPackages={“org.mycompanyname.myprocessors”, “org.othercompany.otherprocessors”})
Does that sound like a viable idea?
Suggestions?
Hi @singularityfx
Thanks for your thoughts. There is something inside of me that feels wrong when I read your suggestion. I have always been of the impression that annotations were short and declarative rather than imperative.
while your approach is more general. it does entail dumping java into strings with no compiler to support the user.
Personally, I think we get the most millage from doing bespoke annotations to the current set of processors - despite the limitations it imposes.
Any oppinions or objections? @jamesbassett ? @ZioberMichal ?
Hi @singularityfx , @kbilsted,
I agree with @kbilsted that we should not go in direction where at the end we have to parse String
to "Java code".
I think that CellProcessor
is a good name but it is already used and we can not reuse it because it will be confusing to have interface and annotation with the same name.
Option 1) and 2) look good and they should cover most of cases. At the beginning, I think, we should put our effort to implement annotations for CellProcessor
s. Things related with configuration we can skip and I think they are not so important.
I propose to create two simple annotations:
public @interface Processor {
Class<? extends CellProcessor> value();
String[] args() default {}; //??? It will be tricky to instantiate a class.
}
and
public @interface Processors {
Processor[] value();
}
according to Repeating Annotations article.
I prefer repeating annotation because they are "eye-friendly" and for long chain of processors it will be easier to register all of them. Chain order: 0-processor invokes 1-processor which invokes ... i-processor which ..... (0, 1, ..., i, ... - indexes of processors in array).
The biggest problem with implementation which I see it is creating instances of given CellProcessor
. Regarding to args
attribute we should be able to invoke proper constructor and try to parse arguments for it.
What if, for example, given CellProcessor
has more than one constructor with the same number of parameters? Should we try first and if it will fail we can try invoke another?
We can add additional attribute:
Class<?>[] argsClasses() default {};
and use it when we have more than one constructor with the same number of parameters but this solution obscures annotation declaration.
What do you think guys?
Repeating annotations are Java8 only. Is it a good idea to drop backward compatibility?
Oh, sorry. I meant to use only one part from this page "Step 2: Declare the Containing Annotation Type" to show my point of view. Sorry for misunderstanding.
I am thinking about something like this:
public class Bean {
@Processors({@Processor(Trim.class), @Processor(ParseDate.class)})
private Date birthDay;
....
}
It must be possible in the current version which we are using.
This project could really benefit from incorporating - or at least absorbing as a module - Super CSV Annotations.
https://github.com/mygreen/super-csv-annotation
This is supremely useful for reducing code complexity. However, the biggest key missing feature I've found so far is that there is no current annotation support for custom cell processors.