# Class Parameters

Object
Parameters

All Implemented Interfaces:
  `Cloneable`, `Printable`, `GeneralParameterValue`, `ParameterValueGroup`

Direct Known Subclasses:
  `ContextualParameters`, `DefaultParameterValueGroup`

public abstract class Parameters extends Object implements ParameterValueGroup, Cloneable, Printable
Convenience methods for fetching parameter values despite the variations in parameter names, value types and units. See `DefaultParameterValueGroup` javadoc for a description of the standard way to get and set a particular parameter in a group. The remaining of this javadoc is specific to Apache SIS.

## Convenience methods

This class provides the following convenience static methods:

- `cast(…, Class)` for type safety with parameterized types.
- `getMemberName(ParameterDescriptor)` for inter-operability between ISO 19111 and ISO 19115.
- `getValueDomain(ParameterDescriptor)` for information purpose.
- `copy(ParameterValueGroup, ParameterValueGroup)` for copying values into an existing instance.

Most instance methods in this class follow the same naming pattern than the methods provided by the `ParameterValue` interface. Those methods are themselves inspired by JDK methods:

Methods fetching parameter value
`Parameters` method | `ParameterValue` method | JDK methods
--- | --- | ---
`getValue(ParameterDescriptor)` | `getValue()` |
`booleanValue(ParameterDescriptor)` | `booleanValue()` | `Boolean.booleanValue()`
`intValue(ParameterDescriptor)` | `intValue()` | `Number.intValue()`
`intValueList(ParameterDescriptor)` | `intValueList()` |
`doubleValue(ParameterDescriptor)` | `doubleValue()` | `Number.doubleValue()`
`doubleValueList(ParameterDescriptor)` | `doubleValueList()` |
`stringValue(ParameterDescriptor)` | `stringValue()` |

## Fetching parameter values despite different names, types or units

The common way to get a parameter is to invoke the `ParameterValueGroup​.parameter(String)` method. This `Parameters` class provides alternative ways, using a `ParameterDescriptor` argument instead of a `String` argument. Those descriptors provide additional information like the various aliases under which the same parameter may be known. By using this information, `Parameters` can choose the most appropriate parameter name or alias (by searching for a common authority) when it delegates its work to the `parameter(String)` method.

### Example

The same parameter may be known under different names. For example, the length of the semi-major axis of the ellipsoid is commonly known as `"semi_major"`. But that parameter can also be named `"semi_major_axis"`, `"earth_radius"` or simply `"a"` in other libraries. When fetching parameter values, we do not always know in advance which of the above-cited names is recognized by an arbitrary `ParameterValueGroup` instance.

`Parameters` uses also the descriptor information for applying type and unit conversions (i.e. returned values are converted to the units of measurement specified by the given parameter descriptor).

## Note for subclass implementers

This class does not implement any method from the `ParameterValueGroup` interface (this class is not named “`AbstractParameterValueGroup`” for that reason). Extending this class or extending `Object` make almost no difference for implementers; `Parameters` purpose is mostly to extend the API for users convenience. All methods in this class get their information from the `ParameterValueGroup` methods. In addition, unless otherwise specified, methods in this class is isolated from all others: overriding one method has no impact on other methods.

Since:
  0.4

- ## Constructor Summary

  Constructors
  Modifier
  Constructor
  Description
  `protected`
  `Parameters()`
  For subclass constructors only.

- ## Method Summary

  Modifier and Type
  Method
  Description
  `boolean`
  `booleanValue(ParameterDescriptor<Boolean> parameter)`
  Returns the boolean value of the parameter identified by the given descriptor.
  `static <T> ParameterDescriptor<T>`
  `cast(ParameterDescriptor<?> descriptor, Class<T> valueClass)`
  Casts the given parameter descriptor to the given type.
  `static <T> ParameterValue<T>`
  `cast(ParameterValue<?> parameter, Class<T> valueClass)`
  Casts the given parameter value to the given type.
  `static Parameters`
  `castOrWrap(ParameterValueGroup parameters)`
  Returns the given parameter value group as a `Parameters` instance.
  `Parameters`
  `clone()`
  Returns a copy of this group of parameter values.
  `static void`
  `copy(ParameterValueGroup values, ParameterValueGroup destination)`
  Copies the values of a parameter group into another parameter group.
  `double`
  `doubleValue(ParameterDescriptor<? extends Number> parameter)`
  Returns the floating point value of the parameter identified by the given descriptor.
  `double`
  `doubleValue(ParameterDescriptor<? extends Number> parameter, Unit<?> unit)`
  Returns the floating point value of the parameter identified by the given descriptor, converted to the given unit of measurement.
  `double[]`
  `doubleValueList(ParameterDescriptor<double[]> parameter)`
  Returns the floating point values of the parameter identified by the given descriptor.
  `static GeneralParameterDescriptor[]`
  `getDescriptors(GeneralParameterValue... parameters)`
  Returns the descriptors of the given parameters, in the same order.
  `<T> T`
  `getMandatoryValue(ParameterDescriptor<T> parameter)`
  Returns the value of the parameter identified by the given descriptor, or throws an exception if none.
  `static MemberName`
  `getMemberName(ParameterDescriptor<?> parameter)`
  Gets the parameter name as an instance of `MemberName`.
  `<T> ParameterValue<T>`
  `getOrCreate(ParameterDescriptor<T> parameter)`
  Returns the parameter identified by the given descriptor.
  `Optional<URI>`
  `getSourceFile(ParameterDescriptor<?> parameter)`
  Returns the URI of the GML document or WKT file from which a parameter value has been read.
  `<T> T`
  `getValue(ParameterDescriptor<T> parameter)`
  Returns the value of the parameter identified by the given descriptor, or `null` if none.
  `static Range<?>`
  `getValueDomain(ParameterDescriptor<?> descriptor)`
  Returns the domain of valid values defined by the given descriptor, or `null` if none.
  `int`
  `intValue(ParameterDescriptor<? extends Number> parameter)`
  Returns the integer value of the parameter identified by the given descriptor.
  `int[]`
  `intValueList(ParameterDescriptor<int[]> parameter)`
  Returns the integer values of the parameter identified by the given descriptor.
  `static boolean`
  `isUnmodifiable(ParameterValueGroup parameters)`
  Returns `true` if the given parameter group is a non-null instance created by `unmodifiable(…)`.
  `void`
  `print()`
  Prints a string representation of this group to the standard output stream.
  `String`
  `stringValue(ParameterDescriptor<? extends CharSequence> parameter)`
  Returns the string value of the parameter identified by the given descriptor.
  `String`
  `toString()`
  Returns a string representation of this group.
  `static Parameters`
  `unmodifiable(ParameterValueGroup parameters)`
  Returns the given parameter value group as an unmodifiable `Parameters` instance.
  `static Parameters`
  `unmodifiable(ParameterValueGroup parameters, Predicate<? super GeneralParameterDescriptor> filter)`
  Returns the given parameter value group as an unmodifiable `Parameters` instance with some parameters hidden.

  ### Methods inherited from class Object

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

  ### Methods inherited from interface ParameterValueGroup

  `addGroup, getDescriptor, groups, parameter, values`

- ## Constructor Details

  - ### Parameters

    protected Parameters()
    For subclass constructors only.

- ## Method Details

  - ### isUnmodifiable

    public static boolean isUnmodifiable(ParameterValueGroup parameters)
    Returns `true` if the given parameter group is a non-null instance created by `unmodifiable(…)`.
    Parameters:
      `parameters` - the parameter group to test. Can be `null`.
    Returns:
      whether the given parameters are non-null and unmodifiable.
    Since:
      1.3

  - ### unmodifiable

    public static Parameters unmodifiable(ParameterValueGroup parameters)
    Returns the given parameter value group as an unmodifiable `Parameters` instance. If the given parameters is already an unmodifiable instance of `Parameters`, then it is returned as-is. Otherwise this method copies all parameter values in a new, unmodifiable, parameter group instance.
    Parameters:
      `parameters` - the parameters to make unmodifiable, or `null`.
    Returns:
      an unmodifiable group with the same parameters as the given group, or `null` if the given argument was null.
    Since:
      0.7
    See Also:
      - `DefaultParameterValue​.unmodifiable(ParameterValue)`

  - ### unmodifiable

    public static Parameters unmodifiable(ParameterValueGroup parameters, Predicate<? super GeneralParameterDescriptor> filter)
    Returns the given parameter value group as an unmodifiable `Parameters` instance with some parameters hidden. The hidden parameters are excluded from the list returned by `ParameterValueGroup​.values()`, but are otherwise still accessible when the hidden parameters is explicitly named in a call to `ParameterValueGroup​.parameter(String)`.

    #### Use case

    This method is used for hiding parameters that should be inferred from the context. For example, the `"semi_major"` and `"semi_minor"` parameters are included in the list of `MathTransform` parameters because that class has no way to know the values if they are not explicitly provided. But those semi-axis length parameters should not be included in the list of `CoordinateOperation` parameters because they are inferred from the context (the source and target CRS).
    Parameters:
      `parameters` - the parameters to make unmodifiable, or `null`.
      `filter` - specifies which source parameters to keep visible, or `null` if no filtering.
    Returns:
      an unmodifiable group with the parameters of the given group to keep visible, or `null` if the `parameters` argument was null.
    Since:
      1.3

  - ### castOrWrap

    public static Parameters castOrWrap(ParameterValueGroup parameters)
    Returns the given parameter value group as a `Parameters` instance. If the given parameters is already an instance of `Parameters`, then it is returned as-is. Otherwise this method returns a wrapper which delegate all method invocations to the given instance.

    This method provides a way to get access to the non-static `Parameters` methods, like `getValue(ParameterDescriptor)`, for an arbitrary `ParameterValueGroup` instance.

    Parameters:
      `parameters` - the object to cast or wrap, or `null`.
    Returns:
      the given argument as an instance of `Parameters` (may be the same reference), or `null` if the given argument was null.

  - ### cast

    public static <T> ParameterDescriptor<T> cast(ParameterDescriptor<?> descriptor, Class<T> valueClass) throws ClassCastException
    Casts the given parameter descriptor to the given type. An exception is thrown immediately if the parameter does not have the expected value class.
    Type Parameters:
      `T` - the expected value class.
    Parameters:
      `descriptor` - the descriptor to cast, or `null`.
      `valueClass` - the expected value class.
    Returns:
      the descriptor cast to the given value class, or `null` if the given descriptor was null.
    Throws:
      `ClassCastException` - if the given descriptor does not have the expected value class.
    See Also:
      - `Class​.cast(Object)`

  - ### cast

    public static <T> ParameterValue<T> cast(ParameterValue<?> parameter, Class<T> valueClass) throws ClassCastException
    Casts the given parameter value to the given type. An exception is thrown immediately if the parameter does not have the expected value class.
    Type Parameters:
      `T` - the expected value class.
    Parameters:
      `parameter` - the parameter to cast, or `null`.
      `valueClass` - the expected value class.
    Returns:
      the value cast to the given type, or `null` if the given value was null.
    Throws:
      `ClassCastException` - if the given value doesn't have the expected value class.
    See Also:
      - `Class​.cast(Object)`

  - ### getDescriptors

    public static GeneralParameterDescriptor[] getDescriptors(GeneralParameterValue... parameters)
    Returns the descriptors of the given parameters, in the same order. Special cases:
    - If the given array is `null`, then this method returns `null`.
    - If an element of the given array is `null`, then the corresponding element of the returned array is also `null`.
    Parameters:
      `parameters` - the parameter values from which to get the descriptors, or `null`.
    Returns:
      the descriptors of the given parameter values, or `null` if the `parameters` argument was null.
    Since:
      0.6

  - ### getMemberName

    public static MemberName getMemberName(ParameterDescriptor<?> parameter)
    Gets the parameter name as an instance of `MemberName`. This method performs the following checks:
    - If the primary name is an instance of `MemberName` (for example a `NamedIdentifier` subclass), returns that primary name.
    - Otherwise this method searches for the first alias which is an instance of `MemberName` (a subtype of aliases type). If found, that alias is returned.
    - If no alias is found, then this method tries to build a `MemberName` from the primary name and the value class, using the mapping defined in `DefaultTypeName` javadoc.
    This method can be used as a bridge between the parameter object defined by ISO 19111 (namely `CC_OperationParameter`) and the one defined by ISO 19115 (namely `SV_Parameter`).
    Parameters:
      `parameter` - the parameter from which to get the name (may be `null`).
    Returns:
      the member name, or `null` if none.
    Since:
      0.5
    See Also:
      - `Names​.createMemberName(CharSequence, String, CharSequence, Class)`

  - ### getValueDomain

    public static Range<?> getValueDomain(ParameterDescriptor<?> descriptor)
    Returns the domain of valid values defined by the given descriptor, or `null` if none. This method performs the following operations:
    - If the given parameter is an instance of `DefaultParameterDescriptor`, delegate to `DefaultParameterDescriptor​.getValueDomain()`.
    - Otherwise builds the range from the minimum value, maximum value and, if the values are numeric, from the unit.
    Parameters:
      `descriptor` - the parameter descriptor, or `null`.
    Returns:
      the domain of valid values, or `null` if none.
    See Also:
      - `DefaultParameterDescriptor​.getValueDomain()`

  - ### getSourceFile

    public Optional<URI> getSourceFile(ParameterDescriptor<?> parameter) throws ParameterNotFoundException
    Returns the URI of the GML document or WKT file from which a parameter value has been read.. This information can be used together with `getValue(ParameterDescriptor<URI>)` for resolving a parameter value as a path relative to the GML or WKT file declaring the parameter. Note that the source file is not necessarily the same for all parameters in a group, because a GML document could define parameters in files referenced by different `xlink:href` attribute values.
    Returns:
      the URI of the GML document or WKT file from which a parameter value has been read
    Throws:
      `ParameterNotFoundException`
    Since:
      1.5
    See Also:
      - `DefaultParameterValue​.getSourceFile()`
      - `WKTFormat​.getSourceFile()`
      - `MarshalContext​.getDocumentURI()`
      - `URI​.resolve(URI)`

  - ### getValue

    public <T> T getValue(ParameterDescriptor<T> parameter) throws ParameterNotFoundException
    Returns the value of the parameter identified by the given descriptor, or `null` if none. This method uses the following information from the given `parameter` descriptor:
    - The most appropriate name or alias to use for searching in this `ParameterValueGroup`, chosen as below:
      - a name or alias defined by the same authority, if any;
      - an arbitrary name or alias otherwise.
    - The default value to return if there is no value associated to the above-cited name or alias.
    - The unit of measurement (if any) of numerical value to return.
    - The type of value to return.
    This method can be useful when the `ParameterDescriptor` are known in advance, for example in the implementation of some coordinate operation method. If the caller has no such `ParameterDescriptor` at hand, then the `parameter(String)` method is probably more convenient.
    Type Parameters:
      `T` - the type of the parameter value.
    Parameters:
      `parameter` - the name or alias of the parameter to look for, together with the desired type and unit of value.
    Returns:
      the requested parameter value if it exists, or the default value otherwise (which may be `null`).
    Throws:
      `ParameterNotFoundException` - if the given `parameter` name or alias is not legal for this group.
      `UnconvertibleObjectException` - if the parameter value cannot be converted to the expected type.
    Since:
      0.6
    See Also:
      - `getMandatoryValue(ParameterDescriptor)`
      - `getOrCreate(ParameterDescriptor)`
      - `DefaultParameterValueGroup​.parameter(String)`
      - `DefaultParameterValue​.getValue()`

  - ### getMandatoryValue

    public <T> T getMandatoryValue(ParameterDescriptor<T> parameter) throws ParameterNotFoundException
    Returns the value of the parameter identified by the given descriptor, or throws an exception if none. The default implementation performs the same work as `getValue(ParameterDescriptor)` and verifies that the returned value is non-null.
    Type Parameters:
      `T` - the type of the parameter value.
    Parameters:
      `parameter` - the name or alias of the parameter to look for, together with the desired type and unit of value.
    Returns:
      the requested parameter value if it exists, or the default value otherwise provided that it is not `null`.
    Throws:
      `ParameterNotFoundException` - if the given `parameter` name or alias is not legal for this group.
      `IllegalStateException` - if the value is not defined and there is no default value.
    Since:
      0.7
    See Also:
      - `getValue(ParameterDescriptor)`
      - `getOrCreate(ParameterDescriptor)`

  - ### booleanValue

    public boolean booleanValue(ParameterDescriptor<Boolean> parameter) throws ParameterNotFoundException
    Returns the boolean value of the parameter identified by the given descriptor. See `getValue(ParameterDescriptor)` for more information about how this method uses the given `parameter` argument.
    Parameters:
      `parameter` - the name or alias of the parameter to look for.
    Returns:
      the requested parameter value if it exists, or the non-null default value otherwise.
    Throws:
      `ParameterNotFoundException` - if the given `parameter` name or alias is not legal for this group.
      `IllegalStateException` - if the value is not defined and there is no default value.
    Since:
      0.6
    See Also:
      - `DefaultParameterValue​.booleanValue()`

  - ### intValue

    public int intValue(ParameterDescriptor<? extends Number> parameter) throws ParameterNotFoundException
    Returns the integer value of the parameter identified by the given descriptor. See `getValue(ParameterDescriptor)` for more information about how this method uses the given `parameter` argument.
    Parameters:
      `parameter` - the name or alias of the parameter to look for.
    Returns:
      the requested parameter value if it exists, or the non-null default value otherwise.
    Throws:
      `ParameterNotFoundException` - if the given `parameter` name or alias is not legal for this group.
      `IllegalStateException` - if the value is not defined and there is no default value.
    Since:
      0.6
    See Also:
      - `DefaultParameterValue​.intValue()`

  - ### intValueList

    public int[] intValueList(ParameterDescriptor<int[]> parameter) throws ParameterNotFoundException
    Returns the integer values of the parameter identified by the given descriptor. See `getValue(ParameterDescriptor)` for more information about how this method uses the given `parameter` argument.
    Parameters:
      `parameter` - the name or alias of the parameter to look for.
    Returns:
      the requested parameter values if they exist, or the non-null default value otherwise.
    Throws:
      `ParameterNotFoundException` - if the given `parameter` name or alias is not legal for this group.
      `IllegalStateException` - if the value is not defined and there is no default value.
    Since:
      0.6
    See Also:
      - `DefaultParameterValue​.intValueList()`

  - ### doubleValue

    public double doubleValue(ParameterDescriptor<? extends Number> parameter) throws ParameterNotFoundException
    Returns the floating point value of the parameter identified by the given descriptor. See `getValue(ParameterDescriptor)` for more information about how this method uses the given `parameter` argument.

    If the given descriptor supplies a unit of measurement, then the returned value will be converted into that unit.

    Parameters:
      `parameter` - the name or alias of the parameter to look for.
    Returns:
      the requested parameter value if it exists, or the non-null default value otherwise.
    Throws:
      `ParameterNotFoundException` - if the given `parameter` name or alias is not legal for this group.
      `IllegalStateException` - if the value is not defined and there is no default value.
    Since:
      0.6
    See Also:
      - `DefaultParameterValue​.doubleValue(Unit)`

  - ### doubleValue

    public double doubleValue(ParameterDescriptor<? extends Number> parameter, Unit<?> unit) throws ParameterNotFoundException
    Returns the floating point value of the parameter identified by the given descriptor, converted to the given unit of measurement. See `getValue(ParameterDescriptor)` for more information about how this method uses the given `parameter` argument.
    Parameters:
      `parameter` - the name or alias of the parameter to look for.
      `unit` - the desired unit of measurement.
    Returns:
      the requested parameter value if it exists, or the non-null default value otherwise.
    Throws:
      `ParameterNotFoundException` - if the given `parameter` name or alias is not legal for this group.
      `IllegalStateException` - if the value is not defined and there is no default value.
      `IllegalArgumentException` - if the specified unit is invalid for the parameter.
    Since:
      1.3
    See Also:
      - `DefaultParameterValue​.doubleValue(Unit)`

  - ### doubleValueList

    public double[] doubleValueList(ParameterDescriptor<double[]> parameter) throws ParameterNotFoundException
    Returns the floating point values of the parameter identified by the given descriptor. See `getValue(ParameterDescriptor)` for more information about how this method uses the given `parameter` argument.

    If the given descriptor supplies a unit of measurement, then the returned values will be converted into that unit.

    Parameters:
      `parameter` - the name or alias of the parameter to look for.
    Returns:
      the requested parameter values if they exists, or the non-null default value otherwise.
    Throws:
      `ParameterNotFoundException` - if the given `parameter` name or alias is not legal for this group.
      `IllegalStateException` - if the value is not defined and there is no default value.
    Since:
      0.6
    See Also:
      - `DefaultParameterValue​.doubleValueList(Unit)`

  - ### stringValue

    public String stringValue(ParameterDescriptor<? extends CharSequence> parameter) throws ParameterNotFoundException
    Returns the string value of the parameter identified by the given descriptor. See `getValue(ParameterDescriptor)` for more information about how this method uses the given `parameter` argument.
    Parameters:
      `parameter` - the name or alias of the parameter to look for.
    Returns:
      the requested parameter value if it exists, or the non-null default value otherwise.
    Throws:
      `ParameterNotFoundException` - if the given `parameter` name or alias is not legal for this group.
      `IllegalStateException` - if the value is not defined and there is no default value.
    Since:
      0.6
    See Also:
      - `DefaultParameterValue​.stringValue()`

  - ### getOrCreate

    public <T> ParameterValue<T> getOrCreate(ParameterDescriptor<T> parameter) throws ParameterNotFoundException
    Returns the parameter identified by the given descriptor. If the identified parameter is optional and not yet created, then it will be created now.

    The default implementation is equivalent to:

        return cast(parameter(name), parameter.getValueClass());

    where `name` is a `parameter` name or alias chosen by the same algorithm as `getValue(ParameterDescriptor)`.
    Type Parameters:
      `T` - the type of the parameter value.
    Parameters:
      `parameter` - the parameter to look for.
    Returns:
      the requested parameter instance.
    Throws:
      `ParameterNotFoundException` - if the given `parameter` name or alias is not legal for this group.
    Since:
      0.6
    See Also:
      - `getValue(ParameterDescriptor)`
      - `getMandatoryValue(ParameterDescriptor)`
      - `DefaultParameterValueGroup​.parameter(String)`

  - ### clone

    public Parameters clone()
    Returns a copy of this group of parameter values. The default implementation performs a shallow copy, but subclasses are encouraged to perform a deep copy.
    Specified by:
      `clone` in interface `GeneralParameterValue`
    Specified by:
      `clone` in interface `ParameterValueGroup`
    Overrides:
      `clone` in class `Object`
    Returns:
      a copy of this group of parameter values.
    See Also:
      - `copy(ParameterValueGroup, ParameterValueGroup)`

  - ### copy

    public static void copy(ParameterValueGroup values, ParameterValueGroup destination) throws InvalidParameterNameException, InvalidParameterValueException
    Copies the values of a parameter group into another parameter group. All values in the `source` group shall be valid for the `destination` group, but the `destination` may have more parameters. Sub-groups are copied recursively.

    A typical usage of this method is for transferring values from an arbitrary implementation to some specific implementation, or to a parameter group using a different but compatible descriptor.

    Parameters:
      `values` - the parameter values to copy.
      `destination` - where to copy the values.
    Throws:
      `InvalidParameterNameException` - if a `source` parameter name is unknown to the `destination`.
      `InvalidParameterValueException` - if the value of a `source` parameter is invalid for the `destination`.
    Since:
      0.5
    See Also:
      - `clone()`

  - ### toString

    public String toString()
    Returns a string representation of this group. The default implementation delegates to `ParameterFormat`.

    This method is for information purpose only and may change in future SIS version.

    Overrides:
      `toString` in class `Object`
    Since:
      0.7

  - ### print

    @Debug public void print()
    Prints a string representation of this group to the standard output stream. If a console is attached to the running JVM (i.e. if the application is run from the command-line and the output is not redirected to a file) and if Apache SIS thinks that the console supports the ANSI escape codes (a.k.a. X3.64), then a syntax coloring will be applied.

    This is a convenience method for debugging purpose and for console applications.

    Specified by:
      `print` in interface `Printable`
    Since:
      0.7