Package org.apache.sis.io.wkt

# Class Formatter

Object
Formatter

All Implemented Interfaces:
  `Localized`

public class Formatter extends Object implements Localized
Provides support methods for formatting a Well Known Text (WKT).

`Formatter` instances are created by `WKTFormat` and given to the `FormattableObject​.formatTo(Formatter)` method of the object to format. `Formatter` provides the following services:

- A series of `append(…)` methods to be invoked by the `formatTo(Formatter)` implementations.
- Contextual information. In particular, the contextual units depend on the enclosing WKT element.
- A flag for declaring the object unformattable.

Since:
  0.4
See Also:
  - WKT 2 specification
  - Legacy WKT 1

Defined in the `sis-referencing` module

- ## Constructor Summary

  Constructors
  Constructor
  Description
  `Formatter()`
  Creates a new formatter instance with the default configuration.
  `Formatter(Convention convention, Symbols symbols, int indentation)`
  Creates a new formatter instance with the specified convention, symbols and indentation.

- ## Method Summary

  Modifier and Type
  Method
  Description
  `<Q extends Quantity<Q>>
  Unit<Q>`
  `addContextualUnit(Unit<Q> unit)`
  Adds a unit to use for the next measurements of the quantity `Q`.
  `void`
  `append(boolean value)`
  Appends a boolean value.
  `void`
  `append(double number)`
  Appends an floating point value.
  `void`
  `append(long number)`
  Appends an integer value.
  `void`
  `append(String text, ElementKind type)`
  Appends a character string between quotes.
  `void`
  `append(Date date)`
  Appends a date.
  `void`
  `append(Unit<?> unit)`
  Appends a unit in a `Unit[…]` element or one of the specialized elements.
  `void`
  `append(FormattableObject object)`
  Appends the given `FormattableObject`.
  `void`
  `append(Vector[] rows, int... fractionDigits)`
  Appends rows of numbers.
  `void`
  `append(GeographicBoundingBox bbox, int fractionDigits)`
  Appends the given geographic bounding box in a `BBOX[…]` element.
  `void`
  `append(MathTransform transform)`
  Appends the given math transform, typically (but not necessarily) in a `PARAM_MT[…]` element.
  `void`
  `append(CodeList<?> code)`
  Appends an enumeration or code list value.
  `void`
  `appendAny(Object value)`
  Appends an object or an array of objects.
  `String`
  `delegateTo(Object other)`
  Delegates the formatting to another `FormattableObject` implementation.
  `final Convention`
  `getConvention()`
  Returns the convention to use for formatting the WKT.
  `FormattableObject`
  `getEnclosingElement(int depth)`
  Returns the enclosing WKT element, or `null` if element being formatted is the root.
  `final Locale`
  `getLocale()`
  Returns the locale to use for localizing `InternationalString` instances.
  `final Citation`
  `getNameAuthority()`
  Returns the preferred authority for choosing the projection and parameter names.
  `final Transliterator`
  `getTransliterator()`
  Returns a mapper between Java character sequences and the characters to write in WKT.
  `boolean`
  `hasContextualUnit(int depth)`
  Returns `true` if the element at the given depth specified a contextual unit.
  `void`
  `indent(int amount)`
  Increases or decreases the indentation.
  `boolean`
  `isInvalidWKT()`
  Returns `true` if the WKT written by this formatter is not strictly compliant to the WKT specification.
  `void`
  `newLine()`
  Request a line separator before the next element to format.
  `void`
  `restoreContextualUnit(Unit<?> unit, Unit<?> previous)`
  Restores the contextual unit to its previous state before the call to `addContextualUnit(Unit)`.
  `void`
  `setInvalidWKT(Class<?> unformattable, Exception cause)`
  Marks the current WKT representation of the given class as not strictly compliant with the WKT specification.
  `void`
  `setInvalidWKT(IdentifiedObject unformattable, Exception cause)`
  Marks the current WKT representation of the given object as not strictly compliant with the WKT specification.
  `String`
  `shortOrLong(String shortKeyword, String longKeyword)`
  Selects a short or long keyword depending on the `KeywordStyle` value.
  `<Q extends Quantity<Q>>
  Unit<Q>`
  `toContextualUnit(Unit<Q> unit)`
  Returns the unit to use instead of the given one, or `unit` if there is no replacement.
  `String`
  `toString()`
  Returns a string representation of this formatter for debugging purpose.
  `String`
  `toWKT()`
  Returns the WKT formatted by this object.

  ### Methods inherited from class Object

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

- ## Constructor Details

  - ### Formatter

    public Formatter()
    Creates a new formatter instance with the default configuration.

  - ### Formatter

    public Formatter(Convention convention, Symbols symbols, int indentation)
    Creates a new formatter instance with the specified convention, symbols and indentation.
    Parameters:
      `convention` - the convention to use.
      `symbols` - the symbols.
      `indentation` - the amount of spaces to use in indentation for WKT formatting, or `WKTFormat​.SINGLE_LINE` for formatting the whole WKT on a single line.

- ## Method Details

  - ### getConvention

    public final Convention getConvention()
    Returns the convention to use for formatting the WKT. The default is `Convention​.WKT2`.
    Returns:
      the convention (never `null`).
    See Also:
      - `WKTFormat​.setConvention(Convention)`
      - `FormattableObject​.toString(Convention)`

  - ### getTransliterator

    public final Transliterator getTransliterator()
    Returns a mapper between Java character sequences and the characters to write in WKT. The intent is to specify how to write characters that are not allowed in WKT strings according ISO 19162 specification. Return values can be:
    - `Transliterator​.DEFAULT` for performing replacements like "é" → "e" in all WKT elements except `REMARKS["…"]`.
    - `Transliterator​.IDENTITY` for preserving non-ASCII characters.
    - Any other user-supplied mapping.
    Returns:
      the mapper between Java character sequences and the characters to write in WKT.
    Since:
      0.6
    See Also:
      - `WKTFormat​.setTransliterator(Transliterator)`

  - ### getNameAuthority

    public final Citation getNameAuthority()
    Returns the preferred authority for choosing the projection and parameter names.

    The preferred authority can be set by the `WKTFormat​.setNameAuthority(Citation)` method. This is not necessarily the authority who created the object to format.

    Example: The EPSG name of the `EPSG:6326` datum is "World Geodetic System 1984". However if the preferred authority is OGC, then the formatted datum name will rather look like "WGS84" (the exact string depends on the object aliases).
    Returns:
      the authority for projection and parameter names.
    See Also:
      - `WKTFormat​.getNameAuthority()`
      - `IdentifiedObjects​.getName(IdentifiedObject, Citation)`

  - ### getLocale

    public final Locale getLocale()
    Returns the locale to use for localizing `InternationalString` instances. This is not the locale for formatting dates and numbers.
    Specified by:
      `getLocale` in interface `Localized`
    Returns:
      the locale to use for localizing international strings.

  - ### newLine

    public void newLine()
    Request a line separator before the next element to format. Invoking this method before any `append(…)` method call will cause the next element to appear on the next line.

    This method has no effect in any of the following cases:

    - This method has already been invoked before the next `append(…)`.
    - The indentation is `WKTFormat​.SINGLE_LINE`.

  - ### indent

    public void indent(int amount)
    Increases or decreases the indentation. A value of `+1` increases the indentation by the amount of spaces specified at construction time, and a value of `-1` reduces it by the same amount.
    Parameters:
      `amount` - +1 for increasing the indentation, or -1 for decreasing it, or 0 for no-op.

  - ### shortOrLong

    public String shortOrLong(String shortKeyword, String longKeyword)
    Selects a short or long keyword depending on the `KeywordStyle` value. This method can be used by `FormattableObject​.formatTo(Formatter)` implementations for choosing the return value.
    Parameters:
      `shortKeyword` - the keyword to return if the style is `KeywordStyle​.SHORT`.
      `longKeyword` - the keyword to return if the style is `KeywordStyle​.LONG`.
    Returns:
      the short or long keyword depending on the keyword style setting.
    Since:
      0.6
    See Also:
      - `WKTFormat​.setKeywordStyle(KeywordStyle)`

  - ### append

    public void append(FormattableObject object)
    Appends the given `FormattableObject`. This method performs the following steps:
    - Invoke `object.formatTo(this)`.
    - Prepend the keyword returned by the above method call (e.g. `"GEOCS"`).
    - If the given object is an instance of `IdentifiedObject`, then append complementary information:

    > Complementary WKT elements
    > WKT 2 element | WKT 1 element | For types
    > --- | --- | ---
    > `Anchor[…]` |  | `Datum`
    > `Scope[…]` |  | `ReferenceSystem`, `Datum`, `CoordinateOperation`
    > `Area[…]` |  | `ReferenceSystem`, `Datum`, `CoordinateOperation`
    > `BBox[…]` |  | `ReferenceSystem`, `Datum`, `CoordinateOperation`
    > `VerticalExtent[…]` |  | `ReferenceSystem`, `Datum`, `CoordinateOperation`
    > `TimeExtent[…]` |  | `ReferenceSystem`, `Datum`, `CoordinateOperation`
    > `Id[…]` | `Authority[…]` | `IdentifiedObject`
    > `Remarks[…]` |  | `ReferenceSystem`, `CoordinateOperation`

    Parameters:
      `object` - the formattable object to append to the WKT, or `null` if none.

  - ### append

    public void append(GeographicBoundingBox bbox, int fractionDigits)
    Appends the given geographic bounding box in a `BBOX[…]` element. Longitude and latitude values will be formatted in decimal degrees. Longitudes are relative to the Greenwich meridian, with values increasing toward East. Latitudes values are increasing toward North.

    #### Numerical precision

    The ISO 19162 standards recommends to format those values with only 2 decimal digits. This is because `GeographicBoundingBox` does not specify the datum, so this box is an approximated information only.
    Parameters:
      `bbox` - the geographic bounding box to append to the WKT, or `null`.
      `fractionDigits` - the number of fraction digits to use. The recommended value is 2.

  - ### append

    public void append(MathTransform transform)
    Appends the given math transform, typically (but not necessarily) in a `PARAM_MT[…]` element.
    Parameters:
      `transform` - the transform object to append to the WKT, or `null` if none.

  - ### append

    public void append(String text, ElementKind type)
    Appends a character string between quotes. The element separator will be written before the text if needed.
    Parameters:
      `text` - the string to format to the WKT, or `null` if none.
      `type` - the key of the colors to apply if syntax coloring is enabled, or `null` if none.

  - ### append

    public void append(CodeList<?> code)
    Appends an enumeration or code list value. The element separator will be written before the code list if needed.

    For the WKT 2 format, this method uses the ISO name if available (for example `"northEast"`). For the WKT 1 format, this method uses the programmatic name instead (for example `"NORTH_EAST"`).

    Parameters:
      `code` - the code list to append to the WKT, or `null` if none.

  - ### append

    public void append(Date date)
    Appends a date. The element separator will be written before the date if needed.
    Parameters:
      `date` - the date to append to the WKT, or `null` if none.

  - ### append

    public void append(boolean value)
    Appends a boolean value. The element separator will be written before the boolean if needed.
    Parameters:
      `value` - the boolean to append to the WKT.

  - ### append

    public void append(long number)
    Appends an integer value. The element separator will be written before the number if needed.
    Parameters:
      `number` - the integer to append to the WKT.

  - ### append

    public void append(double number)
    Appends an floating point value. The element separator will be written before the number if needed.
    Parameters:
      `number` - the floating point value to append to the WKT.

  - ### append

    public void append(Vector[] rows, int... fractionDigits)
    Appends rows of numbers. Each number is separated by a space, and each row is separated by a comma. Rows usually have all the same length, but this is not mandatory. This method can be used for formatting geometries or matrix.
    Parameters:
      `rows` - the rows to append, or `null` if none.
      `fractionDigits` - the number of fraction digits for each column in a row, or `null` for default. A precision can be specified for each column because those columns are often different dimensions of a Coordinate Reference System (CRS), each with their own units of measurement. If a row contains more numbers than `fractionDigits​.length`, then the last value in this array is repeated for all remaining row numbers.
    Since:
      1.0

  - ### append

    public void append(Unit<?> unit)
    Appends a unit in a `Unit[…]` element or one of the specialized elements. Specialized elements are `AngleUnit`, `LengthUnit`, `ScaleUnit`, `ParametricUnit` and `TimeUnit`. By default, specialized unit keywords are used with the WKT 2 convention.
    Example: `append(Units​.KILOMETRE)` will append "`LengthUnit["km", 1000]`" to the WKT.
    Parameters:
      `unit` - the unit to append to the WKT, or `null` if none.
    See Also:
      - WKT 2 specification §7.4

  - ### appendAny

    public void appendAny(Object value)
    Appends an object or an array of objects. This method performs the following choices:
    - If the given value is `null`, then this method appends the "`null`" string (without quotes).
    - Otherwise if the given value is an array, then this method appends the opening sequence symbol, formats all elements by invoking this method recursively, then appends the closing sequence symbol.
    - Otherwise if the value type is assignable to the argument type of one of the `append(…)` methods in this class, then the formatting will be delegated to that method.
    - Otherwise the given value is appended as a quoted text with its `toString()` representation.
    Parameters:
      `value` - the value to append to the WKT, or `null`.

  - ### delegateTo

    public String delegateTo(Object other) throws UnformattableObjectException
    Delegates the formatting to another `FormattableObject` implementation. Invoking this method is equivalent to first verifying the `other` class, then delegating as below:

    >     return other.formatTo(this);

    This method is useful for `FormattableObject` which are wrapper around another object. It allows to delegate the WKT formatting to the wrapped object.
    Parameters:
      `other` - the object to format with this formatter.
    Returns:
      the value returned by `FormattableObject​.formatTo(Formatter)`.
    Throws:
      `UnformattableObjectException`
    Since:
      0.5

  - ### getEnclosingElement

    public FormattableObject getEnclosingElement(int depth)
    Returns the enclosing WKT element, or `null` if element being formatted is the root. This method can be invoked by child elements having some aspects that depend on the enclosing element.
    Parameters:
      `depth` - 1 for the immediate parent, 2 for the parent of the parent, etc.
    Returns:
      the parent element at the given depth, or `null`.

  - ### hasContextualUnit

    public boolean hasContextualUnit(int depth)
    Returns `true` if the element at the given depth specified a contextual unit. This method returns `true` if the formattable object given by `getEnclosingElement(depth)` has invoked `addContextualUnit(Unit)` with a non-null unit at least once.
    Note: The main purpose of this method is to allow `AXIS[…]` elements to determine if they should inherit the unit specified by the enclosing CRS, or if they should specify their unit explicitly.
    Parameters:
      `depth` - 1 for the immediate parent, 2 for the parent of the parent, etc.
    Returns:
      whether the parent element at the given depth has invoked `addContextualUnit(…)` at least once.

  - ### addContextualUnit

    public <Q extends Quantity<Q>> Unit<Q> addContextualUnit(Unit<Q> unit)
    Adds a unit to use for the next measurements of the quantity `Q`. The given unit will apply to all WKT elements containing a value of quantity `Q` without their own `UNIT[…]` element, until the `restoreContextualUnit(Unit, Unit)` method is invoked.

    If the given unit is null, then this method does nothing and returns `null`.

    #### Special case

    If the WKT conventions are `WKT1_COMMON_UNITS`, then this method ignores the given unit and returns `null`. See `Convention​.WKT1_COMMON_UNITS` javadoc for more information.
    Type Parameters:
      `Q` - the unit quantity.
    Parameters:
      `unit` - the contextual unit to add, or `null` if none.
    Returns:
      the previous contextual unit for quantity `Q`, or `null` if none.

  - ### restoreContextualUnit

    public void restoreContextualUnit(Unit<?> unit, Unit<?> previous)
    Restores the contextual unit to its previous state before the call to `addContextualUnit(Unit)`. This method is used in the following pattern:

    >     final Unit<?> previous = formatter.addContextualUnit(unit);
    >     // ... format some WKT elements here.
    >     formatter.restoreContextualUnit(unit, previous);

    Parameters:
      `unit` - the value given in argument to `addContextualUnit(unit)` (can be `null`).
      `previous` - the value returned by `addContextualUnit(unit)` (can be `null`).
    Throws:
      `IllegalStateException` - if this method has not been invoked in the pattern documented above.
    Since:
      0.6

  - ### toContextualUnit

    public <Q extends Quantity<Q>> Unit<Q> toContextualUnit(Unit<Q> unit)
    Returns the unit to use instead of the given one, or `unit` if there is no replacement. This method searches for a unit specified by `addContextualUnit(Unit)` which is compatible with the given unit.
    Type Parameters:
      `Q` - the quantity of the unit.
    Parameters:
      `unit` - the unit to replace by the contextual unit, or `null`.
    Returns:
      a contextual unit compatible with the given unit, or `unit` (which may be null) if no contextual unit has been found.

  - ### isInvalidWKT

    public boolean isInvalidWKT()
    Returns `true` if the WKT written by this formatter is not strictly compliant to the WKT specification. This method returns `true` if `setInvalidWKT(IdentifiedObject, Exception)` has been invoked at least once. The action to take regarding invalid WKT is caller-dependent. For example `FormattableObject​.toString()` will accepts loose WKT formatting and ignore this flag, while `FormattableObject​.toWKT()` requires strict WKT formatting and will thrown an exception if this flag is set.
    Returns:
      `true` if the WKT is invalid.

  - ### setInvalidWKT

    public void setInvalidWKT(IdentifiedObject unformattable, Exception cause)
    Marks the current WKT representation of the given object as not strictly compliant with the WKT specification. This method can be invoked by implementations of `FormattableObject​.formatTo(Formatter)` when the object to format is more complex than what the WKT specification allows. Applications can test `isInvalidWKT()` later for checking WKT validity.
    Parameters:
      `unformattable` - the object that can not be formatted,
      `cause` - the cause for the failure to format, or `null` if the cause is not an exception.

  - ### setInvalidWKT

    public void setInvalidWKT(Class<?> unformattable, Exception cause)
    Marks the current WKT representation of the given class as not strictly compliant with the WKT specification. This method can be used as an alternative to `setInvalidWKT(IdentifiedObject, Exception)` when the problematic object is not an instance of `IdentifiedObject`.
    Parameters:
      `unformattable` - the class of the object that can not be formatted,
      `cause` - the cause for the failure to format, or `null` if the cause is not an exception.

  - ### toWKT

    public String toWKT()
    Returns the WKT formatted by this object.
    Returns:
      the WKT formatted by this formatter.

  - ### toString

    public String toString()
    Returns a string representation of this formatter for debugging purpose.
    Overrides:
      `toString` in class `Object`
    Returns:
      a string representation of this formatter.