Package org.apache.sis.util

# Interface ObjectConverter<S,T>

Type Parameters:
  `S` - the type of objects to convert.
  `T` - the type of converted objects.

All Superinterfaces:
  `Function<S,T>`

public interface ObjectConverter<S,T> extends Function<S,T>
A function which converts instances of source type to instances of target type. The source and target types may be the same, in which case the `ObjectConverter` actually converts the values rather than the type.

The main method of this interface is `apply(Object)`, which receives an object of type S and returns an object of type T. The set of all S values for which `apply(S)` does not throw `UnconvertibleObjectException` is called the domain of this function, regardless of whether the T result is `null` or not.

## Function properties

Some characteristics about the S to T mapping are given by the `properties()` enumeration, together with the `getSourceClass()` and `getTargetClass()` methods. Some possible function properties are:

- Injective if no pair of S can produce the same T value (e.g.: conversions from `Integer` to `String`).
- Surjective if every values of T can be created from one or many values of S (e.g.: conversions from `String` to `Integer`).
- Bijective if there is a one-to-one relationship between the S and T values.
- Order preserving if any sequence of increasing S values (in the sense of `Comparable`) is mapped to a sequence of increasing T values.
- Order reversing if any sequence of increasing S values (in the sense of `Comparable`) is mapped to a sequence of decreasing T values.

Example: The function properties regarding order is important when converting `Range` objects. For example if the converter reverses the value ordering (e.g. reverses the sign of numerical values), then the minimum and maximum values in each `Range` instance 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.
Below are some guidelines about the function properties that a converter can declare:

- If `apply(S)` returns `null` for unconvertible objects, then this `ObjectConverter` can not be declared injective because more than one S value can produce the same T value (namely `null`).
- If `apply(S)` throws an exception for unconvertible objects, then this `ObjectConverter` can be declared as an injective function if the other values met the criteria.

Since:
  0.3
See Also:
  - `ObjectConverters`

Defined in the `sis-utility` module

- ## Method Summary

  Modifier and Type
  Method
  Description
  `T`
  `apply(S object)`
  Converts the given object from the source type S to the target type T.
  `Class<S>`
  `getSourceClass()`
  Returns the type of objects to convert.
  `Class<T>`
  `getTargetClass()`
  Returns the type of converted objects.
  `ObjectConverter<T,S>`
  `inverse()`
  Returns a converter capable to convert instances of T back to instances of S.
  `Set<FunctionProperty>`
  `properties()`
  Returns the manner in which source values (S) are mapped to target values (T).

  ### Methods inherited from interface Function

  `andThen, compose`

- ## Method Details

  - ### properties

    Set<FunctionProperty> properties()
    Returns the manner in which source values (S) are mapped to target values (T). Some possible function properties are:
    - Injective if no pair of S can produce the same T value (e.g.: conversions from `Integer` to `String`).
    - Surjective if every values of T can be created from one or many values of S (e.g.: conversions from `String` to `Integer`).
    - Bijective if there is a one-to-one relationship between the S and T values.
    - Order preserving if any sequence of increasing S values (in the sense of `Comparable`) is mapped to a sequence of increasing T values.
    - Order reversing if any sequence of increasing S values (in the sense of `Comparable`) is mapped to a sequence of decreasing T values.
    Note that if the `apply(Object)` method returns `null` for unconvertible source values, then this properties set can not contain `FunctionProperty​.INJECTIVE` because more than one source value could be converted to the same `null` target value.
    Returns:
      the manners in which source values are mapped to target values. May be an empty set, but never null.

  - ### getSourceClass

    Class<S> getSourceClass()
    Returns the type of objects to convert.
    Returns:
      the type of objects to convert.

  - ### getTargetClass

    Class<T> getTargetClass()
    Returns the type of converted objects.
    Returns:
      the type of converted objects.

  - ### apply

    T apply(S object) throws UnconvertibleObjectException
    Converts the given object from the source type S to the target type T. If the given object can not be converted, then this method may either returns `null` or throws an exception, at implementation choice (except for injective functions, which must throw an exception - see the class Javadoc for more discussion about function properties).
    Example: in Apache SIS implementation, converters from `String` to `Number` distinguish two kinds of unconvertible objects:
    - Null or empty source string result in a `null` value to be returned.
    - All other kind of unparsable strings results in an exception to be thrown.
    In other words, the `""` value is unconvertible but nevertheless considered as part of the converter domain, and is mapped to "no number". All other unparsable strings are considered outside the converter domain.
    Specified by:
      `apply` in interface `Function<S,T>`
    Parameters:
      `object` - the object to convert, or `null`.
    Returns:
      the converted object, or `null`.
    Throws:
      `UnconvertibleObjectException` - if the given object is not an element of the function domain.

  - ### inverse

    ObjectConverter<T,S> inverse() throws UnsupportedOperationException
    Returns a converter capable to convert instances of T back to instances of S. Before to invoke this method, callers can verify if this converter is invertible as below:

    >     if (converter.properties().contains(FunctionProperty.INVERTIBLE)) {
    >         // Call to converter.inverse() is allowed here.
    >     }

    Returns:
      a converter for converting instances of T back to instances of S.
    Throws:
      `UnsupportedOperationException` - if this converter is not invertible.
    See Also:
      - `FunctionProperty​.INVERTIBLE`