1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186
|
package com.jclark.xsl.conv;
import java.net.URL;
import java.util.Hashtable;
public class NumberListFormat implements Cloneable {
static private NumberFormat defaultFormat = new DecimalNumberFormat('0', 1);
static private Hashtable formatTokenHandlerTable = new Hashtable();
static {
NumberFormat format = new AlphabetNumberFormat("abcdefghijklmnopqrstuvwxyz");
AlphabetFormatTokenHandler handler = new AlphabetFormatTokenHandler(format);
formatTokenHandlerTable.put("a", handler);
format = new AlphabetNumberFormat("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
handler = new AlphabetFormatTokenHandler(format);
formatTokenHandlerTable.put("A", handler);
formatTokenHandlerTable.put("i", new RomanNumberFormat("mdclxvi"));
formatTokenHandlerTable.put("I", new RomanNumberFormat("MDCLXVI"));
}
private NumberFormat[] formats = null;
private String[] formatTokens = new String[] { "1" };
private String prefix = "";
private String suffix = "";
// i-th element is separator between i-th and i+1-th number
private String[] separators = new String[] { "." };
private int groupingSize = 0;
private String groupingSeparator = null;
private String lang = null;
private String letterValue = null;
public static
void setFormatTokenHandler(String formatToken, FormatTokenHandler handler) {
formatTokenHandlerTable.put(formatToken, handler);
}
public void setFormat(String format) {
formats = null;
int n = 0;
for (int i = 0; i < format.length(); i++) {
if (isAlnum(format.charAt(i))
&& (i == 0 || !isAlnum(format.charAt(i - 1))))
n++;
}
if (n == 0) {
formatTokens = new String[1];
formatTokens[0] = "1";
prefix = "";
}
else
formatTokens = new String[n];
if (n <= 1) {
separators = new String[1];
separators[0] = ".";
}
else
separators = new String[n - 1];
int fi = 0;
for (int i = 0; i < n; i++) {
int sepStart = fi;
while (!isAlnum(format.charAt(fi)))
fi++;
if (i == 0)
prefix = format.substring(0, fi);
else
separators[i - 1] = format.substring(sepStart, fi);
int numberStart = fi++;
while (fi < format.length() && isAlnum(format.charAt(fi)))
fi++;
formatTokens[i] = format.substring(numberStart, fi);
}
suffix = format.substring(fi);
}
static private boolean isAlnum(char c) {
switch (Character.getType(c)) {
case Character.UPPERCASE_LETTER:
case Character.LOWERCASE_LETTER:
case Character.TITLECASE_LETTER:
case Character.MODIFIER_LETTER:
case Character.OTHER_LETTER:
case Character.DECIMAL_DIGIT_NUMBER:
case Character.LETTER_NUMBER:
case Character.OTHER_NUMBER:
return true;
}
return false;
}
public void setLang(String lang) {
formats = null;
this.lang = lang;
}
public void setLetterValue(String letterValue) {
this.letterValue = letterValue;
}
public void setGroupingSeparator(String sep) {
if (sep == null || sep.length() == 0)
groupingSeparator = null;
else
groupingSeparator = sep;
}
public void setGroupingSize(int n) {
groupingSize = n;
}
public String getPrefix(int i) {
if (i == 0)
return prefix;
i -= 1;
if (i < separators.length)
return separators[i];
return separators[separators.length - 1];
}
public String formatNumber(int i, int n) {
if (n < 0)
throw new IllegalArgumentException("cannot format negative number");
return group(getFormat(i).format(n));
}
public String getSuffix() {
return suffix;
}
private NumberFormat getFormat(int i) {
if (formats == null)
formats = new NumberFormat[formatTokens.length];
if (i >= formats.length)
i = formats.length - 1;
if (formats[i] == null)
formats[i] = findFormat(formatTokens[i]);
return formats[i];
}
private NumberFormat findFormat(String formatToken) {
NumberFormat f = findDecimalFormat(formatToken);
if (f != null)
return f;
FormatTokenHandler handler = (FormatTokenHandler)formatTokenHandlerTable.get(formatToken);
if (handler != null) {
f = handler.getFormat(lang, letterValue);
if (f != null)
return f;
}
return defaultFormat;
}
private NumberFormat findDecimalFormat(String format) {
char digitOne = format.charAt(format.length() - 1);
if (!Character.isDigit(digitOne) || Character.digit(digitOne, 10) != 1)
return null;
for (int i = 0; i < format.length() - 1; i++)
if (format.charAt(i) + 1 != digitOne)
return null;
return new DecimalNumberFormat((char)(digitOne - 1), format.length());
}
private String group(String number) {
if (groupingSeparator == null || groupingSize <= 0 || number.length() <= groupingSize)
return number;
char buf[] = new char[number.length() + ((number.length() - 1)/groupingSize) * groupingSeparator.length()];
int j = 0;
for (int i = 0; i < number.length(); i++) {
if (i > 0 && (number.length() - i) % groupingSize == 0) {
for (int k = 0; k < groupingSeparator.length(); k++)
buf[j++] = groupingSeparator.charAt(k);
}
buf[j++] = number.charAt(i);
}
return new String(buf);
}
public Object clone() {
try {
return super.clone();
} catch (CloneNotSupportedException e) {
throw new InternalError();
}
}
}
|