KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sf > saxon > style > XSLNumber


1 package net.sf.saxon.style;
2 import net.sf.saxon.expr.*;
3 import net.sf.saxon.instruct.Executable;
4 import net.sf.saxon.instruct.NumberInstruction;
5 import net.sf.saxon.instruct.ValueOf;
6 import net.sf.saxon.number.NumberFormatter;
7 import net.sf.saxon.number.Numberer;
8 import net.sf.saxon.number.Numberer_en;
9 import net.sf.saxon.om.AttributeCollection;
10 import net.sf.saxon.pattern.NodeKindTest;
11 import net.sf.saxon.pattern.Pattern;
12 import net.sf.saxon.trans.XPathException;
13 import net.sf.saxon.type.ItemType;
14 import net.sf.saxon.value.SequenceType;
15 import net.sf.saxon.value.StringValue;
16
17 /**
18 * An xsl:number element in the stylesheet. <br>
19 */

20
21 public class XSLNumber extends StyleElement {
22
23     private static final int SINGLE = 0;
24     private static final int MULTI = 1;
25     private static final int ANY = 2;
26     private static final int SIMPLE = 3;
27
28     private int level;
29     private Pattern count = null;
30     private Pattern from = null;
31     private Expression select = null;
32     private Expression value = null;
33     private Expression format = null;
34     private Expression groupSize = null;
35     private Expression groupSeparator = null;
36     private Expression letterValue = null;
37     private Expression lang = null;
38     private Expression ordinal = null;
39     private NumberFormatter formatter = null;
40     private Numberer numberer = null;
41     private boolean hasVariablesInPatterns = false;
42
43     private static Numberer defaultNumberer = new Numberer_en();
44
45     /**
46     * Determine whether this node is an instruction.
47     * @return true - it is an instruction
48     */

49
50     public boolean isInstruction() {
51         return true;
52     }
53
54     /**
55      * Determine the type of item returned by this instruction (only relevant if
56      * it is an instruction).
57      * @return the item type returned
58      */

59
60     protected ItemType getReturnedItemType() {
61         return NodeKindTest.TEXT;
62     }
63
64     public void prepareAttributes() throws XPathException {
65
66         AttributeCollection atts = getAttributeList();
67
68         String JavaDoc selectAtt = null;
69         String JavaDoc valueAtt = null;
70         String JavaDoc countAtt = null;
71         String JavaDoc fromAtt = null;
72         String JavaDoc levelAtt = null;
73         String JavaDoc formatAtt = null;
74         String JavaDoc gsizeAtt = null;
75         String JavaDoc gsepAtt = null;
76         String JavaDoc langAtt = null;
77         String JavaDoc letterValueAtt = null;
78         String JavaDoc ordinalAtt = null;
79
80         for (int a=0; a<atts.getLength(); a++) {
81             int nc = atts.getNameCode(a);
82             String JavaDoc f = getNamePool().getClarkName(nc);
83             if (f==StandardNames.SELECT) {
84                 selectAtt = atts.getValue(a);
85             } else if (f==StandardNames.VALUE) {
86                 valueAtt = atts.getValue(a);
87             } else if (f==StandardNames.COUNT) {
88                 countAtt = atts.getValue(a);
89             } else if (f==StandardNames.FROM) {
90                 fromAtt = atts.getValue(a);
91             } else if (f==StandardNames.LEVEL) {
92                 levelAtt = atts.getValue(a).trim();
93             } else if (f==StandardNames.FORMAT) {
94                 formatAtt = atts.getValue(a);
95             } else if (f==StandardNames.LANG) {
96                 langAtt = atts.getValue(a);
97             } else if (f==StandardNames.LETTER_VALUE) {
98                 letterValueAtt = atts.getValue(a).trim();
99             } else if (f==StandardNames.GROUPING_SIZE) {
100                 gsizeAtt = atts.getValue(a).trim();
101             } else if (f==StandardNames.GROUPING_SEPARATOR) {
102                 gsepAtt = atts.getValue(a);
103             } else if (f==StandardNames.ORDINAL) {
104                 ordinalAtt = atts.getValue(a);
105             } else {
106                 checkUnknownAttribute(nc);
107             }
108         }
109
110         if (selectAtt != null) {
111             select = makeExpression(selectAtt);
112         }
113
114         if (valueAtt!=null) {
115             value = makeExpression(valueAtt);
116             if (selectAtt != null) {
117                 compileError("The select attribute and value attribute must not both be present", "XTSE0975");
118             }
119             if (countAtt != null) {
120                 compileError("The count attribute and value attribute must not both be present", "XTSE0975");
121             }
122             if (fromAtt != null) {
123                 compileError("The from attribute and value attribute must not both be present", "XTSE0975");
124             }
125             if (levelAtt != null) {
126                 compileError("The level attribute and value attribute must not both be present", "XTSE0975");
127             }
128         }
129
130         if (countAtt!=null) {
131             count = makePattern(countAtt);
132             // the following test is a very crude way of testing if the pattern might
133
// contain variables, but it's good enough...
134
if (countAtt.indexOf('$')>=0) {
135                 hasVariablesInPatterns = true;
136             }
137         }
138
139         if (fromAtt!=null) {
140             from = makePattern(fromAtt);
141             if (fromAtt.indexOf('$')>=0) {
142                 hasVariablesInPatterns = true;
143             }
144         }
145
146         if (levelAtt==null) {
147             level = SINGLE;
148         } else if (levelAtt.equals("single")) {
149             level = SINGLE;
150         } else if (levelAtt.equals("multiple")) {
151             level = MULTI;
152         } else if (levelAtt.equals("any")) {
153             level = ANY;
154         } else {
155             compileError("Invalid value for level attribute", "XTSE0020");
156         }
157
158         if (level==SINGLE && from==null && count==null) {
159             level=SIMPLE;
160         }
161
162         if (formatAtt != null) {
163             format = makeAttributeValueTemplate(formatAtt);
164             if (format instanceof StringValue) {
165                 formatter = new NumberFormatter();
166                 formatter.prepare(((StringValue)format).getStringValue());
167             }
168             // else we'll need to allocate the formatter at run-time
169
} else {
170             formatter = new NumberFormatter();
171             formatter.prepare("1");
172         }
173
174         if (gsepAtt!=null && gsizeAtt!=null) {
175             // the spec says that if only one is specified, it is ignored
176
groupSize = makeAttributeValueTemplate(gsizeAtt);
177             groupSeparator = makeAttributeValueTemplate(gsepAtt);
178         }
179
180         if (langAtt==null) {
181             numberer = defaultNumberer;
182         } else {
183             lang = makeAttributeValueTemplate(langAtt);
184             if (lang instanceof StringValue) {
185                 numberer = makeNumberer(((StringValue)lang).getStringValue());
186             } // else we allocate a numberer at run-time
187
}
188
189         if (letterValueAtt != null) {
190             letterValue = makeAttributeValueTemplate(letterValueAtt);
191         }
192
193         if (ordinalAtt != null) {
194             ordinal = makeAttributeValueTemplate(ordinalAtt);
195         }
196
197     }
198
199     public void validate() throws XPathException {
200         checkWithinTemplate();
201         checkEmpty();
202
203         select = typeCheck("select", select);
204         value = typeCheck("value", value);
205         format = typeCheck("format", format);
206         groupSize = typeCheck("group-size", groupSize);
207         groupSeparator = typeCheck("group-separator", groupSeparator);
208         letterValue = typeCheck("letter-value", letterValue);
209         ordinal = typeCheck("ordinal", ordinal);
210         lang = typeCheck("lang", lang);
211         from = typeCheck("from", from);
212         count = typeCheck("count", count);
213
214         if (select != null) {
215             try {
216                 RoleLocator role =
217                     new RoleLocator(RoleLocator.INSTRUCTION, "xsl:number/select", 0, null);
218                 role.setSourceLocator(new ExpressionLocation(this));
219                 select = TypeChecker.staticTypeCheck(select,
220                                             SequenceType.SINGLE_NODE,
221                                             false, role, getStaticContext());
222             } catch (XPathException err) {
223                 compileError(err);
224             }
225         }
226     }
227
228     public Expression compile(Executable exec) throws XPathException {
229         NumberInstruction expr = new NumberInstruction ( select,
230                                         level,
231                                         count,
232                                         from,
233                                         value,
234                                         format,
235                                         groupSize,
236                                         groupSeparator,
237                                         letterValue,
238                                         ordinal,
239                                         lang,
240                                         formatter,
241                                         numberer,
242                                         hasVariablesInPatterns,
243                                         backwardsCompatibleModeIsEnabled());
244         int loc = getStaticContext().getLocationMap().allocateLocationId(getSystemId(), getLineNumber());
245         expr.setLocationId(loc);
246         ExpressionTool.makeParentReferences(expr);
247         ValueOf inst = new ValueOf(expr, false, false);
248         inst.setLocationId(allocateLocationId(getSystemId(), getLineNumber()));
249         ExpressionTool.makeParentReferences(inst);
250         inst.setIsNumberingInstruction();
251         return inst;
252     }
253
254     /**
255     * Load a Numberer class for a given language and check it is OK.
256     */

257
258     protected Numberer makeNumberer (String JavaDoc language) {
259         Numberer numberer;
260         if (language.equals("en")) {
261             numberer = defaultNumberer;
262         } else {
263             String JavaDoc langClassName = "net.sf.saxon.number.Numberer_";
264             for (int i=0; i<language.length(); i++) {
265                 if (Character.isLetter(language.charAt(i))) {
266                     langClassName += language.charAt(i);
267                 }
268             }
269             try {
270                 numberer = (Numberer)(getConfiguration().getInstance(langClassName, null));
271             } catch (Exception JavaDoc err) {
272                 numberer = defaultNumberer;
273             }
274         }
275
276         return numberer;
277      }
278 }
279
280 //
281
// The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
282
// you may not use this file except in compliance with the License. You may obtain a copy of the
283
// License at http://www.mozilla.org/MPL/
284
//
285
// Software distributed under the License is distributed on an "AS IS" basis,
286
// WITHOUT WARRANTY OF ANY KIND, either express or implied.
287
// See the License for the specific language governing rights and limitations under the License.
288
//
289
// The Original Code is: all this file.
290
//
291
// The Initial Developer of the Original Code is Michael H. Kay.
292
//
293
// Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
294
//
295
// Contributor(s): none.
296
//
297
Popular Tags