Module org.apache.sis.util
Package org.apache.sis.measure

# Class UnitFormat

Object
Format
UnitFormat

All Implemented Interfaces:
  `Serializable`, `Cloneable`, `UnitFormat`, `Localized`

public class UnitFormat extends Format implements UnitFormat, Localized
Parses and formats units of measurement as SI symbols, URI in OGC namespace or other symbols. This class combines in a single class the API from `java​.text` and the API from `javax​.measure​.format`. In addition to the symbols of the Système international (SI), this class is also capable to handle some symbols found in Well Known Text (WKT) definitions or in XML files.

## Parsing authority codes

If a character sequence given to the `parse(CharSequence)` method is of the form `"EPSG:####"`, `"urn:ogc:def:uom:EPSG::####"` or `"http://www​.opengis​.net/def/uom/EPSG/0/####"` (ignoring case and whitespaces around path separators), then `"####"` is parsed as an integer and forwarded to the `Units​.valueOfEPSG(int)` method.

## Note on netCDF unit symbols

In netCDF files, values of "unit" attribute are concatenations of an angular unit with an axis direction, as in `"degrees_east"` or `"degrees_north"`. This class ignores those suffixes and unconditionally returns `Units​.DEGREE` for all axis directions.

## Multi-threading

`UnitFormat` is generally not thread-safe. If units need to be parsed or formatted in different threads, each thread should have its own `UnitFormat` instance.

Since:
  0.8
See Also:
  - `Units​.valueOf(String)`
  - Serialized Form

- ## Nested Class Summary

  Nested Classes
  Modifier and Type
  Class
  Description
  `static enum`
  `UnitFormat​.Style`
  Identify whether unit formatting uses ASCII symbols, Unicode symbols or full localized names.

  ## Nested classes/interfaces inherited from class Format

  `Format​.Field`

- ## Constructor Summary

  Constructors
  Constructor
  Description
  `UnitFormat(Locale locale)`
  Creates a new format for the given locale.

- ## Method Summary

  Modifier and Type
  Method
  Description
  `UnitFormat`
  `clone()`
  Returns a clone of this unit format.
  `StringBuffer`
  `format(Object unit, StringBuffer toAppendTo, FieldPosition pos)`
  Formats the specified unit in the given buffer.
  `String`
  `format(Unit<?> unit)`
  Formats the given unit.
  `Appendable`
  `format(Unit<?> unit, Appendable toAppendTo)`
  Formats the specified unit.
  `Locale`
  `getLocale()`
  Returns the locale used by this `UnitFormat`.
  `UnitFormat​.Style`
  `getStyle()`
  Returns whether unit formatting uses ASCII symbols, Unicode symbols or full localized names.
  `boolean`
  `isLocaleSensitive()`
  Returns whether this `UnitFormat` depends on the `Locale` given at construction time for performing its tasks.
  `void`
  `label(Unit<?> unit, String label)`
  Attaches a label to the specified unit.
  `Unit<?>`
  `parse(CharSequence symbols)`
  Parses the given text as an instance of `Unit`.
  `Unit<?>`
  `parse(CharSequence symbols, ParsePosition position)`
  Parses a portion of the given text as an instance of `Unit`.
  `Object`
  `parseObject(String source)`
  Parses text from a string to produce a unit.
  `Object`
  `parseObject(String source, ParsePosition pos)`
  Parses text from a string to produce a unit, or returns `null` if the parsing failed.
  `void`
  `setLocale(Locale locale)`
  Sets the locale that this `UnitFormat` will use for long names.
  `void`
  `setStyle(UnitFormat​.Style style)`
  Sets whether unit formatting should use ASCII symbols, Unicode symbols or full localized names.

  ### Methods inherited from class Format

  `format, formatToCharacterIterator`

  ### Methods inherited from class Object

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

- ## Constructor Details

  - ### UnitFormat

    public UnitFormat(Locale locale)
    Creates a new format for the given locale.
    Parameters:
      `locale` - the locale to use for parsing and formatting units.

- ## Method Details

  - ### getLocale

    public Locale getLocale()
    Returns the locale used by this `UnitFormat`.
    Specified by:
      `getLocale` in interface `Localized`
    Returns:
      the locale of this `UnitFormat`.

  - ### setLocale

    public void setLocale(Locale locale)
    Sets the locale that this `UnitFormat` will use for long names. For example, a call to `setLocale(Locale​.US)` instructs this formatter to use the “meter” spelling instead of “metre”.
    Parameters:
      `locale` - the new locale for this `UnitFormat`.
    See Also:
      - `UnitServices​.getUnitFormat(String)`

  - ### isLocaleSensitive

    public boolean isLocaleSensitive()
    Returns whether this `UnitFormat` depends on the `Locale` given at construction time for performing its tasks. This method returns `true` if formatting long names (e.g. “metre” or “meter”} and `false` if formatting only the unit symbol (e.g. “m”).
    Specified by:
      `isLocaleSensitive` in interface `UnitFormat`
    Returns:
      `true` if formatting depends on the locale.

  - ### getStyle

    public UnitFormat.Style getStyle()
    Returns whether unit formatting uses ASCII symbols, Unicode symbols or full localized names.
    Returns:
      the style of units formatted by this `UnitFormat` instance.

  - ### setStyle

    public void setStyle(UnitFormat.Style style)
    Sets whether unit formatting should use ASCII symbols, Unicode symbols or full localized names.
    Parameters:
      `style` - the desired style of units.

  - ### label

    public void label(Unit<?> unit, String label)
    Attaches a label to the specified unit. A label can be a substitute to either the unit symbol or the `unit name`, depending on the format style. If the specified label is already associated to another unit, then the previous association is discarded.

    #### Restriction on character set

    Current implementation accepts only letters, subscripts, spaces (including non-breaking spaces but not CR/LF characters), the degree sign (°) and a few other characters like underscore. The set of legal characters may be expanded in future Apache SIS versions, but the following restrictions are likely to remain:
    - The following characters are reserved since they have special meaning in UCUM format, in URI or in Apache SIS parser:

      > " # ( ) * + - . / : = ? [ ] { } ^ ⋅ ∕

    - The symbol cannot begin or end with digits, since such digits would be confused with unit power.
    Specified by:
      `label` in interface `UnitFormat`
    Parameters:
      `unit` - the unit being labeled.
      `label` - the new label for the given unit.
    Throws:
      `IllegalArgumentException` - if the given label is not a valid unit name.

  - ### format

    public Appendable format(Unit<?> unit, Appendable toAppendTo) throws IOException
    Formats the specified unit. This method performs the first of the following actions that can be done.
    1. If a label has been specified for the given unit, then that label is appended unconditionally.
    2. Otherwise if the formatting style is `UnitFormat​.Style​.NAME` and the `Unit​.getName()` method returns a non-null value, then that value is appended. `Unit` instances implemented by Apache SIS are handled in a special way for localizing the name according the locale specified to this format.
    3. Otherwise if the `Unit​.getSymbol()` method returns a non-null value, then that value is appended.
    4. Otherwise a default symbol is created from the entries returned by `Unit​.getBaseUnits()`.
    Specified by:
      `format` in interface `UnitFormat`
    Parameters:
      `unit` - the unit to format.
      `toAppendTo` - where to format the unit.
    Returns:
      the given `toAppendTo` argument, for method calls chaining.
    Throws:
      `IOException` - if an error occurred while writing to the destination.

  - ### format

    public StringBuffer format(Object unit, StringBuffer toAppendTo, FieldPosition pos)
    Formats the specified unit in the given buffer. This method delegates to `format(Unit, Appendable)`.
    Specified by:
      `format` in class `Format`
    Parameters:
      `unit` - the unit to format.
      `toAppendTo` - where to format the unit.
      `pos` - where to store the position of a formatted field, or `null` if none.
    Returns:
      the given `toAppendTo` argument, for method calls chaining.

  - ### format

    public String format(Unit<?> unit)
    Formats the given unit. This method delegates to `format(Unit, Appendable)`.
    Specified by:
      `format` in interface `UnitFormat`
    Parameters:
      `unit` - the unit to format.
    Returns:
      the formatted unit.

  - ### parse

    public Unit<?> parse(CharSequence symbols) throws MeasurementParseException
    Parses the given text as an instance of `Unit`. If the parse completes without reading the entire length of the text, an exception is thrown.

    The parsing is lenient: symbols can be products or quotients of units like “m∕s”, words like “meters per second”, or authority codes like `"urn:ogc:def:uom:EPSG::1026"`. The product operator can be either `'.'` (ASCII) or `'⋅'` (Unicode) character. Exponent after symbol can be decimal digits as in “m2” or a superscript as in “m²”.

    This method differs from `parse(CharSequence, ParsePosition)` in the treatment of white spaces: that method with a `ParsePosition` argument stops parsing at the first white space, while this `parse(…)` method treats white spaces as multiplications. The reason for this difference is that white space is normally not a valid multiplication symbol; it could be followed by a text which is not part of the unit symbol. But in the case of this `parse(CharSequence)` method, the whole `CharSequence` shall be a unit symbol. In such case, white spaces are less ambiguous.

    The default implementation delegates to `parse(symbols, new ParsePosition(0))` and verifies that all non-white characters have been parsed. Units separated by spaces are multiplied; for example "kg m**-2" is parsed as kg/m².

    Specified by:
      `parse` in interface `UnitFormat`
    Parameters:
      `symbols` - the unit symbols or URI to parse.
    Returns:
      the unit parsed from the specified symbols.
    Throws:
      `MeasurementParseException` - if a problem occurred while parsing the given symbols.
    See Also:
      - `Units​.valueOf(String)`

  - ### parse

    public Unit<?> parse(CharSequence symbols, ParsePosition position) throws MeasurementParseException
    Parses a portion of the given text as an instance of `Unit`. Parsing begins at the index given by `ParsePosition​.getIndex()`. After parsing, the above-cited index is updated to the first unparsed character.

    The parsing is lenient: symbols can be products or quotients of units like “m∕s”, words like “meters per second”, or authority codes like `"urn:ogc:def:uom:EPSG::1026"`. The product operator can be either `'.'` (ASCII) or `'⋅'` (Unicode) character. Exponent after symbol can be decimal digits as in “m2” or a superscript as in “m²”.

    Note that contrarily to `parseObject(String, ParsePosition)`, this method never return `null`. If an error occurs at parsing time, an unchecked `MeasurementParseException` is thrown.

    Specified by:
      `parse` in interface `UnitFormat`
    Parameters:
      `symbols` - the unit symbols to parse.
      `position` - on input, index of the first character to parse. On output, index after the last parsed character.
    Returns:
      the unit parsed from the specified symbols.
    Throws:
      `MeasurementParseException` - if a problem occurred while parsing the given symbols.

  - ### parseObject

    public Object parseObject(String source) throws ParseException
    Parses text from a string to produce a unit. The default implementation delegates to `parse(CharSequence)` and wraps the `MeasurementParseException` into a `ParseException` for compatibility with `java​.text` API.
    Overrides:
      `parseObject` in class `Format`
    Parameters:
      `source` - the text, part of which should be parsed.
    Returns:
      a unit parsed from the string.
    Throws:
      `ParseException` - if the given string cannot be fully parsed.

  - ### parseObject

    public Object parseObject(String source, ParsePosition pos)
    Parses text from a string to produce a unit, or returns `null` if the parsing failed. The default implementation delegates to `parse(CharSequence, ParsePosition)` and catches the `MeasurementParseException`.
    Specified by:
      `parseObject` in class `Format`
    Parameters:
      `source` - the text, part of which should be parsed.
      `pos` - index and error index information as described above.
    Returns:
      a unit parsed from the string, or `null` in case of error.

  - ### clone

    public UnitFormat clone()
    Returns a clone of this unit format. The new unit format will be initialized to the same locale and labels than this format.
    Overrides:
      `clone` in class `Format`
    Returns:
      a clone of this unit format.