KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > icl > saxon > functions > FormatNumber


1 package com.icl.saxon.functions;
2 import com.icl.saxon.*;
3 import com.icl.saxon.expr.*;
4
5 //import java.util.*;
6
//import java.lang.Math;
7
import java.text.*;
8
9
10
11 public class FormatNumber extends Function {
12
13     private DecimalFormat decimalFormat = new DecimalFormat();
14     private String JavaDoc previousFormat = "[null]";
15     private DecimalFormatSymbols previousDFS = null;
16     private Controller boundController = null;
17
18     public String JavaDoc getName() {
19         return "format-number";
20     };
21
22     /**
23     * Determine the data type of the exprEssion
24     * @return Value.STRING
25     */

26
27     public int getDataType() {
28         return Value.STRING;
29     }
30
31     /**
32     * Simplify and validate
33     */

34
35     public Expression simplify() throws XPathException {
36         int numArgs = checkArgumentCount(2, 3);
37
38         // Note, even if all arguments are known we can't pre-evaluate the
39
// function because we don't have access to the DecimalFormatManager
40

41         argument[0] = argument[0].simplify();
42         argument[1] = argument[1].simplify();
43         if (numArgs==3) {
44             argument[2] = argument[2].simplify();
45         }
46         return this;
47         
48     }
49
50     /**
51     * Evaluate in a context where a string is wanted
52     */

53
54     public String JavaDoc evaluateAsString(Context context) throws XPathException {
55         int numArgs = getNumberOfArguments();
56
57         Controller ctrl = boundController;
58         if (ctrl==null) {
59             ctrl = context.getController();
60         }
61         DecimalFormatManager dfm = ctrl.getDecimalFormatManager();
62         DecimalFormatSymbols dfs;
63
64         double number = argument[0].evaluateAsNumber(context);
65         String JavaDoc format = argument[1].evaluateAsString(context);
66         
67         if (numArgs==2) {
68             dfs = dfm.getDefaultDecimalFormat();
69         } else {
70             String JavaDoc df = argument[2].evaluateAsString(context);
71             int dfnum = getStaticContext().getFingerprint(df, false);
72             dfs = dfm.getNamedDecimalFormat(dfnum);
73             if (dfs==null) {
74                 throw new XPathException(
75                     "format-number function: decimal-format " + df + " not registered");
76             }
77         }
78         return formatNumber(number, format, dfs);
79     }
80
81     /**
82     * Evaluate in a general context
83     */

84
85     public Value evaluate(Context c) throws XPathException {
86         return new StringValue(evaluateAsString(c));
87     }
88
89     /**
90     * Here is the method that does the work. It needs to be synchronized because
91     * it remembers information from one invocation to the next; it doesn't matter
92     * if these are in different threads but it can't be interrupted. The reason for
93     * remembering information is that getting a new DecimalFormatSymbols each time
94     * is incredibly expensive, especially with the Microsoft Java VM. Actually
95     * the synchronization is unnecessary if there is a bound Controller.
96     */

97
98     public synchronized String JavaDoc
99             formatNumber(double n, String JavaDoc format, DecimalFormatSymbols dfs)
100             throws XPathException {
101         try {
102             DecimalFormat df = decimalFormat;
103             if (!(dfs==previousDFS && format.equals(previousFormat))) {
104                 df.setDecimalFormatSymbols(dfs);
105                 df.applyLocalizedPattern(format);
106                 previousDFS = dfs;
107                 previousFormat = format;
108             }
109             return df.format(n);
110         } catch (Exception JavaDoc err) {
111             throw new XPathException("Unable to interpret format pattern " + format + " (" + err + ")");
112         }
113     }
114
115     /**
116     * Determine the dependencies
117     */

118
119     public int getDependencies() {
120         int dep = 0;
121         if (boundController==null) {
122             dep = Context.CONTROLLER;
123         }
124         dep |= argument[0].getDependencies();
125         dep |= argument[1].getDependencies();
126         if (getNumberOfArguments()==3) {
127             dep |= argument[2].getDependencies();
128         }
129         return dep;
130     }
131
132     /**
133     * Reduce the dependencies
134     */

135
136     public Expression reduce(int dep, Context c) throws XPathException {
137         FormatNumber f = new FormatNumber();
138         f.addArgument(argument[0].reduce(dep, c));
139         f.addArgument(argument[1].reduce(dep, c));
140         if (getNumberOfArguments()==3) {
141             f.addArgument(argument[2].reduce(dep, c));
142         }
143         if ((dep & Context.CONTROLLER) != 0) {
144             f.boundController = c.getController();
145         }
146         f.setStaticContext(getStaticContext());
147         return f;
148     }
149
150
151 }
152
153
154
155 //
156
// The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
157
// you may not use this file except in compliance with the License. You may obtain a copy of the
158
// License at http://www.mozilla.org/MPL/
159
//
160
// Software distributed under the License is distributed on an "AS IS" basis,
161
// WITHOUT WARRANTY OF ANY KIND, either express or implied.
162
// See the License for the specific language governing rights and limitations under the License.
163
//
164
// The Original Code is: all this file.
165
//
166
// The Initial Developer of the Original Code is
167
// Michael Kay of International Computers Limited (mhkay@iclway.co.uk).
168
//
169
// Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
170
//
171
// Contributor(s): none.
172
//
173
Popular Tags