KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > icl > saxon > style > XSLNumber


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 /**
13 * An xsl:number element in the stylesheet.<BR>
14 */

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     /**
38     * Determine whether this node is an instruction.
39     * @return true - it is an instruction
40     */

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 JavaDoc valueAtt = null;
53         String JavaDoc countAtt = null;
54         String JavaDoc fromAtt = null;
55         String JavaDoc levelAtt = null;
56         String JavaDoc formatAtt = null;
57         String JavaDoc gsizeAtt = null;
58         String JavaDoc gsepAtt = null;
59         String JavaDoc langAtt = null;
60         String JavaDoc 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 we'll need to allocate the formatter at run-time
123
} else {
124             formatter = new NumberFormatter();
125             formatter.prepare("1");
126         }
127
128         if (gsepAtt!=null && gsizeAtt!=null) {
129             // the spec says that if only one is specified, it is ignored
130
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             } // else we allocate a numberer at run-time
141
}
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(); // an empty list
178
}
179             } else if (level==ANY) {
180                 value = Navigator.getNumberAny(source, count, from, context);
181                 if (value==0) {
182                     vec = new Vector(); // an empty list
183
}
184             } else if (level==MULTI) {
185                 vec = Navigator.getNumberMulti(source, count, from, context);
186             }
187         }
188
189         int gpsize = 0;
190         String JavaDoc gpseparator = "";
191         String JavaDoc language;
192         String JavaDoc letterVal;
193
194         if (groupSize!=null) {
195             String JavaDoc g = groupSize.evaluateAsString(context);
196             try {
197                 gpsize = Integer.parseInt(g);
198             } catch (NumberFormatException JavaDoc err) {
199                 throw styleError("group-size must be numeric");
200             }
201         }
202
203         if (groupSeparator!=null) {
204             gpseparator = groupSeparator.evaluateAsString(context);
205         }
206
207         // fast path for the simple case
208

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 JavaDoc(value));
230         }
231
232         NumberFormatter nf;
233         if (formatter==null) { // format not known until run-time
234
nf = new NumberFormatter();
235             nf.prepare(format.evaluateAsString(context));
236         } else {
237             nf = formatter;
238         }
239         
240         String JavaDoc s = nf.format(vec, gpsize, gpseparator, letterVal, numberer);
241         context.getOutputter().writeContent(s);
242     }
243
244     /**
245     * Load a Numberer class for a given language and check it is OK.
246     */

247
248     protected static Numberer makeNumberer (String JavaDoc language) //throws SAXException
249
{
250         Numberer numberer;
251         if (language.equals("en")) {
252             numberer = defaultNumberer;
253         } else {
254             String JavaDoc 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 JavaDoc err) {
263                 numberer = defaultNumberer;
264             }
265         }
266
267         return numberer;
268      }
269 }
270
271 //
272
// The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
273
// you may not use this file except in compliance with the License. You may obtain a copy of the
274
// License at http://www.mozilla.org/MPL/
275
//
276
// Software distributed under the License is distributed on an "AS IS" basis,
277
// WITHOUT WARRANTY OF ANY KIND, either express or implied.
278
// See the License for the specific language governing rights and limitations under the License.
279
//
280
// The Original Code is: all this file.
281
//
282
// The Initial Developer of the Original Code is
283
// Michael Kay of International Computers Limited (mhkay@iclway.co.uk).
284
//
285
// Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
286
//
287
// Contributor(s): none.
288
//
289
Popular Tags