View Javadoc
1   /*
2    * reserved comment block
3    * DO NOT REMOVE OR ALTER!
4    */
5   /*
6    * Copyright 2001-2004 The Apache Software Foundation.
7    *
8    * Licensed under the Apache License, Version 2.0 (the "License");
9    * you may not use this file except in compliance with the License.
10   * You may obtain a copy of the License at
11   *
12   *     http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing, software
15   * distributed under the License is distributed on an "AS IS" BASIS,
16   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17   * See the License for the specific language governing permissions and
18   * limitations under the License.
19   */
20  /*
21   * $Id: FormatNumberCall.java,v 1.2.4.1 2005/09/01 15:26:46 pvedula Exp $
22   */
23  
24  package com.sun.org.apache.xalan.internal.xsltc.compiler;
25  
26  import java.util.Vector;
27  
28  import com.sun.org.apache.bcel.internal.generic.ConstantPoolGen;
29  import com.sun.org.apache.bcel.internal.generic.INVOKESTATIC;
30  import com.sun.org.apache.bcel.internal.generic.INVOKEVIRTUAL;
31  import com.sun.org.apache.bcel.internal.generic.InstructionList;
32  import com.sun.org.apache.bcel.internal.generic.PUSH;
33  import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ClassGenerator;
34  import com.sun.org.apache.xalan.internal.xsltc.compiler.util.MethodGenerator;
35  import com.sun.org.apache.xalan.internal.xsltc.compiler.util.RealType;
36  import com.sun.org.apache.xalan.internal.xsltc.compiler.util.StringType;
37  import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type;
38  import com.sun.org.apache.xalan.internal.xsltc.compiler.util.TypeCheckError;
39  
40  /**
41   * @author Jacek Ambroziak
42   * @author Santiago Pericas-Geertsen
43   * @author Morten Jorgensen
44   */
45  final class FormatNumberCall extends FunctionCall {
46      private Expression _value;
47      private Expression _format;
48      private Expression _name;
49      private QName      _resolvedQName = null;
50  
51      public FormatNumberCall(QName fname, Vector arguments) {
52          super(fname, arguments);
53          _value = argument(0);
54          _format = argument(1);
55          _name = argumentCount() == 3 ? argument(2) : null;
56      }
57  
58      public Type typeCheck(SymbolTable stable) throws TypeCheckError {
59  
60          // Inform stylesheet to instantiate a DecimalFormat object
61          getStylesheet().numberFormattingUsed();
62  
63          final Type tvalue = _value.typeCheck(stable);
64          if (tvalue instanceof RealType == false) {
65              _value = new CastExpr(_value, Type.Real);
66          }
67          final Type tformat = _format.typeCheck(stable);
68          if (tformat instanceof StringType == false) {
69              _format = new CastExpr(_format, Type.String);
70          }
71          if (argumentCount() == 3) {
72              final Type tname = _name.typeCheck(stable);
73  
74              if (_name instanceof LiteralExpr) {
75                  final LiteralExpr literal = (LiteralExpr) _name;
76                  _resolvedQName =
77                      getParser().getQNameIgnoreDefaultNs(literal.getValue());
78              }
79              else if (tname instanceof StringType == false) {
80                  _name = new CastExpr(_name, Type.String);
81              }
82          }
83          return _type = Type.String;
84      }
85  
86      public void translate(ClassGenerator classGen, MethodGenerator methodGen) {
87          final ConstantPoolGen cpg = classGen.getConstantPool();
88          final InstructionList il = methodGen.getInstructionList();
89  
90          _value.translate(classGen, methodGen);
91          _format.translate(classGen, methodGen);
92  
93          final int fn3arg = cpg.addMethodref(BASIS_LIBRARY_CLASS,
94                                              "formatNumber",
95                                              "(DLjava/lang/String;"+
96                                              "Ljava/text/DecimalFormat;)"+
97                                              "Ljava/lang/String;");
98          final int get = cpg.addMethodref(TRANSLET_CLASS,
99                                           "getDecimalFormat",
100                                          "(Ljava/lang/String;)"+
101                                          "Ljava/text/DecimalFormat;");
102 
103         il.append(classGen.loadTranslet());
104         if (_name == null) {
105             il.append(new PUSH(cpg, EMPTYSTRING));
106         }
107         else if (_resolvedQName != null) {
108             il.append(new PUSH(cpg, _resolvedQName.toString()));
109         }
110         else {
111             _name.translate(classGen, methodGen);
112         }
113         il.append(new INVOKEVIRTUAL(get));
114         il.append(new INVOKESTATIC(fn3arg));
115     }
116 }