1. /*
  2. * Copyright 2001-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: FormatNumberCall.java,v 1.11 2004/02/16 22:24:28 minchau Exp $
  18. */
  19. package com.sun.org.apache.xalan.internal.xsltc.compiler;
  20. import java.util.Vector;
  21. import com.sun.org.apache.bcel.internal.generic.ConstantPoolGen;
  22. import com.sun.org.apache.bcel.internal.generic.INVOKESTATIC;
  23. import com.sun.org.apache.bcel.internal.generic.INVOKEVIRTUAL;
  24. import com.sun.org.apache.bcel.internal.generic.InstructionList;
  25. import com.sun.org.apache.bcel.internal.generic.PUSH;
  26. import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ClassGenerator;
  27. import com.sun.org.apache.xalan.internal.xsltc.compiler.util.MethodGenerator;
  28. import com.sun.org.apache.xalan.internal.xsltc.compiler.util.RealType;
  29. import com.sun.org.apache.xalan.internal.xsltc.compiler.util.StringType;
  30. import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type;
  31. import com.sun.org.apache.xalan.internal.xsltc.compiler.util.TypeCheckError;
  32. /**
  33. * @author Jacek Ambroziak
  34. * @author Santiago Pericas-Geertsen
  35. * @author Morten Jorgensen
  36. */
  37. final class FormatNumberCall extends FunctionCall {
  38. private Expression _value;
  39. private Expression _format;
  40. private Expression _name;
  41. private QName _resolvedQName = null;
  42. public FormatNumberCall(QName fname, Vector arguments) {
  43. super(fname, arguments);
  44. _value = argument(0);
  45. _format = argument(1);
  46. _name = argumentCount() == 3 ? argument(2) : null;
  47. }
  48. public Type typeCheck(SymbolTable stable) throws TypeCheckError {
  49. // Inform stylesheet to instantiate a DecimalFormat object
  50. getStylesheet().numberFormattingUsed();
  51. final Type tvalue = _value.typeCheck(stable);
  52. if (tvalue instanceof RealType == false) {
  53. _value = new CastExpr(_value, Type.Real);
  54. }
  55. final Type tformat = _format.typeCheck(stable);
  56. if (tformat instanceof StringType == false) {
  57. _format = new CastExpr(_format, Type.String);
  58. }
  59. if (argumentCount() == 3) {
  60. final Type tname = _name.typeCheck(stable);
  61. if (_name instanceof LiteralExpr) {
  62. final LiteralExpr literal = (LiteralExpr) _name;
  63. _resolvedQName =
  64. getParser().getQNameIgnoreDefaultNs(literal.getValue());
  65. }
  66. else if (tname instanceof StringType == false) {
  67. _name = new CastExpr(_name, Type.String);
  68. }
  69. }
  70. return _type = Type.String;
  71. }
  72. public void translate(ClassGenerator classGen, MethodGenerator methodGen) {
  73. final ConstantPoolGen cpg = classGen.getConstantPool();
  74. final InstructionList il = methodGen.getInstructionList();
  75. _value.translate(classGen, methodGen);
  76. _format.translate(classGen, methodGen);
  77. final int fn3arg = cpg.addMethodref(BASIS_LIBRARY_CLASS,
  78. "formatNumber",
  79. "(DLjava/lang/String;"+
  80. "Ljava/text/DecimalFormat;)"+
  81. "Ljava/lang/String;");
  82. final int get = cpg.addMethodref(TRANSLET_CLASS,
  83. "getDecimalFormat",
  84. "(Ljava/lang/String;)"+
  85. "Ljava/text/DecimalFormat;");
  86. il.append(classGen.loadTranslet());
  87. if (_name == null) {
  88. il.append(new PUSH(cpg, EMPTYSTRING));
  89. }
  90. else if (_resolvedQName != null) {
  91. il.append(new PUSH(cpg, _resolvedQName.toString()));
  92. }
  93. else {
  94. _name.translate(classGen, methodGen);
  95. }
  96. il.append(new INVOKEVIRTUAL(get));
  97. il.append(new INVOKESTATIC(fn3arg));
  98. }
  99. }