1 package com.icl.saxon.style; 2 import com.icl.saxon.tree.AttributeCollection; 3 import com.icl.saxon.*; 4 import com.icl.saxon.om.*; 5 import com.icl.saxon.expr.*; 6 import com.icl.saxon.pattern.Pattern; 7 import com.icl.saxon.number.*; 8 import com.icl.saxon.functions.Round; 9 import javax.xml.transform.*; 10 import java.util.*; 11 12 15 16 public class XSLNumber extends StyleElement { 17 18 private final static int SINGLE = 0; 19 private final static int MULTI = 1; 20 private final static int ANY = 2; 21 private final static int SIMPLE = 3; 22 23 private int level; 24 private Pattern count = null; 25 private Pattern from = null; 26 private Expression expr = null; 27 private Expression format = null; 28 private Expression groupSize = null; 29 private Expression groupSeparator = null; 30 private Expression letterValue = null; 31 private Expression lang = null; 32 private NumberFormatter formatter = null; 33 private Numberer numberer = null; 34 35 private static Numberer defaultNumberer = new Numberer_en(); 36 37 41 42 public boolean isInstruction() { 43 return true; 44 } 45 46 47 public void prepareAttributes() throws TransformerConfigurationException { 48 49 StandardNames sn = getStandardNames(); 50 AttributeCollection atts = getAttributeList(); 51 52 String valueAtt = null; 53 String countAtt = null; 54 String fromAtt = null; 55 String levelAtt = null; 56 String formatAtt = null; 57 String gsizeAtt = null; 58 String gsepAtt = null; 59 String langAtt = null; 60 String letterValueAtt = null; 61 62 for (int a=0; a<atts.getLength(); a++) { 63 int nc = atts.getNameCode(a); 64 int f = nc & 0xfffff; 65 if (f==sn.VALUE) { 66 valueAtt = atts.getValue(a); 67 } else if (f==sn.COUNT) { 68 countAtt = atts.getValue(a); 69 } else if (f==sn.FROM) { 70 fromAtt = atts.getValue(a); 71 } else if (f==sn.LEVEL) { 72 levelAtt = atts.getValue(a); 73 } else if (f==sn.FORMAT) { 74 formatAtt = atts.getValue(a); 75 } else if (f==sn.LANG) { 76 langAtt = atts.getValue(a); 77 } else if (f==sn.LETTER_VALUE) { 78 letterValueAtt = atts.getValue(a); 79 } else if (f==sn.GROUPING_SIZE) { 80 gsizeAtt = atts.getValue(a); 81 } else if (f==sn.GROUPING_SEPARATOR) { 82 gsepAtt = atts.getValue(a); 83 } else { 84 checkUnknownAttribute(nc); 85 } 86 } 87 88 if (valueAtt!=null) { 89 expr = makeExpression(valueAtt); 90 } 91 92 if (countAtt!=null) { 93 count = makePattern(countAtt); 94 } 95 96 if (fromAtt!=null) { 97 from = makePattern(fromAtt); 98 } 99 100 if (levelAtt==null) { 101 level = SINGLE; 102 } else if (levelAtt.equals("single")) { 103 level = SINGLE; 104 } else if (levelAtt.equals("multiple")) { 105 level = MULTI; 106 } else if (levelAtt.equals("any")) { 107 level = ANY; 108 } else { 109 compileError("Invalid value for level attribute"); 110 } 111 112 if (level==SINGLE && from==null && count==null) { 113 level=SIMPLE; 114 } 115 116 if (formatAtt != null) { 117 format = makeAttributeValueTemplate(formatAtt); 118 if (format instanceof StringValue) { 119 formatter = new NumberFormatter(); 120 formatter.prepare(((StringValue)format).asString()); 121 } 122 } else { 124 formatter = new NumberFormatter(); 125 formatter.prepare("1"); 126 } 127 128 if (gsepAtt!=null && gsizeAtt!=null) { 129 groupSize = makeAttributeValueTemplate(gsizeAtt); 131 groupSeparator = makeAttributeValueTemplate(gsepAtt); 132 } 133 134 if (langAtt==null) { 135 numberer = defaultNumberer; 136 } else { 137 lang = makeAttributeValueTemplate(langAtt); 138 if (lang instanceof StringValue) { 139 numberer = makeNumberer(((StringValue)lang).asString()); 140 } } 142 143 if (letterValueAtt != null) { 144 letterValue = makeAttributeValueTemplate(letterValueAtt); 145 } 146 147 } 148 149 public void validate() throws TransformerConfigurationException { 150 checkWithinTemplate(); 151 checkEmpty(); 152 } 153 154 public void process(Context context) throws TransformerException 155 { 156 NodeInfo source = context.getCurrentNodeInfo(); 157 int value = -1; 158 Vector vec = null; 159 160 if (expr!=null) { 161 double d = expr.evaluateAsNumber(context); 162 if (d < 0.5 || Double.isNaN(d) || Double.isInfinite(d) || 163 d > Integer.MAX_VALUE) { 164 context.getOutputter().writeContent(new NumericValue(d).asString()); 165 return; 166 } else { 167 value = (int)Round.round(d); 168 } 169 170 } else { 171 172 if (level==SIMPLE) { 173 value = Navigator.getNumberSimple(source, context); 174 } else if (level==SINGLE) { 175 value = Navigator.getNumberSingle(source, count, from, context); 176 if (value==0) { 177 vec = new Vector(); } 179 } else if (level==ANY) { 180 value = Navigator.getNumberAny(source, count, from, context); 181 if (value==0) { 182 vec = new Vector(); } 184 } else if (level==MULTI) { 185 vec = Navigator.getNumberMulti(source, count, from, context); 186 } 187 } 188 189 int gpsize = 0; 190 String gpseparator = ""; 191 String language; 192 String letterVal; 193 194 if (groupSize!=null) { 195 String g = groupSize.evaluateAsString(context); 196 try { 197 gpsize = Integer.parseInt(g); 198 } catch (NumberFormatException err) { 199 throw styleError("group-size must be numeric"); 200 } 201 } 202 203 if (groupSeparator!=null) { 204 gpseparator = groupSeparator.evaluateAsString(context); 205 } 206 207 209 if (vec==null && format==null && gpsize==0 && lang==null) { 210 context.getOutputter().writeContent("" + value); 211 return; 212 } 213 214 if (numberer==null) { 215 numberer = makeNumberer(lang.evaluateAsString(context)); 216 } 217 218 if (letterValue==null) { 219 letterVal = ""; 220 } else { 221 letterVal = letterValue.evaluateAsString(context); 222 if (!(letterVal.equals("alphabetic") || letterVal.equals("traditional"))) { 223 throw styleError("letter-value must be \"traditional\" or \"alphabetic\""); 224 } 225 } 226 227 if (vec==null) { 228 vec = new Vector(); 229 vec.addElement(new Integer (value)); 230 } 231 232 NumberFormatter nf; 233 if (formatter==null) { nf = new NumberFormatter(); 235 nf.prepare(format.evaluateAsString(context)); 236 } else { 237 nf = formatter; 238 } 239 240 String s = nf.format(vec, gpsize, gpseparator, letterVal, numberer); 241 context.getOutputter().writeContent(s); 242 } 243 244 247 248 protected static Numberer makeNumberer (String language) { 250 Numberer numberer; 251 if (language.equals("en")) { 252 numberer = defaultNumberer; 253 } else { 254 String langClassName = "com.icl.saxon.number.Numberer_"; 255 for (int i=0; i<language.length(); i++) { 256 if (Character.isLetter(language.charAt(i))) { 257 langClassName += language.charAt(i); 258 } 259 } 260 try { 261 numberer = (Numberer)(Loader.getInstance(langClassName)); 262 } catch (Exception err) { 263 numberer = defaultNumberer; 264 } 265 } 266 267 return numberer; 268 } 269 } 270 271 | Popular Tags |