PageRenderTime 52ms CodeModel.GetById 25ms RepoModel.GetById 1ms app.codeStats 0ms

/lib/saxonB/net/sf/saxon/number/NumberFormatter.java

https://bitbucket.org/dmwelch/phdxnat_pipeline
Java | 187 lines | 113 code | 21 blank | 53 comment | 34 complexity | a3aee5e60e961c8fa227a7d560948736 MD5 | raw file
  1. package net.sf.saxon.number;
  2. import net.sf.saxon.charcode.UTF16;
  3. import net.sf.saxon.om.FastStringBuffer;
  4. import java.io.Serializable;
  5. import java.util.ArrayList;
  6. import java.util.List;
  7. /**
  8. * Class NumberFormatter defines a method to format a ArrayList of integers as a character
  9. * string according to a supplied format specification.
  10. * @author Michael H. Kay
  11. */
  12. public class NumberFormatter implements Serializable {
  13. private ArrayList formatTokens;
  14. private ArrayList punctuationTokens;
  15. private boolean startsWithPunctuation;
  16. /**
  17. * Tokenize the format pattern.
  18. * @param format the format specification. Contains one of the following values:<ul>
  19. * <li>"1": conventional decimal numbering</li>
  20. * <li>"a": sequence a, b, c, ... aa, ab, ac, ...</li>
  21. * <li>"A": sequence A, B, C, ... AA, AB, AC, ...</li>
  22. * <li>"i": sequence i, ii, iii, iv, v ...</li>
  23. * <li>"I": sequence I, II, III, IV, V, ...</li>
  24. * </ul>
  25. * This symbol may be preceded and followed by punctuation (any other characters) which is
  26. * copied to the output string.
  27. */
  28. public void prepare(String format) {
  29. // Tokenize the format string into alternating alphanumeric and non-alphanumeric tokens
  30. if (format.length()==0) {
  31. format="1";
  32. }
  33. formatTokens = new ArrayList(10);
  34. punctuationTokens = new ArrayList(10);
  35. int len = format.length();
  36. int i=0;
  37. int t;
  38. boolean first = true;
  39. startsWithPunctuation = true;
  40. while (i<len) {
  41. int c = format.charAt(i);
  42. t=i;
  43. if (UTF16.isHighSurrogate(c)) {
  44. c = UTF16.combinePair((char)c, format.charAt(++i));
  45. }
  46. while (isLetterOrDigit(c)) {
  47. i++;
  48. if (i==len) break;
  49. c = format.charAt(i);
  50. if (UTF16.isHighSurrogate(c)) {
  51. c = UTF16.combinePair((char)c, format.charAt(++i));
  52. }
  53. }
  54. if (i>t) {
  55. String tok = format.substring(t, i);
  56. formatTokens.add(tok);
  57. if (first) {
  58. punctuationTokens.add(".");
  59. startsWithPunctuation = false;
  60. first = false;
  61. }
  62. }
  63. if (i==len) break;
  64. t=i;
  65. c = format.charAt(i);
  66. if (UTF16.isHighSurrogate(c)) {
  67. c = UTF16.combinePair((char)c, format.charAt(++i));
  68. }
  69. while (!isLetterOrDigit(c)) {
  70. first = false;
  71. i++;
  72. if (i==len) break;
  73. c = format.charAt(i);
  74. if (UTF16.isHighSurrogate(c)) {
  75. c = UTF16.combinePair((char)c, format.charAt(++i));
  76. }
  77. }
  78. if (i>t) {
  79. String sep = format.substring(t, i);
  80. punctuationTokens.add(sep);
  81. }
  82. }
  83. if (formatTokens.isEmpty()) {
  84. formatTokens.add("1");
  85. if (punctuationTokens.size() == 1) {
  86. punctuationTokens.add(punctuationTokens.get(0));
  87. }
  88. }
  89. }
  90. /**
  91. * Determine whether a (possibly non-BMP) character is a letter or digit.
  92. * @param c the codepoint of the character to be tested
  93. * @return For a non-BMP character: on JDK1.4, always returns false. On JDK 1.5, returns the result
  94. * of calling Character.isLetterOrDigit(int codepoint).
  95. */
  96. private static boolean isLetterOrDigit(int c) {
  97. if (c <= 0x7F) {
  98. // Fast path for ASCII characters
  99. return (c >= 0x30 && c <= 0x39) || (c >= 0x41 && c <= 0x5A) || (c >= 0x61 && c <= 0x7A);
  100. } else {
  101. return Alphanumeric.isAlphanumeric(c);
  102. }
  103. }
  104. /**
  105. * Format a list of numbers.
  106. * @param numbers the numbers to be formatted (a sequence of integer values; it may also contain
  107. * preformatted strings as part of the error recovery fallback)
  108. * @return the formatted output string.
  109. */
  110. public CharSequence format(List numbers, int groupSize, String groupSeparator,
  111. String letterValue, String ordinal, Numberer numberer) {
  112. FastStringBuffer sb = new FastStringBuffer(20);
  113. int num = 0;
  114. int tok = 0;
  115. // output first punctuation token
  116. if (startsWithPunctuation) {
  117. sb.append((String)punctuationTokens.get(tok));
  118. }
  119. // output the list of numbers
  120. while (num<numbers.size()) {
  121. if (num>0) {
  122. if (tok==0 && startsWithPunctuation) {
  123. // The first punctuation token isn't a separator if it appears before the first
  124. // formatting token. Such a punctuation token is used only once, at the start.
  125. sb.append(".");
  126. } else {
  127. sb.append((String)punctuationTokens.get(tok));
  128. }
  129. }
  130. Object o = numbers.get(num++);
  131. String s;
  132. if (o instanceof Long) {
  133. long nr = ((Long)o).longValue();
  134. s = numberer.format(nr, (String)formatTokens.get(tok),
  135. groupSize, groupSeparator, letterValue, ordinal);
  136. } else {
  137. s = o.toString();
  138. }
  139. sb.append(s);
  140. tok++;
  141. if (tok==formatTokens.size()) tok--;
  142. }
  143. // output the final punctuation token
  144. if (punctuationTokens.size()>formatTokens.size()) {
  145. sb.append((String)punctuationTokens.get(punctuationTokens.size()-1));
  146. }
  147. return sb.condense();
  148. }
  149. }
  150. //
  151. // The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
  152. // you may not use this file except in compliance with the License. You may obtain a copy of the
  153. // License at http://www.mozilla.org/MPL/
  154. //
  155. // Software distributed under the License is distributed on an "AS IS" basis,
  156. // WITHOUT WARRANTY OF ANY KIND, either express or implied.
  157. // See the License for the specific language governing rights and limitations under the License.
  158. //
  159. // The Original Code is: all this file.
  160. //
  161. // The Initial Developer of the Original Code is Michael H. Kay.
  162. //
  163. // Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
  164. //
  165. // Contributor(s): none.
  166. //