# Class Types

Object
Static
Types

public final class Types extends Static
Static methods working on GeoAPI types and `CodeList` values. This class provides:

- Methods for fetching the ISO name or description of a code list:
  - `getStandardName(Class)` for ISO name
  - `getListName(CodeList)` for ISO name
  - `getDescription(Class)` for a description
- Methods for fetching the ISO name or description of a code value:
  - `getCodeName(CodeList)` for ISO name,
  - `getCodeTitle(CodeList)` for a label or title
  - `getDescription(CodeList)` for a more verbose description
- Methods for fetching an instance from a name (converse of above `get` methods):
  - `forCodeName(Class, String, boolean)`
  - `forEnumName(Class, String)`

## Substituting a free text by a code list

The ISO standard allows to substitute some character strings in the free text domain by a `CodeList` value. Such substitution can be done with:

- `getCodeTitle(CodeList)` for getting the `InternationalString` instance to store in a metadata property.
- `forCodeTitle(CharSequence)` for retrieving the `CodeList` previously stored as an `InternationalString`.

## Example

In the following XML fragment, the `<mac:type>` value is normally a `<gco:CharacterString>` but has been replaced by a `SensorType` code below:

    <mac:MI_Instrument>
      <mac:type>
        <gmi:MI_SensorTypeCode
            codeList="http://standards.iso.org/…snip…/codelists.xml#CI_SensorTypeCode"
            codeListValue="RADIOMETER">Radiometer</gmi:MI_SensorTypeCode>
      </mac:type>
    </mac:MI_Instrument>

Since:
  0.3

- ## Method Summary

  Modifier and Type
  Method
  Description
  `static <T extends CodeList<T>>
  T`
  `forCodeName(Class<T> codeType, String name, boolean canCreate)`
  Deprecated, for removal: This API element is subject to removal in a future version.
  This method depends on reflection, which is restricted in the context of Java Module System.
  `static <T extends CodeList<T>>
  T`
  `forCodeName(Class<T> codeType, String name, Function<? super String, ? extends T> constructor)`
  Returns the code of the given type that matches the given name, or optionally returns a new one if none match the name.
  `static CodeList<?>`
  `forCodeTitle(CharSequence title)`
  Returns the code list or enumeration value for the given title, or `null` if none.
  `static <T extends Enum<T>>
  T`
  `forEnumName(Class<T> enumType, String name)`
  Returns the enumeration value of the given type that matches the given name, or `null` if none.
  `static Class<?>`
  `forStandardName(String identifier)`
  Returns the Java type (usually a GeoAPI interface) for the given ISO name, or `null` if none.
  `static String`
  `getCodeLabel(CodeList<?> code)`
  Returns a unlocalized title for the given enumeration or code list value.
  `static String`
  `getCodeName(CodeList<?> code)`
  Returns the ISO name (if available) or the Java name (as a fallback) of the given enumeration or code list value.
  `static InternationalString`
  `getCodeTitle(CodeList<?> code)`
  Returns the title of the given enumeration or code list value.
  `static <T extends CodeList<?>>
  T[]`
  `getCodeValues(Class<T> codeType)`
  Deprecated, for removal: This API element is subject to removal in a future version.
  This method depends on reflection, which is restricted in the context of Java Module System.
  `static InternationalString`
  `getDescription(Class<?> type)`
  Returns a description for the given class, or `null` if none.
  `static InternationalString`
  `getDescription(Class<?> type, String property)`
  Returns a description for the given property, or `null` if none.
  `static InternationalString`
  `getDescription(CodeList<?> code)`
  Returns the description of the given enumeration or code list value, or `null` if none.
  `static String`
  `getListName(CodeList<?> code)`
  Returns the ISO classname (if available) or the Java classname (as a fallback) of the given enumeration or code list value.
  `static String`
  `getStandardName(Class<?> type)`
  Returns the ISO name for the given class, or `null` if none.
  `static InternationalString`
  `toInternationalString(CharSequence string)`
  Returns the given characters sequence as an international string.
  `static InternationalString`
  `toInternationalString(Map<String,?> properties, String prefix)`
  Returns an international string for the values in the given properties map, or `null` if none.
  `static InternationalString[]`
  `toInternationalStrings(CharSequence... strings)`
  Returns the given array of `CharSequence`s as an array of `InternationalString`s.
  `static String`
  `toString(InternationalString i18n, Locale locale)`
  Returns the given international string in the given locale, or `null` if the given string is null.

  ### Methods inherited from class Object

  `clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

- ## Method Details

  - ### getStandardName

    @OptionalCandidate public static String getStandardName(Class<?> type)
    Returns the ISO name for the given class, or `null` if none. This method can be used for GeoAPI interfaces or `CodeList`.

    #### Examples

    - `getStandardName(Citation.class)` (an interface) returns `"CI_Citation"`.
    - `getStandardName(AxisDirection.class)` (a code list) returns `"CS_AxisDirection"`.

    #### Implementation note

    This method looks for the `UML` annotation on the given type. It does not search for parent classes or interfaces if the given type is not directly annotated (i.e. `@UML` annotations are not inherited). If no annotation is found, then this method does not fallback on the Java name since, as the name implies, this method is about standard names.
    Parameters:
      `type` - the GeoAPI interface or code list from which to get the ISO name, or `null`.
    Returns:
      the ISO name for the given type, or `null` if none or if the given type is `null`.
    See Also:
      - `forStandardName(String)`

  - ### getListName

    public static String getListName(CodeList<?> code)
    Returns the ISO classname (if available) or the Java classname (as a fallback) of the given enumeration or code list value. This method uses the `UML` annotation if it exists, or fallback on the simple class name otherwise.

    #### Examples

    - `getListName(ParameterDirection​.IN_OUT)` returns `"SV_ParameterDirection"`.
    - `getListName(AxisDirection​.NORTH)` returns `"CS_AxisDirection"`.
    - `getListName(TopicCategory​.INLAND_WATERS)` returns `"MD_TopicCategoryCode"`.
    - `getListName(ImagingCondition​.BLURRED_IMAGE)` returns `"MD_ImagingConditionCode"`.
    Parameters:
      `code` - the code for which to get the class name, or `null`.
    Returns:
      the ISO (preferred) or Java (fallback) class name, or `null` if the given code is null.

  - ### getCodeName

    public static String getCodeName(CodeList<?> code)
    Returns the ISO name (if available) or the Java name (as a fallback) of the given enumeration or code list value. If the value has no `UML` identifier, then the programmatic name is used as a fallback.

    #### Examples

    - `getCodeName(ParameterDirection​.IN_OUT)` returns `"in/out"`.
    - `getCodeName(AxisDirection​.NORTH)` returns `"north"`.
    - `getCodeName(TopicCategory​.INLAND_WATERS)` returns `"inlandWaters"`.
    - `getCodeName(ImagingCondition​.BLURRED_IMAGE)` returns `"blurredImage"`.
    Parameters:
      `code` - the code for which to get the name, or `null`.
    Returns:
      the UML identifiers or programmatic name for the given code, or `null` if the given code is null.
    See Also:
      - `getCodeLabel(CodeList)`
      - `getCodeTitle(CodeList)`
      - `getDescription(CodeList)`
      - `forCodeName(Class, String, boolean)`

  - ### getCodeLabel

    public static String getCodeLabel(CodeList<?> code)
    Returns a unlocalized title for the given enumeration or code list value. This method builds a title using heuristics rules, which should give reasonable results without the need of resource bundles. For better results, consider using `getCodeTitle(CodeList)` instead.

    The current heuristic implementation iterates over all code names, selects the longest one excluding the field name if possible, then makes a sentence from that name.

    #### Examples

    - `getCodeLabel(AxisDirection​.NORTH)` returns `"North"`.
    - `getCodeLabel(TopicCategory​.INLAND_WATERS)` returns `"Inland waters"`.
    - `getCodeLabel(ImagingCondition​.BLURRED_IMAGE)` returns `"Blurred image"`.
    Parameters:
      `code` - the code from which to get a title, or `null`.
    Returns:
      a unlocalized title for the given code, or `null` if the given code is null.
    See Also:
      - `getCodeName(CodeList)`
      - `getCodeTitle(CodeList)`
      - `getDescription(CodeList)`

  - ### getCodeTitle

    public static InternationalString getCodeTitle(CodeList<?> code)
    Returns the title of the given enumeration or code list value. Title are usually much shorter than descriptions. English titles are often the same as the code labels.

    The code or enumeration value given in argument to this method can be retrieved from the returned title with the `forCodeTitle(CharSequence)` method. See Substituting a free text by a code list in this class javadoc for more information.

    Parameters:
      `code` - the code for which to get the title, or `null`.
    Returns:
      the title, or `null` if the given code is null.
    See Also:
      - `getDescription(CodeList)`
      - `forCodeTitle(CharSequence)`

  - ### getDescription

    @OptionalCandidate public static InternationalString getDescription(CodeList<?> code)
    Returns the description of the given enumeration or code list value, or `null` if none. For a description of the code list as a whole instead of a particular code, see `getDescription(Class)`.
    Parameters:
      `code` - the code for which to get the localized description, or `null`.
    Returns:
      the description, or `null` if none or if the given code is null.
    See Also:
      - `getCodeTitle(CodeList)`
      - `getDescription(Class)`

  - ### getDescription

    @OptionalCandidate public static InternationalString getDescription(Class<?> type)
    Returns a description for the given class, or `null` if none. This method can be used for GeoAPI interfaces or `CodeList`.
    Parameters:
      `type` - the GeoAPI interface or code list from which to get the description, or `null`.
    Returns:
      the description, or `null` if none or if the given type is `null`.
    See Also:
      - `getDescription(CodeList)`

  - ### getDescription

    public static InternationalString getDescription(Class<?> type, String property)
    Returns a description for the given property, or `null` if none. The given type shall be a GeoAPI interface, and the given property shall be a UML identifier. If any of the input argument is `null`, then this method returns `null`.
    Parameters:
      `type` - the GeoAPI interface from which to get the description of a property, or `null`.
      `property` - the ISO name of the property for which to get the description, or `null`.
    Returns:
      the description, or `null` if none or if the given type or property name is `null`.

  - ### getCodeValues

    @Deprecated(since="1.5", forRemoval=true) public static <T extends CodeList<?>> T[] getCodeValues(Class<T> codeType)
    Deprecated, for removal: This API element is subject to removal in a future version.
    This method depends on reflection, which is restricted in the context of Java Module System. Instead, `T​.values()` static methods should be invoked directly as much as possible.
    Returns all known values for the given type of code list. Note that the size of the returned array may growth between different invocations of this method, since users can add their own codes to an existing list.
    Type Parameters:
      `T` - the compile-time type given as the `codeType` parameter.
    Parameters:
      `codeType` - the type of code list.
    Returns:
      the list of values for the given code list, or an empty array if none.
    See Also:
      - `Class​.getEnumConstants()`

  - ### forStandardName

    public static Class<?> forStandardName(String identifier)
    Returns the Java type (usually a GeoAPI interface) for the given ISO name, or `null` if none. The identifier argument shall be the value documented in the `UML​.identifier()` annotation on the Java type.

    #### Examples

    - `forStandardName("CI_Citation")` returns `Citation.class`
    - `forStandardName("CS_AxisDirection")` returns `AxisDirection.class`

    #### Implementation note

    The package prefix (e.g. `"CI_"` in `"CI_Citation"`) can be omitted. The flexibility is provided for allowing transition to newer ISO standards, which are dropping the package prefixes. For example, `"CS_AxisDirection"` in ISO 19111:2007 has been renamed `"AxisDirection"` in ISO 19111:2019.

    Only identifiers for the stable part of GeoAPI or for some Apache SIS classes are recognized. This method does not handle the identifiers for interfaces in the `geoapi-pending` module.

    #### Future evolution

    When a new ISO type does not yet have a corresponding GeoAPI interface, this method may temporarily return an Apache SIS class instead, until a future version can use the interface. For example, `forStandardName("CI_Individual")` returns `DefaultIndividual.class` in Apache SIS versions that depend on GeoAPI 3.0, but the return type may be changed to `Individual​.class` when Apache SIS will be upgraded to GeoAPI 3.1.
    Parameters:
      `identifier` - the ISO UML identifier, or `null`.
    Returns:
      the GeoAPI interface, or `null` if the given identifier is `null` or unknown.

  - ### forEnumName

    @OptionalCandidate public static <T extends Enum<T>> T forEnumName(Class<T> enumType, String name)
    Returns the enumeration value of the given type that matches the given name, or `null` if none. This method is similar to the standard `Enum​.valueOf(…)` method, except that this method is more tolerant on string comparisons:
    - Name comparisons are case-insensitive.
    - Only letter and digit characters are compared. Spaces and punctuation characters like `'_'` and `'-'` are ignored.
    If there is no match, this method returns `null` — it does not thrown an exception, unless the given class is not an enumeration.
    Type Parameters:
      `T` - the compile-time type given as the `enumType` parameter.
    Parameters:
      `enumType` - the type of enumeration.
      `name` - the name of the enumeration value to obtain, or `null`.
    Returns:
      a value matching the given name, or `null` if the name is null or if no matching enumeration is found.
    Since:
      0.5
    See Also:
      - `Enum​.valueOf(Class, String)`

  - ### forCodeName

    @OptionalCandidate public static <T extends CodeList<T>> T forCodeName(Class<T> codeType, String name, Function<? super String, ? extends T> constructor)
    Returns the code of the given type that matches the given name, or optionally returns a new one if none match the name. This method performs the same work as the GeoAPI `CodeList​.valueOf(…)` method, except that this method is more tolerant on string comparisons when looking for an existing code:
    - Name comparisons are case-insensitive.
    - Only letter and digit characters are compared. Spaces and punctuation characters like `'_'` and `'-'` are ignored.
    If no match is found, then a new code is created only if the `creator` argument is non-null. That argument should be a lambda function to the `valueOf(String)` method of the code list class. Example:

        AxisDirection dir = Types.forCodeName(AxisDirection.class, name, AxisDirection::valueOf);

    If the `constructor` is null and no existing code matches the given name, then this method returns `null`.
    Type Parameters:
      `T` - the compile-time type given as the `codeType` parameter.
    Parameters:
      `codeType` - the type of code list.
      `name` - the name of the code to obtain, or `null`.
      `constructor` - the constructor to use if a new code needs to be created, or `null` for not creating any new code.
    Returns:
      a code matching the given name, or `null` if the name is null or if no matching code is found and `constructor` is `null`.
    Since:
      1.5
    See Also:
      - `getCodeName(ControlledVocabulary)`
      - invalid reference

            CodeList#valueOf(Class, String, Function)

  - ### forCodeName

    @Deprecated(since="1.5", forRemoval=true) public static <T extends CodeList<T>> T forCodeName(Class<T> codeType, String name, boolean canCreate)
    Deprecated, for removal: This API element is subject to removal in a future version.
    This method depends on reflection, which is restricted in the context of Java Module System. Replaced by `forCodeName(Class, String, Function)`.
    Returns the code of the given type that matches the given name, or optionally returns a new one. If no match is found, then a new code is created only if the `canCreate` argument is `true`. Otherwise this method returns `null`.
    Type Parameters:
      `T` - the compile-time type given as the `codeType` parameter.
    Parameters:
      `codeType` - the type of code list.
      `name` - the name of the code to obtain, or `null`.
      `canCreate` - `true` if this method is allowed to create new code.
    Returns:
      a code matching the given name, or `null` if the name is null or if no matching code is found and `canCreate` is `false`.

  - ### forCodeTitle

    public static CodeList<?> forCodeTitle(CharSequence title)
    Returns the code list or enumeration value for the given title, or `null` if none. The current implementation performs the following choice:
    - If the given title is a value returned by a previous call to `getCodeTitle(CodeList)`, returns the code or enumeration value used for creating that title.
    - Otherwise returns `null`.
    Parameters:
      `title` - the title for which to get a code or enumeration value, or `null`.
    Returns:
      the code or enumeration value associated with the given title, or `null`.
    Since:
      0.7
    See Also:
      - `getCodeTitle(CodeList)`

  - ### toInternationalString

    @OptionalCandidate public static InternationalString toInternationalString(Map<String,?> properties, String prefix) throws IllegalArgumentException
    Returns an international string for the values in the given properties map, or `null` if none. This method is used when a property in a `Map` may have many localized variants. For example, the given map may contains a `"remarks"` property defined by values associated to the `"remarks_en"` and `"remarks_fr"` keys, for English and French locales respectively.

    If the given map is `null`, then this method returns `null`. Otherwise this method iterates over the entries having a key that starts with the specified prefix, followed by the `'_'` character. For each such key:

    - If the key is exactly equals to `prefix`, selects `Locale​.ROOT`.
    - Otherwise the characters after `'_'` are parsed as an ISO language and country code by the `Locales​.parse(String, int)` method. Note that 3-letters codes are replaced by their 2-letters counterparts on a best effort basis.
    - The value for the decoded locale is added in the international string to be returned.
    Parameters:
      `properties` - the map from which to get the string values for an international string, or `null`.
      `prefix` - the prefix of keys to use for creating the international string.
    Returns:
      the international string, or `null` if the given map is null or does not contain values associated to keys starting with the given prefix.
    Throws:
      `IllegalArgumentException` - if a key starts by the given prefix and:
      - The key suffix is an illegal `Locale` code,
      - or the value associated to that key is a not a `CharSequence`.
    Since:
      0.4
    See Also:
      - `Locales​.parse(String, int)`
      - `DefaultInternationalString(Map)`

  - ### toInternationalString

    public static InternationalString toInternationalString(CharSequence string)
    Returns the given characters sequence as an international string. If the given sequence is null or an instance of `InternationalString`, then this method returns it unchanged. Otherwise, this method copies the `InternationalString​.toString()` value in a new `SimpleInternationalString` instance and returns it.
    Parameters:
      `string` - the characters sequence to convert, or `null`.
    Returns:
      the given sequence as an international string, or `null` if the given sequence was null.
    See Also:
      - `DefaultNameFactory​.createInternationalString(Map)`

  - ### toInternationalStrings

    public static InternationalString[] toInternationalStrings(CharSequence... strings)
    Returns the given array of `CharSequence`s as an array of `InternationalString`s. If the given array is null or an instance of `InternationalString[]`, then this method returns it unchanged. Otherwise a new array of type `InternationalString[]` is created and every elements from the given array is copied or cast in the new array.

    If a defensive copy of the `strings` array is wanted, then the caller needs to check if the returned array is the same instance as the one given in argument to this method.

    Parameters:
      `strings` - the characters sequences to convert, or `null`.
    Returns:
      the given array as an array of type `InternationalString[]`, or `null` if the given array was null.

  - ### toString

    public static String toString(InternationalString i18n, Locale locale)
    Returns the given international string in the given locale, or `null` if the given string is null. If the given locale is `null`, then the `i18n` default locale is used.
    Parameters:
      `i18n` - the international string to get as a localized string, or `null` if none.
      `locale` - the desired locale, or `null` for the `i18n` default locale.
    Returns:
      the localized string, or `null` if `i18n` is `null`.
    Since:
      0.8