Hello all
I'm a little bit delayed by the port of converters, which are a little
bit more difficult than I though. Part of the delay is because I'm
precisely trying to simplify them. However I hope to finish them
tomorrow, and continue the metadata port which is blocked by this issue.
I know that various projects have converters, including Apache
commons-beanutils. For this reason, I'm putting all the converter
implementations in internal package in order to have the flexibility to
replace them by an other implementations if we want in the future. For
now, the SIS converters serve a different purpose than the
commons-beanutils ones. Actually the SIS converters are closer to the
Spring's ones, and the ObjectConverter<S,T> interface has been designed
to be compatible with the Spring's one.
The main differences between commons-beanutils converters and SIS/Spring
converters is in the way the 'convert' method is defined:
* commons-beanutils: Object convert(Class, Object);
* Spring/SIS: T convert(S); - note the parameterized types
The SIS/Spring form is potentially more efficient since it doesn't have
to examine the target type everytime the convert method is invoked. The
target type is considered part of the converter definition, which fit
well SIS needs.
The main differences between the Spring converters and the SIS ones is
that Spring defines only one method - convert(S) - while SIS has more
exigences:
* An inverse() method returning a converter going backward from T to
S. This is needed for the java.util.Map views mentioned later.
* A properties() method returning some information about the
converter. In particular, the properties tell us if conversions from
S to T preserve (or reverse) ordering. This information is
irrelevant when converting independent values (maybe it was the only
use-case that Spring was concerned about), but become important when
converting Ranges. For example if the converter reverses the value
ordering (e.g. reverses the sign of numerical values), then the
minimum and maximum values in Ranges need to be interchanged. If the
ordering is not preserved at all (neither directly or reversed), as
for example in the conversion from Number to String, then we can not
convert Ranges at all.
An other reason for having SIS control on converters is that their
behaviour may depend on the context. For example when marshalling to ISO
19139 XML documents, some (not all) conversions to String shall use the
Locale defined in the 'language' property of the enclosing MD_Metadata
element. I'm not sure that we want to reproduce this (relatively)
complex rule in Java API (for now it doesn't), but it seems safe to keep
the flexibility to hack our converters that way if needed in the future.
Regarding metadata, converters are used for two purposes:
* When reading and writing metadata through Java reflection instead
than direct calls to the Java methods. For example it is possible to
view a metadata object as a java.util.Map (like JavaBeans), which is
quite convenient for writing some generic code. Converters allow to
edit metadata values without knowledge of the exact type.
* For building views over a subset of metadata values. For example if
one has a Map<K, Citation>, it is possible to build a view (not a
copy) of Map<K, String> where the Strings are the 'title' property
values of the Citation instances.
Martin