KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > xpath > objects > XNumber


1 /*
2  * Copyright 1999-2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 /*
17  * $Id: XNumber.java,v 1.19 2004/02/17 04:34:38 minchau Exp $
18  */

19 package org.apache.xpath.objects;
20
21 import org.apache.xpath.ExpressionOwner;
22 import org.apache.xpath.XPathContext;
23 import org.apache.xpath.XPathVisitor;
24
25 /**
26  * This class represents an XPath number, and is capable of
27  * converting the number to other types, such as a string.
28  * @xsl.usage general
29  */

30 public class XNumber extends XObject
31 {
32
33   /** Value of the XNumber object.
34    * @serial */

35   double m_val;
36
37   /**
38    * Construct a XNodeSet object.
39    *
40    * @param d Value of the object
41    */

42   public XNumber(double d)
43   {
44     super();
45
46     m_val = d;
47   }
48   
49   /**
50    * Construct a XNodeSet object.
51    *
52    * @param d Value of the object
53    */

54   public XNumber(Number JavaDoc num)
55   {
56
57     super();
58
59     m_val = num.doubleValue();
60     m_obj = num;
61   }
62
63   /**
64    * Tell that this is a CLASS_NUMBER.
65    *
66    * @return node type CLASS_NUMBER
67    */

68   public int getType()
69   {
70     return CLASS_NUMBER;
71   }
72
73   /**
74    * Given a request type, return the equivalent string.
75    * For diagnostic purposes.
76    *
77    * @return type string "#NUMBER"
78    */

79   public String JavaDoc getTypeString()
80   {
81     return "#NUMBER";
82   }
83
84   /**
85    * Cast result object to a number.
86    *
87    * @return the value of the XNumber object
88    */

89   public double num()
90   {
91     return m_val;
92   }
93   
94   /**
95    * Evaluate expression to a number.
96    *
97    * @return 0.0
98    *
99    * @throws javax.xml.transform.TransformerException
100    */

101   public double num(XPathContext xctxt)
102     throws javax.xml.transform.TransformerException JavaDoc
103   {
104
105     return m_val;
106   }
107
108   /**
109    * Cast result object to a boolean.
110    *
111    * @return false if the value is NaN or equal to 0.0
112    */

113   public boolean bool()
114   {
115     return (Double.isNaN(m_val) || (m_val == 0.0)) ? false : true;
116   }
117
118 // /**
119
// * Cast result object to a string.
120
// *
121
// * @return "NaN" if the number is NaN, Infinity or -Infinity if
122
// * the number is infinite or the string value of the number.
123
// */
124
// private static final int PRECISION = 16;
125
// public String str()
126
// {
127
//
128
// if (Double.isNaN(m_val))
129
// {
130
// return "NaN";
131
// }
132
// else if (Double.isInfinite(m_val))
133
// {
134
// if (m_val > 0)
135
// return "Infinity";
136
// else
137
// return "-Infinity";
138
// }
139
//
140
// long longVal = (long)m_val;
141
// if ((double)longVal == m_val)
142
// return Long.toString(longVal);
143
//
144
//
145
// String s = Double.toString(m_val);
146
// int len = s.length();
147
//
148
// if (s.charAt(len - 2) == '.' && s.charAt(len - 1) == '0')
149
// {
150
// return s.substring(0, len - 2);
151
// }
152
//
153
// int exp = 0;
154
// int e = s.indexOf('E');
155
// if (e != -1)
156
// {
157
// exp = Integer.parseInt(s.substring(e + 1));
158
// s = s.substring(0,e);
159
// len = e;
160
// }
161
//
162
// // Calculate Significant Digits:
163
// // look from start of string for first digit
164
// // look from end for last digit
165
// // significant digits = end - start + (0 or 1 depending on decimal location)
166
//
167
// int decimalPos = -1;
168
// int start = (s.charAt(0) == '-') ? 1 : 0;
169
// findStart: for( ; start < len; start++ )
170
// {
171
// switch (s.charAt(start))
172
// {
173
// case '0':
174
// break;
175
// case '.':
176
// decimalPos = start;
177
// break;
178
// default:
179
// break findStart;
180
// }
181
// }
182
// int end = s.length() - 1;
183
// findEnd: for( ; end > start; end-- )
184
// {
185
// switch (s.charAt(end))
186
// {
187
// case '0':
188
// break;
189
// case '.':
190
// decimalPos = end;
191
// break;
192
// default:
193
// break findEnd;
194
// }
195
// }
196
//
197
// int sigDig = end - start;
198
//
199
// // clarify decimal location if it has not yet been found
200
// if (decimalPos == -1)
201
// decimalPos = s.indexOf('.');
202
//
203
// // if decimal is not between start and end, add one to sigDig
204
// if (decimalPos < start || decimalPos > end)
205
// ++sigDig;
206
//
207
// // reduce significant digits to PRECISION if necessary
208
// if (sigDig > PRECISION)
209
// {
210
// // re-scale BigDecimal in order to get significant digits = PRECISION
211
// BigDecimal num = new BigDecimal(s);
212
// int newScale = num.scale() - (sigDig - PRECISION);
213
// if (newScale < 0)
214
// newScale = 0;
215
// s = num.setScale(newScale, BigDecimal.ROUND_HALF_UP).toString();
216
//
217
// // remove trailing '0's; keep track of decimalPos
218
// int truncatePoint = s.length();
219
// while (s.charAt(--truncatePoint) == '0')
220
// ;
221
//
222
// if (s.charAt(truncatePoint) == '.')
223
// {
224
// decimalPos = truncatePoint;
225
// }
226
// else
227
// {
228
// decimalPos = s.indexOf('.');
229
// truncatePoint += 1;
230
// }
231
//
232
// s = s.substring(0, truncatePoint);
233
// len = s.length();
234
// }
235
//
236
// // Account for exponent by adding zeros as needed
237
// // and moving the decimal place
238
//
239
// if (exp == 0)
240
// return s;
241
//
242
// start = 0;
243
// String sign;
244
// if (s.charAt(0) == '-')
245
// {
246
// sign = "-";
247
// start++;
248
// }
249
// else
250
// sign = "";
251
//
252
// String wholePart = s.substring(start, decimalPos);
253
// String decimalPart = s.substring(decimalPos + 1);
254
//
255
// // get the number of digits right of the decimal
256
// int decimalLen = decimalPart.length();
257
//
258
// if (exp >= decimalLen)
259
// return sign + wholePart + decimalPart + zeros(exp - decimalLen);
260
//
261
// if (exp > 0)
262
// return sign + wholePart + decimalPart.substring(0, exp) + "."
263
// + decimalPart.substring(exp);
264
//
265
// return sign + "0." + zeros(-1 - exp) + wholePart + decimalPart;
266
// }
267

268   /**
269    * Cast result object to a string.
270    *
271    * @return "NaN" if the number is NaN, Infinity or -Infinity if
272    * the number is infinite or the string value of the number.
273    */

274   public String JavaDoc str()
275   {
276
277     if (Double.isNaN(m_val))
278     {
279       return "NaN";
280     }
281     else if (Double.isInfinite(m_val))
282     {
283       if (m_val > 0)
284         return "Infinity";
285       else
286         return "-Infinity";
287     }
288
289     double num = m_val;
290     String JavaDoc s = Double.toString(num);
291     int len = s.length();
292
293     if (s.charAt(len - 2) == '.' && s.charAt(len - 1) == '0')
294     {
295       s = s.substring(0, len - 2);
296
297       if (s.equals("-0"))
298         return "0";
299
300       return s;
301     }
302
303     int e = s.indexOf('E');
304
305     if (e < 0)
306     {
307       if (s.charAt(len - 1) == '0')
308         return s.substring(0, len - 1);
309       else
310         return s;
311     }
312
313     int exp = Integer.parseInt(s.substring(e + 1));
314     String JavaDoc sign;
315
316     if (s.charAt(0) == '-')
317     {
318       sign = "-";
319       s = s.substring(1);
320
321       --e;
322     }
323     else
324       sign = "";
325
326     int nDigits = e - 2;
327
328     if (exp >= nDigits)
329       return sign + s.substring(0, 1) + s.substring(2, e)
330              + zeros(exp - nDigits);
331
332     // Eliminate trailing 0's - bugzilla 14241
333
while (s.charAt(e-1) == '0')
334       e--;
335          
336     if (exp > 0)
337       return sign + s.substring(0, 1) + s.substring(2, 2 + exp) + "."
338              + s.substring(2 + exp, e);
339
340     return sign + "0." + zeros(-1 - exp) + s.substring(0, 1)
341            + s.substring(2, e);
342   }
343
344
345   /**
346    * Return a string of '0' of the given length
347    *
348    *
349    * @param n Length of the string to be returned
350    *
351    * @return a string of '0' with the given length
352    */

353   static private String JavaDoc zeros(int n)
354   {
355     if (n < 1)
356       return "";
357
358     char[] buf = new char[n];
359
360     for (int i = 0; i < n; i++)
361     {
362       buf[i] = '0';
363     }
364
365     return new String JavaDoc(buf);
366   }
367
368   /**
369    * Return a java object that's closest to the representation
370    * that should be handed to an extension.
371    *
372    * @return The value of this XNumber as a Double object
373    */

374   public Object JavaDoc object()
375   {
376     if(null == m_obj)
377       m_obj = new Double JavaDoc(m_val);
378     return m_obj;
379   }
380
381   /**
382    * Tell if two objects are functionally equal.
383    *
384    * @param obj2 Object to compare this to
385    *
386    * @return true if the two objects are equal
387    *
388    * @throws javax.xml.transform.TransformerException
389    */

390   public boolean equals(XObject obj2)
391   {
392
393     // In order to handle the 'all' semantics of
394
// nodeset comparisons, we always call the
395
// nodeset function.
396
int t = obj2.getType();
397     try
398     {
399         if (t == XObject.CLASS_NODESET)
400           return obj2.equals(this);
401         else if(t == XObject.CLASS_BOOLEAN)
402           return obj2.bool() == bool();
403         else
404            return m_val == obj2.num();
405     }
406     catch(javax.xml.transform.TransformerException JavaDoc te)
407     {
408       throw new org.apache.xml.utils.WrappedRuntimeException(te);
409     }
410   }
411   
412   /**
413    * Tell if this expression returns a stable number that will not change during
414    * iterations within the expression. This is used to determine if a proximity
415    * position predicate can indicate that no more searching has to occur.
416    *
417    *
418    * @return true if the expression represents a stable number.
419    */

420   public boolean isStableNumber()
421   {
422     return true;
423   }
424   
425   /**
426    * @see XPathVisitable#callVisitors(ExpressionOwner, XPathVisitor)
427    */

428   public void callVisitors(ExpressionOwner owner, XPathVisitor visitor)
429   {
430     visitor.visitNumberLiteral(owner, this);
431   }
432
433
434 }
435
Popular Tags