1 16 19 20 package org.apache.xalan.xsltc.dom; 21 22 import java.util.Vector ; 23 24 import org.apache.xalan.xsltc.DOM; 25 import org.apache.xalan.xsltc.Translet; 26 import org.apache.xml.dtm.DTM; 27 import org.apache.xml.dtm.DTMAxisIterator; 28 29 34 public abstract class NodeCounter implements Axis { 35 public static final int END = DTM.NULL; 36 37 protected int _node = END; 38 protected int _nodeType = DOM.FIRST_TYPE - 1; 39 protected int _value = Integer.MIN_VALUE; 40 41 public final DOM _document; 42 public final DTMAxisIterator _iterator; 43 public final Translet _translet; 44 45 protected String _format; 46 protected String _lang; 47 protected String _letterValue; 48 protected String _groupSep; 49 protected int _groupSize; 50 51 private boolean separFirst = true; 52 private boolean separLast = false; 53 private Vector separToks = null; 54 private Vector formatToks = null; 55 private int nSepars = 0; 56 private int nFormats = 0; 57 58 private static String [] Thousands = 59 {"", "m", "mm", "mmm" }; 60 private static String [] Hundreds = 61 {"", "c", "cc", "ccc", "cd", "d", "dc", "dcc", "dccc", "cm"}; 62 private static String [] Tens = 63 {"", "x", "xx", "xxx", "xl", "l", "lx", "lxx", "lxxx", "xc"}; 64 private static String [] Ones = 65 {"", "i", "ii", "iii", "iv", "v", "vi", "vii", "viii", "ix"}; 66 67 protected NodeCounter(Translet translet, 68 DOM document, DTMAxisIterator iterator) { 69 _translet = translet; 70 _document = document; 71 _iterator = iterator; 72 } 73 74 78 abstract public NodeCounter setStartNode(int node); 79 80 84 public NodeCounter setValue(int value) { 85 _value = value; 86 return this; 87 } 88 89 92 protected void setFormatting(String format, String lang, String letterValue, 93 String groupSep, String groupSize) { 94 _lang = lang; 95 _format = format; 96 _groupSep = groupSep; 97 _letterValue = letterValue; 98 99 try { 100 _groupSize = Integer.parseInt(groupSize); 101 } 102 catch (NumberFormatException e) { 103 _groupSize = 0; 104 } 105 106 final int length = _format.length(); 107 boolean isFirst = true; 108 separFirst = true; 109 separLast = false; 110 111 separToks = new Vector (); 112 formatToks = new Vector (); 113 114 118 for (int j = 0, i = 0; i < length;) { 119 char c = _format.charAt(i); 120 for (j = i; Character.isLetterOrDigit(c);) { 121 if (++i == length) break; 122 c = _format.charAt(i); 123 } 124 if (i > j) { 125 if (isFirst) { 126 separToks.addElement("."); 127 isFirst = separFirst = false; 128 } 129 formatToks.addElement(_format.substring(j, i)); 130 } 131 132 if (i == length) break; 133 134 c = _format.charAt(i); 135 for (j = i; !Character.isLetterOrDigit(c);) { 136 if (++i == length) break; 137 c = _format.charAt(i); 138 isFirst = false; 139 } 140 if (i > j) { 141 separToks.addElement(_format.substring(j, i)); 142 } 143 } 144 145 nSepars = separToks.size(); 146 nFormats = formatToks.size(); 147 if (nSepars > nFormats) separLast = true; 148 149 if (separFirst) nSepars--; 150 if (separLast) nSepars--; 151 if (nSepars == 0) { 152 separToks.insertElementAt(".", 1); 153 nSepars++; 154 } 155 if (separFirst) nSepars ++; 156 } 157 158 161 public NodeCounter setDefaultFormatting() { 162 setFormatting("1", "en", "alphabetic", null, null); 163 return this; 164 } 165 166 170 abstract public String getCounter(); 171 172 177 public String getCounter(String format, String lang, String letterValue, 178 String groupSep, String groupSize) { 179 setFormatting(format, lang, letterValue, groupSep, groupSize); 180 return getCounter(); 181 } 182 183 188 public boolean matchesCount(int node) { 189 return _nodeType == _document.getExpandedTypeID(node); 190 } 191 192 196 public boolean matchesFrom(int node) { 197 return false; 198 } 199 200 203 protected String formatNumbers(int value) { 204 return formatNumbers(new int[] { value }); 205 } 206 207 211 protected String formatNumbers(int[] values) { 212 final int nValues = values.length; 213 final int length = _format.length(); 214 215 boolean isEmpty = true; 216 for (int i = 0; i < nValues; i++) 217 if (values[i] != Integer.MIN_VALUE) 218 isEmpty = false; 219 if (isEmpty) return(""); 220 221 boolean isFirst = true; 223 int t = 0, n = 0, s = 1; 224 final StringBuffer buffer = new StringBuffer (); 225 226 if (separFirst) buffer.append((String )separToks.elementAt(0)); 228 229 while (n < nValues) { 231 final int value = values[n]; 232 if (value != Integer.MIN_VALUE) { 233 if (!isFirst) buffer.append((String ) separToks.elementAt(s++)); 234 formatValue(value, (String )formatToks.elementAt(t++), buffer); 235 if (t == nFormats) t--; 236 if (s >= nSepars) s--; 237 isFirst = false; 238 } 239 n++; 240 } 241 242 if (separLast) buffer.append((String )separToks.lastElement()); 244 return buffer.toString(); 245 } 246 247 252 private void formatValue(int value, String format, StringBuffer buffer) { 253 char c = format.charAt(0); 254 255 if (Character.isDigit(c)) { 256 char zero = (char)(c - Character.getNumericValue(c)); 257 258 StringBuffer temp = buffer; 259 if (_groupSize > 0) { 260 temp = new StringBuffer (); 261 } 262 String s = ""; 263 int n = value; 264 while (n > 0) { 265 s = (char) ((int) zero + (n % 10)) + s; 266 n = n / 10; 267 } 268 269 for (int i = 0; i < format.length() - s.length(); i++) { 270 temp.append(zero); 271 } 272 temp.append(s); 273 274 if (_groupSize > 0) { 275 for (int i = 0; i < temp.length(); i++) { 276 if (i != 0 && ((temp.length() - i) % _groupSize) == 0) { 277 buffer.append(_groupSep); 278 } 279 buffer.append(temp.charAt(i)); 280 } 281 } 282 } 283 else if (c == 'i' && !_letterValue.equals("alphabetic")) { 284 buffer.append(romanValue(value)); 285 } 286 else if (c == 'I' && !_letterValue.equals("alphabetic")) { 287 buffer.append(romanValue(value).toUpperCase()); 288 } 289 else { 290 int min = (int) c; 291 int max = (int) c; 292 293 if (c >= 0x3b1 && c <= 0x3c9) { 295 max = 0x3c9; } 297 else { 298 while (Character.isLetterOrDigit((char) (max + 1))) { 300 max++; 301 } 302 } 303 buffer.append(alphaValue(value, min, max)); 304 } 305 } 306 307 private String alphaValue(int value, int min, int max) { 308 if (value <= 0) { 309 return "" + value; 310 } 311 312 int range = max - min + 1; 313 char last = (char)(((value-1) % range) + min); 314 if (value > range) { 315 return alphaValue((value-1) / range, min, max) + last; 316 } 317 else { 318 return "" + last; 319 } 320 } 321 322 private String romanValue(int n) { 323 if (n <= 0 || n > 4000) { 324 return "" + n; 325 } 326 return 327 Thousands[n / 1000] + 328 Hundreds[(n / 100) % 10] + 329 Tens[(n/10) % 10] + 330 Ones[n % 10]; 331 } 332 } 333 334 | Popular Tags |