You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

PageNumberGenerator.java 5.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. /*
  2. * Licensed to the Apache Software Foundation (ASF) under one or more
  3. * contributor license agreements. See the NOTICE file distributed with
  4. * this work for additional information regarding copyright ownership.
  5. * The ASF licenses this file to You under the Apache License, Version 2.0
  6. * (the "License"); you may not use this file except in compliance with
  7. * the License. You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. /* $Id$ */
  18. package org.apache.fop.fo.pagination;
  19. /**
  20. * This class uses the 'format', 'groupingSeparator', 'groupingSize',
  21. * and 'letterValue' properties on fo:page-sequence to return a String
  22. * corresponding to the supplied integer page number.
  23. */
  24. public class PageNumberGenerator {
  25. private String format;
  26. private char groupingSeparator;
  27. private int groupingSize;
  28. private int letterValue;
  29. // constants
  30. private static final int DECIMAL = 1; // '0*1'
  31. private static final int LOWERALPHA = 2; // 'a'
  32. private static final int UPPERALPHA = 3; // 'A'
  33. private static final int LOWERROMAN = 4; // 'i'
  34. private static final int UPPERROMAN = 5; // 'I'
  35. // flags
  36. private int formatType = DECIMAL;
  37. private int minPadding = 0; // for decimal formats
  38. // preloaded strings of zeros
  39. private String[] zeros = {
  40. "", "0", "00", "000", "0000", "00000"
  41. };
  42. /**
  43. * Main constructor. For further information on the parameters see the XSLT
  44. * specs (Number to String Conversion Attributes).
  45. * @param format format for the page number
  46. * @param groupingSeparator grouping separator
  47. * @param groupingSize grouping size
  48. * @param letterValue letter value
  49. */
  50. public PageNumberGenerator(String format, char groupingSeparator,
  51. int groupingSize, int letterValue) {
  52. this.format = format;
  53. this.groupingSeparator = groupingSeparator;
  54. this.groupingSize = groupingSize;
  55. this.letterValue = letterValue;
  56. // the only accepted format strings are currently '0*1' 'a', 'A', 'i'
  57. // and 'I'
  58. int fmtLen = format.length();
  59. if (fmtLen == 1) {
  60. if (format.equals("1")) {
  61. formatType = DECIMAL;
  62. minPadding = 0;
  63. } else if (format.equals("a")) {
  64. formatType = LOWERALPHA;
  65. } else if (format.equals("A")) {
  66. formatType = UPPERALPHA;
  67. } else if (format.equals("i")) {
  68. formatType = LOWERROMAN;
  69. } else if (format.equals("I")) {
  70. formatType = UPPERROMAN;
  71. } else {
  72. // token not handled
  73. //getLogger().debug("'format' token not recognized; using '1'");
  74. formatType = DECIMAL;
  75. minPadding = 0;
  76. }
  77. } else {
  78. // only accepted token is '0+1'at this stage. Because of the
  79. // wonderful regular expression support in Java, we will resort to a
  80. // loop
  81. for (int i = 0; i < fmtLen - 1; i++) {
  82. if (format.charAt(i) != '0') {
  83. //getLogger().debug("'format' token not recognized; using '1'");
  84. formatType = DECIMAL;
  85. minPadding = 0;
  86. } else {
  87. minPadding = fmtLen - 1;
  88. }
  89. }
  90. }
  91. }
  92. /**
  93. * Formats a page number.
  94. * @param number page number to format
  95. * @return the formatted page number as a String
  96. */
  97. public String makeFormattedPageNumber(int number) {
  98. String pn = null;
  99. if (formatType == DECIMAL) {
  100. pn = Integer.toString(number);
  101. if (minPadding >= pn.length()) {
  102. int nz = minPadding - pn.length() + 1;
  103. pn = zeros[nz] + pn;
  104. }
  105. } else if ((formatType == LOWERROMAN) || (formatType == UPPERROMAN)) {
  106. pn = makeRoman(number);
  107. if (formatType == UPPERROMAN) {
  108. pn = pn.toUpperCase();
  109. }
  110. } else {
  111. // alphabetic
  112. pn = makeAlpha(number);
  113. if (formatType == UPPERALPHA) {
  114. pn = pn.toUpperCase();
  115. }
  116. }
  117. return pn;
  118. }
  119. private String makeRoman(int num) {
  120. int[] arabic = {
  121. 1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1
  122. };
  123. String[] roman = {
  124. "m", "cm", "d", "cd", "c", "xc", "l", "xl", "x", "ix", "v", "iv",
  125. "i"
  126. };
  127. int i = 0;
  128. StringBuffer romanNumber = new StringBuffer();
  129. while (num > 0) {
  130. while (num >= arabic[i]) {
  131. num = num - arabic[i];
  132. romanNumber.append(roman[i]);
  133. }
  134. i = i + 1;
  135. }
  136. return romanNumber.toString();
  137. }
  138. private String makeAlpha(int num) {
  139. String letters = "abcdefghijklmnopqrstuvwxyz";
  140. StringBuffer alphaNumber = new StringBuffer();
  141. int base = 26;
  142. int rem = 0;
  143. num--;
  144. if (num < base) {
  145. alphaNumber.append(letters.charAt(num));
  146. } else {
  147. while (num >= base) {
  148. rem = num % base;
  149. alphaNumber.append(letters.charAt(rem));
  150. num = num / base;
  151. }
  152. alphaNumber.append(letters.charAt(num - 1));
  153. }
  154. return alphaNumber.reverse().toString();
  155. }
  156. }