Class RangeFormat

java.lang.Object
java.text.Format
org.apache.sis.measure.RangeFormat
All Implemented Interfaces:
Serializable, Cloneable, Localized
Direct Known Subclasses:
SampleRangeFormat

public class RangeFormat extends Format implements Localized
Parses and formats Range instances according the given locale. This class complies to the format described in the ISO 31-11 standard, except that the minimal and maximal values are separated by the "" character instead of coma. More specifically, the format is defined as below:
  • If the range is empty, then the range is represented by "{}".
  • Otherwise if the minimal value is equal to the maximal value, then that single value is formatted inside braces as in "{value}".
  • Otherwise the minimal and maximal values are formatted inside bracket or parenthesis, depending on whether each endpoint is inclusive or exclusive:
    • "[min … max]" if both endpoints are inclusive (closed interval);
    • "(min … max)" if both endpoints are exclusive (open interval);
    • or a mix of both styles if an endpoint is inclusive while the other is exclusive.
    The "" symbol is used in place of min or max for unbounded ranges.
If the range to format is an instance of MeasurementRange, then the unit of measurement is appended except for empty ranges.

Lenient parsing

At parsing time, the above formatting rules are relaxed as below:
  • Empty ranges can be represented by "[]"or "()" in addition to the standard "{}".
  • The braces are optional for singleton values, i.e. "value" is accepted as well as "{value}".

Range type and type of range elements

The kind of ranges created by the parse(…) methods is determined by the type of range elements:
  • If the elements type is assignable to Date, then the parse(…) methods will create Range<Date> objects.
  • If the elements type is assignable to Number, then:
    • If the text to parse contains a unit of measurement, then the parse(…) methods will create MeasurementRange objects.
    • Otherwise the parse(…) methods will create NumberRange objects.
Since:
0.3
Version:
1.1
See Also:
  • Field Details

    • serialVersionUID

      private static final long serialVersionUID
      For cross-version compatibility.
      See Also:
    • MIN_VALUE_FIELD

      private static final int MIN_VALUE_FIELD
      The constant value for FieldPosition which designate the minimal value.
      See Also:
    • MAX_VALUE_FIELD

      private static final int MAX_VALUE_FIELD
      The constant value for FieldPosition which designate the maximal value.
      See Also:
    • UNIT_FIELD

      private static final int UNIT_FIELD
      The constant value for FieldPosition which designate the unit of measurement.
      See Also:
    • openSet

      private final int openSet
      The character opening an empty range or a range containing only one element. The default value is '{'.
    • openInclusive

      private final int openInclusive
      The character opening a range in which the minimal value is inclusive. The default value is '['.
    • openExclusive

      private final int openExclusive
      The character opening a range in which the minimal value is exclusive. The default value is '('. Note that the ']' character is also sometimes used.
    • openExclusiveAlt

      private final int openExclusiveAlt
      An alternative character opening a range in which the minimal value is exclusive. This character is not used for formatting (only openExclusive is used), but is accepted during parsing. The default value is ']'.
    • closeSet

      private final int closeSet
      The character closing an empty range or a range containing only one element. The default value is '}'.
    • closeInclusive

      private final int closeInclusive
      The character closing a range in which the maximal value is inclusive. The default value is ']'.
    • closeExclusive

      private final int closeExclusive
      The character closing a range in which the maximal value is exclusive. The default value is ')'. Note that the '[' character is also sometimes used.
    • closeExclusiveAlt

      private final int closeExclusiveAlt
      An alternative character closing a range in which the maximal value is exclusive. This character is not used for formatting (only closeExclusive is used), but is accepted during parsing. The default value is '['.
    • separator

      private final String separator
      The string to use as a separator between minimal and maximal value, not including whitespaces. The default value is "…" (Unicode 2026).
    • minusSign

      private final char minusSign
      Symbols used by this format, inferred from DecimalFormatSymbols.
    • infinity

      private final String infinity
      Symbols used by this format, inferred from DecimalFormatSymbols.
    • alternateForm

      private boolean alternateForm
      true if RangeFormat shall use the alternate form at formatting time. This flag as no effect on parsing, since both forms are accepted.
      See Also:
    • elementType

      protected final Class<?> elementType
      The type of the range components. Valid types are Number, Angle, Date or a subclass of those types. This value determines the kind of range to be created by the parse method:
      • NumberRange<?> if the element type is assignable to Number or Angle.
      • Range<Date> if the element type is assignable to Date.
      See Also:
    • elementFormat

      protected final Format elementFormat
      The format to use for parsing and formatting the range components. The format is determined from the element type:
    • unitFormat

      protected final UnitFormat unitFormat
      The format for unit of measurement, or null if none. This is non-null if and only if elementType is assignable to Number but not to Angle.
    • insertSpaceBeforeUnit

      private transient Map<javax.measure.Unit<?>,Boolean> insertSpaceBeforeUnit
      Whether we should insert a space between the bracket and the unit symbol.
      See Also:
    • locale

      private Locale locale
      The locale for error message, or null for the default.
  • Constructor Details

    • RangeFormat

      public RangeFormat()
      Creates a new format for parsing and formatting number ranges using the default locale.
    • RangeFormat

      public RangeFormat(Locale locale)
      Creates a new format for parsing and formatting number ranges using the given locale.
      Parameters:
      locale - the locale for parsing and formatting range components.
    • RangeFormat

      public RangeFormat(Locale locale, TimeZone timezone)
      Creates a new format for parsing and formatting Range<Date> using the given locale and timezone.
      Parameters:
      locale - the locale for parsing and formatting range components.
      timezone - the timezone for the dates to be formatted.
    • RangeFormat

      public RangeFormat(Locale locale, Class<?> elementType) throws IllegalArgumentException
      Creates a new format for parsing and formatting ranges of the given element type using the given locale. The element type is typically Date.class or some subclass of Number.class.
      Parameters:
      locale - the locale for parsing and formatting range components.
      elementType - the type of range components.
      Throws:
      IllegalArgumentException - if the given type is not recognized by this constructor.
  • Method Details

    • isOpen

      private boolean isOpen(int c)
      Returns true if the given character is any of the opening bracket characters.
    • isClose

      private boolean isClose(int c)
      Returns true if the given character is any of the closing bracket characters.
    • getLocale

      public Locale getLocale()
      Returns this formatter locale. This is the locale specified at construction time if any, or the default locale at construction time otherwise.
      Specified by:
      getLocale in interface Localized
      Returns:
      this formatter locale (never null).
      Since:
      1.0
    • getElementPattern

      public String getElementPattern(boolean localized)
      Returns the pattern used by elementFormat for formatting the minimum and maximum values. If the element format does not use pattern, returns null.
      Parameters:
      localized - true for returning the localized pattern, or false for the unlocalized one.
      Returns:
      the pattern, or null if the elementFormat doesn't use pattern.
      See Also:
    • setElementPattern

      public void setElementPattern(String pattern, boolean localized)
      Sets the pattern to be used by elementFormat for formatting the minimum and maximum values.
      Parameters:
      pattern - the new pattern.
      localized - true if the given pattern is localized.
      Throws:
      IllegalStateException - if the elementFormat does not use pattern.
      See Also:
    • isAlternateForm

      public boolean isAlternateForm()
      Returns true if this RangeFormat shall use the alternate form at formatting time. The alternate form expresses open intervals like ]a…b[ instead of (a…b).

      This flag has no effect on parsing, since the parser accepts both forms.

      Returns:
      true for using the alternate format instead of the default format.
    • setAlternateForm

      public void setAlternateForm(boolean alternateForm)
      Sets whether this RangeFormat shall use the alternate form at formatting time. The alternate form expresses open intervals like ]a…b[ instead of (a…b).
      Parameters:
      alternateForm - true for using the alternate format, or false for using the default format.
    • insertSpaceBeforeUnit

      private boolean insertSpaceBeforeUnit(javax.measure.Unit<?> unit)
      Returns whether we should insert a space between the bracket and the unit symbol. We cache the result because checking for this condition forces us to format the unit symbol twice.
    • getField

      private static int getField(FieldPosition position)
      Returns the *_FIELD constant for the given field position, or -1 if none.
    • cast

      private static Range<?> cast(Object range) throws IllegalArgumentException
      Casts the given object to a Range, or throws an IllegalArgumentException if the given object is not a Range instance. This is used for validating argument of Object type in formatting methods.
      Throws:
      IllegalArgumentException
    • format

      public StringBuffer format(Object range, StringBuffer toAppendTo, FieldPosition pos)
      Formats a Range and appends the resulting text to a given string buffer. See the class javadoc for a description of the format.
      Specified by:
      format in class Format
      Parameters:
      range - the Range object to format.
      toAppendTo - where the text is to be appended.
      pos - identifies a field in the formatted text, or null if none.
      Returns:
      the string buffer passed in as toAppendTo, with formatted text appended.
      Throws:
      IllegalArgumentException - if this formatter cannot format the given object.
    • format

      private void format(Range<?> range, StringBuffer toAppendTo, FieldPosition pos, FormattedCharacterIterator characterIterator)
      Implementation of the format methods.
      Parameters:
      range - the range to format.
      toAppendTo - where the text is to be appended.
      pos - identifies a field in the formatted text, or null if none.
      characterIterator - the character iterator for which the attributes need to be set, or null if none.
    • formatToCharacterIterator

      public AttributedCharacterIterator formatToCharacterIterator(Object range)
      Formats a range as an attributed character iterator. Callers can iterate and queries the attribute values as in the following example: Alternatively, if the current iterator index is before the start of the minimum value field, then the starting position of that field can be obtained directly by it.getRunLimit(MIN_VALUE). If the current iterator index is inside the minimum value field, then the above method call will rather returns the end of that field. The same strategy works for other all fields too.

      The returned character iterator contains all NumberFormat.Field, DateFormat.Field or AngleFormat.Field attributes in addition to the RangeFormat.Field ones. Consequently, the same character may have more than one attribute.

      In Apache SIS implementation, the returned character iterator also implements the CharSequence interface for convenience.

      Overrides:
      formatToCharacterIterator in class Format
      Parameters:
      range - the Range object to format.
      Returns:
      a character iterator together with the attributes describing the formatted value.
      Throws:
      IllegalArgumentException - if value if not an instance of Range.
    • parseObject

      public Object parseObject(String source) throws ParseException
      Parses text from a string to produce a range. The default implementation delegates to parse(String) with no additional work.
      Overrides:
      parseObject in class Format
      Parameters:
      source - the text, part of which should be parsed.
      Returns:
      a range 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 range. The default implementation delegates to parse(String, ParsePosition) with no additional work.
      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 range parsed from the string, or null in case of error.
    • parse

      public Range<?> parse(String source) throws ParseException
      Parses text from the given string to produce a range. This method use the full string. If there is some unparsed characters after the parsed range, then this method thrown an exception.
      Parameters:
      source - the text to parse.
      Returns:
      the parsed range (never null).
      Throws:
      ParseException - if the given string cannot be fully parsed.
    • parse

      public Range<?> parse(String source, ParsePosition pos)
      Parses text from a string to produce a range. The method attempts to parse text starting at the index given by pos. If parsing succeeds, then the index of pos is updated to the index after the last character used, and the parsed range is returned. If an error occurs, then the index of pos is not changed, the error index of pos is set to the index of the character where the error occurred, and null is returned.
      Parameters:
      source - the text, part of which should be parsed.
      pos - index and error index information as described above.
      Returns:
      a range parsed from the string, or null in case of error.
    • tryParse

      private Range<?> tryParse(String source, ParsePosition pos) throws UnconvertibleObjectException
      Tries to parse the given text. In case of success, the error index is undetermined and need to be reset to -1. In case of failure (including an exception being thrown), the parse index is undetermined and need to be reset to its initial value.
      Throws:
      UnconvertibleObjectException
    • convert

      private Object convert(Object value) throws UnconvertibleObjectException
      Converts the given value to an instance of the elementType type. This method is partially the converse of toFormattable(Object).
      Throws:
      UnconvertibleObjectException
    • toFormattable

      private Object toFormattable(Object value)
      Converts the given object to a type that format(…) method can process. This method is partially the converse of convert(Object).
    • valueOfNil

      private Object valueOfNil()
      Returns a "nil" value. This is used for creating empty ranges.
    • clone

      public RangeFormat clone()
      Returns a clone of this range format.
      Overrides:
      clone in class Format
      Returns:
      a clone of this range format.