populating Bean member variables from factory methods?
Brought to you by:
aruckerjones,
sconway
With a csv like this:
country name, currency
Hong Kong, HKD
USA, USD
Canada, CAD
I need to populate classes based on some static method roughly like this:
class Country {
@CsvBindByName(column = "country name")
String name;
@CsvBindByName(column = "currency")
@SomeAssignmentProcessor(method = java.util.Currency::getInstance)
java.util.Currency ccy;
}
Is that possible now?
Well, you could always write a small custom converter for that purpose.
Alternately, you could define a String field for that column, map that, but in the setter for that field, set your Currency field instead.
Would you consider adding that Converter to the codebase? I attached the one I am using.
Looks nice. Any chance you could contribute tests also?
Sure. What class(es) would you suggest I add these tests to? StatefulBeanToCsvWithCSVWriterTest.?
We already have one custom coonverter. I suggest you look at how that is tested and see if that makes sense for your converter also.
You're talking about ConvertGermanToBoolean?
Yes.
I am thinking I would like native support for Currency. It looks quick and easy—it would be your code in a different class and a couple lines to link it into … the mapping strategy, I think. You interested in doing it that way? It would be com.opencsv.bean.ConverterCurrency, analog to ConverterDate, ConverterEnum, ConverterNumber, and ConverterPrimitiveTypes.
Sounds great. I can create that class.
Does this look ok? Can we specify the String.class in the ConverterCurrency constructor the way I've done? Working on tests....
Last edit: Andrew M 2020-07-01
I added tests and a 51st field to AnnotatedMockBeanFull
However it seems like with that extra field I have to add a 51st field to almost every row of every CSV in in the test resources.
Yeah, the test thing is kind of a pain, I admit.
Is there any advantage to having an annotation CsvCurrency? It carries no information. I would simply check the type of the field involved, and if it is Currency, use the new converter.
Your parameters to the new converter are sparse. Take a look at the parameters passed to the other converters and how they are used. I would expect all existing functionality to be supported, and that includes things like format strings. Looking at the other converters should also answer your question about passing in String.class as the type.
If we can automatically apply the converter without an annotation whenever the field type is Currency then that makes the most sense.
I believe there should be no parameters since the currency code is not language or locale specific. Is that right?
Does this look ok?
I changed testUnknownElementType from Currency to TimeZone.
Why is there both opencsv.properties and opencsv_en.properties? I'm guessing the first one becomes the default when the locale is not en, fr, de or pt_br? Could one be removed?
Getting closer.
Yes, both properties files are necessary. Bug 180 for reference.
In ConverterCurrency:
And then of course tests. :)
Attached. I'll add a couple tests too
Where would you want those tests added? I presume we need to test:
Would you add a field to MockBean for this?
The code looks good.
In your tests under "bad" values don't forget null and empty values, as applicable. That's bitten me a time or two.
I would not expect this to be a field in MockBean, because MockBean is not for annotation tests. I would expect to see it in AnnotatedMockBeanFull, though I am open to other suggestions. When I implemented the Java 8 Time API, I put all of those tests in their own mocks. But that was also a lot of fields and a lot of tests.
Are you suggesting I add a 51st field to AnnotatedMockBeanFull?
Yes.
Haven't heard back on this in a while. I like the idea of including this in the next release. Would you be willing to give me what you have with a summary of what's incomplete so I can finish it?
I finished the tests and merged this into master. It will go out with the next release. Thanks for your contribution!