Class NumberConverter

java.lang.Object
org.apache.fop.complexscripts.util.NumberConverter

public class NumberConverter extends Object

Implementation of Number to String Conversion algorithm specified by XSL Transformations (XSLT) Version 2.0, W3C Recommendation, 23 January 2007.

This algorithm differs from that specified in XSLT 1.0 in the following ways:

  • input numbers are greater than or equal to zero rather than greater than zero;
  • introduces format tokens { w, W, Ww };
  • introduces ordinal parameter to generate ordinal numbers;

Implementation Defaults and Limitations

  • If language parameter is unspecified (null or empty string), then the value of DEFAULT_LANGUAGE is used, which is defined below as "eng" (English).
  • Only English, French, and Spanish word numerals are supported, and only if less than one trillion (1,000,000,000,000).
  • Ordinal word numerals are supported for French and Spanish only when less than or equal to ten (10).

Implementation Notes

  • In order to handle format tokens outside the Unicode BMP, all processing is done in Unicode Scalar Values represented with Integer and Integer[] types. Without affecting behavior, this may be subsequently optimized to use int and int[] types.
  • In order to communicate various sub-parameters, including ordinalization, a features is employed, which consists of comma separated name and optional value tokens, where name and value are separated by an equals '=' sign.
  • Ordinal numbers are selected by specifying a word based format token in combination with a 'ordinal' feature with no value, in which case the features 'male' and 'female' may be used to specify gender for gender sensitive languages. For example, the feature string "ordinal,female" selects female ordinals.

This work was originally authored by Glenn Adams (gadams@apache.org).

  • Field Details

    • LETTER_VALUE_ALPHABETIC

      public static final int LETTER_VALUE_ALPHABETIC
      alphabetical
      See Also:
    • LETTER_VALUE_TRADITIONAL

      public static final int LETTER_VALUE_TRADITIONAL
      traditional
      See Also:
    • TOKEN_NONE

      private static final int TOKEN_NONE
      no token type
      See Also:
    • TOKEN_ALPHANUMERIC

      private static final int TOKEN_ALPHANUMERIC
      alhphanumeric token type
      See Also:
    • TOKEN_NONALPHANUMERIC

      private static final int TOKEN_NONALPHANUMERIC
      nonalphanumeric token type
      See Also:
    • DEFAULT_TOKEN

      private static final Integer[] DEFAULT_TOKEN
      default token
    • DEFAULT_SEPARATOR

      private static final Integer[] DEFAULT_SEPARATOR
      default separator
    • DEFAULT_LANGUAGE

      private static final String DEFAULT_LANGUAGE
      default language
      See Also:
    • prefix

      private Integer[] prefix
      prefix token
    • suffix

      private Integer[] suffix
      suffix token
    • tokens

      private Integer[][] tokens
      sequence of tokens, as parsed from format
    • separators

      private Integer[][] separators
      sequence of separators, as parsed from format
    • groupingSeparator

      private int groupingSeparator
      grouping separator
    • groupingSize

      private int groupingSize
      grouping size
    • letterValue

      private int letterValue
      letter value
    • features

      private String features
      letter value system
    • language

      private String language
      language
    • country

      private String country
      country
    • equivalentLanguages

      private static String[][] equivalentLanguages
    • supportedAlphabeticSequences

      private static int[][] supportedAlphabeticSequences
    • supportedSpecials

      private static int[][] supportedSpecials
    • englishWordOnes

      private static String[] englishWordOnes
      English Word Numerals
    • englishWordTeens

      private static String[] englishWordTeens
    • englishWordTens

      private static String[] englishWordTens
    • englishWordOthers

      private static String[] englishWordOthers
    • englishWordOnesOrd

      private static String[] englishWordOnesOrd
    • englishWordTeensOrd

      private static String[] englishWordTeensOrd
    • englishWordTensOrd

      private static String[] englishWordTensOrd
    • englishWordOthersOrd

      private static String[] englishWordOthersOrd
    • frenchWordOnes

      private static String[] frenchWordOnes
      French Word Numerals
    • frenchWordTeens

      private static String[] frenchWordTeens
    • frenchWordTens

      private static String[] frenchWordTens
    • frenchWordOthers

      private static String[] frenchWordOthers
    • frenchWordOnesOrdMale

      private static String[] frenchWordOnesOrdMale
    • frenchWordOnesOrdFemale

      private static String[] frenchWordOnesOrdFemale
    • spanishWordOnes

      private static String[] spanishWordOnes
      Spanish Word Numerals
    • spanishWordTeens

      private static String[] spanishWordTeens
    • spanishWordTweens

      private static String[] spanishWordTweens
    • spanishWordTens

      private static String[] spanishWordTens
    • spanishWordHundreds

      private static String[] spanishWordHundreds
    • spanishWordOthers

      private static String[] spanishWordOthers
    • spanishWordOnesOrdMale

      private static String[] spanishWordOnesOrdMale
    • spanishWordOnesOrdFemale

      private static String[] spanishWordOnesOrdFemale
    • romanMapping

      private static int[] romanMapping
      Roman (Latin) Numerals
    • romanStandardForms

      private static String[] romanStandardForms
    • romanLargeForms

      private static String[] romanLargeForms
    • romanNumberForms

      private static String[] romanNumberForms
    • hebrewGematriaAlphabeticMap

      private static int[] hebrewGematriaAlphabeticMap
      Gematria (Hebrew) Numerals
    • arabicAbjadiAlphabeticMap

      private static int[] arabicAbjadiAlphabeticMap
      Arabic Numerals
    • arabicHijaiAlphabeticMap

      private static int[] arabicHijaiAlphabeticMap
    • hiraganaGojuonAlphabeticMap

      private static int[] hiraganaGojuonAlphabeticMap
      Kana (Japanese) Numerals
    • katakanaGojuonAlphabeticMap

      private static int[] katakanaGojuonAlphabeticMap
    • thaiAlphabeticMap

      private static int[] thaiAlphabeticMap
      Thai Numerals
  • Constructor Details

    • NumberConverter

      public NumberConverter(String format, int groupingSeparator, int groupingSize, int letterValue, String features, String language, String country) throws IllegalArgumentException
      Construct parameterized number converter.
      Parameters:
      format - format for the page number (may be null or empty, which is treated as null)
      groupingSeparator - grouping separator (if zero, then no grouping separator applies)
      groupingSize - grouping size (if zero or negative, then no grouping size applies)
      letterValue - letter value (must be one of the above letter value enumeration values)
      features - features (feature sub-parameters)
      language - (may be null or empty, which is treated as null)
      country - (may be null or empty, which is treated as null)
      Throws:
      IllegalArgumentException - if format is not a valid UTF-16 string (e.g., has unpaired surrogate)
  • Method Details

    • convert

      public String convert(long number)
      Convert a number to string according to conversion parameters.
      Parameters:
      number - number to conver
      Returns:
      string representing converted number
    • convert

      public String convert(List<Long> numbers)
      Convert list of numbers to string according to conversion parameters.
      Parameters:
      numbers - list of numbers to convert
      Returns:
      string representing converted list of numbers
    • parseFormatTokens

      private void parseFormatTokens(String format) throws IllegalArgumentException
      Throws:
      IllegalArgumentException
    • isAlphaNumeric

      private static boolean isAlphaNumeric(int c)
    • convertNumbers

      private void convertNumbers(List<Integer> scalars, List<Long> numbers)
    • convertNumber

      private Integer[] convertNumber(long number, Integer[] separator, Integer[] token)
    • formatNumber

      private Integer[] formatNumber(long number, Integer[] token)
    • formatNumberAsDecimal

      private Integer[] formatNumberAsDecimal(long number, int one, int width)
      Format NUMBER as decimal using characters denoting digits that start at ONE, adding one or more (zero) padding characters as needed to fill out field WIDTH.
      Parameters:
      number - to be formatted
      one - unicode scalar value denoting numeric value 1
      width - non-negative integer denoting field width of number, possible including padding
      Returns:
      formatted number as array of unicode scalars
    • performGrouping

      private static List<Integer> performGrouping(List<Integer> sl, int groupingSize, int groupingSeparator)
    • formatNumberAsSequence

      private Integer[] formatNumberAsSequence(long number, int one, int base, int[] map)
      Format NUMBER as using sequence of characters that start at ONE, and having BASE radix.
      Parameters:
      number - to be formatted
      one - unicode scalar value denoting start of sequence (numeric value 1)
      base - number of elements in sequence
      map - if non-null, then maps sequences indices to unicode scalars
      Returns:
      formatted number as array of unicode scalars
    • formatNumberAsSpecial

      private Integer[] formatNumberAsSpecial(long number, int one)
      Format NUMBER as using special system that starts at ONE.
      Parameters:
      number - to be formatted
      one - unicode scalar value denoting start of system (numeric value 1)
      Returns:
      formatted number as array of unicode scalars
    • formatNumberAsWord

      private Integer[] formatNumberAsWord(long number, int caseType)
      Format NUMBER as word according to TYPE, which must be either Character.UPPERCASE_LETTER, Character.LOWERCASE_LETTER, or Character.TITLECASE_LETTER. Makes use of this.language to determine language of word.
      Parameters:
      number - to be formatted
      caseType - unicode character type for case conversion
      Returns:
      formatted number as array of unicode scalars
    • isLanguage

      private boolean isLanguage(String iso3Code)
    • isSameLanguage

      private static boolean isSameLanguage(String i3c, String lc)
    • hasFeature

      private static boolean hasFeature(String features, String feature)
    • appendScalars

      private static void appendScalars(List<Integer> scalars, Integer[] sa)
    • scalarsToString

      private static String scalarsToString(List<Integer> scalars)
    • isPaddedOne

      private static boolean isPaddedOne(Integer[] token)
    • getDecimalValue

      private static int getDecimalValue(Integer scalar)
    • isStartOfDecimalSequence

      private static boolean isStartOfDecimalSequence(int s)
    • isStartOfAlphabeticSequence

      private static boolean isStartOfAlphabeticSequence(int s)
    • getSequenceBase

      private static int getSequenceBase(int s)
    • isStartOfNumericSpecial

      private static boolean isStartOfNumericSpecial(int s)
    • getSpecialFormatter

      private NumberConverter.SpecialNumberFormatter getSpecialFormatter(int one, int letterValue, String features, String language, String country)
    • toUpperCase

      private static Integer[] toUpperCase(Integer[] sa)
    • toLowerCase

      private static Integer[] toLowerCase(Integer[] sa)
    • convertWordCase

      private static List<String> convertWordCase(List<String> words, int caseType)
    • convertWordCase

      private static String convertWordCase(String word, int caseType)
    • joinWords

      private static String joinWords(List<String> words, String separator)