There is sometimes a need to convert instances from a source Java type to a target Java type while those types are unknown at compile time. Various projects (Apache Common Convert, Spring, etc.) have created their own interface for performing object conversions between types known only at runtime. Details vary, but such interfaces typically look like below:
interface ObjectConverter<S,T> { // Some projects use only "Converter" as interface name.
T apply(S object); // Another method name commonly found in other projects is "convert".
}
Like other projects, Apache SIS also defines its own ObjectConverter
interface.
The main difference between SIS converter interface and the interfaces found in other projects
is that SIS converters provide some information about their mathematical properties.
An Apache SIS converter can have zero, one or many of the following properties:
Example:
the Integer
→ String
conversion performed by Integer.toString()
is an injective function because if two Integer
values are not equal,
then it is guaranteed that their conversions will result in different String
values.
However the String
→ Integer
conversion performed by Integer.valueOf(String)
is not an injective function
because many distinct String
values can be converted to the same Integer
value.
For example converting the "42", "+42" and "0042" character strings all result in the same 42 integer value.
Example:
the String
→ Integer
conversion performed by Integer.valueOf(String)
is a surjective function because every Integer
value can be created from at least one String
value.
However the Integer
→ String
conversion performed by Integer.toString()
is not a surjective function because it cannot produce all possible String
values.
For example there is no way to produce the "ABC" value with the Integer.toString()
method.
Note:
the bijective property is defined here for clarity, but actually does not have an explicit item
in Apache SIS FunctionProperty
enumeration.
It is not necessary since a function that is both injective and surjective is necessarily bijective.
Example:
conversion from Integer
to Long
preserve the natural ordering of elements.
However conversions from Integer
to String
do not preserve natural ordering,
because some sequences of increasing integer values are ordered differently when their string representations are sorted by lexicographic order.
For example 1, 2, 10 become "1", "10", "2".
Example: a conversion that reverses the sign of numbers.
Above information may seem unnecessary when values are converted without taking in account the context in which the values appear. But when the value to convert is part of a bigger object, then above information can affect the way the converted value will be used. For example conversion of a [min … max] range is straightforward when the converter is order preserving. But if the converter is order reversing, then the minimum and maximum values need to be interchanged. For example if the converter reverses the sign of values, then the converted range is [-max … -min]. If the converter is neither order preserving or order reversing, then range conversion is not allowed at all (because it does not contain the same set of values) even if the minimum and maximum values could be converted individually.