19f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson/* 29f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Licensed to the Apache Software Foundation (ASF) under one 39f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * or more contributor license agreements. See the NOTICE file 49f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * distributed with this work for additional information 59f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * regarding copyright ownership. The ASF licenses this file 69f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * to you under the Apache License, Version 2.0 (the "License"); 79f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * you may not use this file except in compliance with the License. 89f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * You may obtain a copy of the License at 99f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * http://www.apache.org/licenses/LICENSE-2.0 119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Unless required by applicable law or agreed to in writing, software 139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * distributed under the License is distributed on an "AS IS" BASIS, 149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * See the License for the specific language governing permissions and 169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * limitations under the License. 179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson/* 199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * $Id: FuncFormatNumb.java 468643 2006-10-28 06:56:03Z minchau $ 209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonpackage org.apache.xalan.templates; 229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport javax.xml.transform.ErrorListener; 249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport javax.xml.transform.TransformerException; 259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xalan.res.XSLMessages; 279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xalan.res.XSLTErrorResources; 289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xml.utils.QName; 299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xml.utils.SAXSourceLocator; 309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xpath.Expression; 319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xpath.XPathContext; 329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xpath.functions.Function3Args; 339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xpath.functions.WrongNumberArgsException; 349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xpath.objects.XObject; 359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xpath.objects.XString; 369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson/** 389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Execute the FormatNumber() function. 399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @xsl.usage advanced 409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonpublic class FuncFormatNumb extends Function3Args 429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson{ 439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson static final long serialVersionUID = -8869935264870858636L; 449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Execute the function. The function must return 479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * a valid object. 489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param xctxt The current execution context. 499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @return A valid XObject. 509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @throws javax.xml.transform.TransformerException 529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException 549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // A bit of an ugly hack to get our context. 579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson ElemTemplateElement templElem = 589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson (ElemTemplateElement) xctxt.getNamespaceContext(); 599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson StylesheetRoot ss = templElem.getStylesheetRoot(); 609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson java.text.DecimalFormat formatter = null; 619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson java.text.DecimalFormatSymbols dfs = null; 629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson double num = getArg0().execute(xctxt).num(); 639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson String patternStr = getArg1().execute(xctxt).str(); 649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // TODO: what should be the behavior here?? 669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if (patternStr.indexOf(0x00A4) > 0) 679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson ss.error(XSLTErrorResources.ER_CURRENCY_SIGN_ILLEGAL); // currency sign not allowed 689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // this third argument is not a locale name. It is the name of a 709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // decimal-format declared in the stylesheet!(xsl:decimal-format 719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson try 729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson Expression arg2Expr = getArg2(); 749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if (null != arg2Expr) 769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson String dfName = arg2Expr.execute(xctxt).str(); 789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson QName qname = new QName(dfName, xctxt.getNamespaceContext()); 799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson dfs = ss.getDecimalFormatComposed(qname); 819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if (null == dfs) 839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson warn(xctxt, XSLTErrorResources.WG_NO_DECIMALFORMAT_DECLARATION, 859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson new Object[]{ dfName }); //"not found!!! 869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson //formatter = new java.text.DecimalFormat(patternStr); 889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson else 909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson //formatter = new java.text.DecimalFormat(patternStr, dfs); 939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson formatter = new java.text.DecimalFormat(); 949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson formatter.setDecimalFormatSymbols(dfs); 969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson formatter.applyLocalizedPattern(patternStr); 979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 1009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson //else 1019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if (null == formatter) 1029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 1039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 1049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // look for a possible default decimal-format 1059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson dfs = ss.getDecimalFormatComposed(new QName("")); 1069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 1079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if (dfs != null) 1089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 1099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson formatter = new java.text.DecimalFormat(); 1109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 1119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson formatter.setDecimalFormatSymbols(dfs); 1129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson formatter.applyLocalizedPattern(patternStr); 1139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 1149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson else 1159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 1169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson dfs = new java.text.DecimalFormatSymbols(java.util.Locale.US); 1179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 1189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson dfs.setInfinity(Constants.ATTRVAL_INFINITY); 1199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson dfs.setNaN(Constants.ATTRVAL_NAN); 1209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 1219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson formatter = new java.text.DecimalFormat(); 1229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 1239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson formatter.setDecimalFormatSymbols(dfs); 1249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 1259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if (null != patternStr) 1269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson formatter.applyLocalizedPattern(patternStr); 1279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 1289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 1299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 1309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return new XString(formatter.format(num)); 1319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 1329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson catch (Exception iae) 1339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 1349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson templElem.error(XSLTErrorResources.ER_MALFORMED_FORMAT_STRING, 1359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson new Object[]{ patternStr }); 1369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 1379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return XString.EMPTYSTRING; 1389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 1399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson //throw new XSLProcessorException(iae); 1409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 1419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 1429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 1439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 1449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Warn the user of a problem. 1459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 1469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param xctxt The XPath runtime state. 1479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param msg Warning message key 1489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param args Arguments to be used in warning message 1499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @throws XSLProcessorException thrown if the active ProblemListener and XPathContext decide 1509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * the error condition is severe enough to halt processing. 1519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 1529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @throws javax.xml.transform.TransformerException 1539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 1549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public void warn(XPathContext xctxt, String msg, Object args[]) 1559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson throws javax.xml.transform.TransformerException 1569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 1579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 1589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson String formattedMsg = XSLMessages.createWarning(msg, args); 1599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson ErrorListener errHandler = xctxt.getErrorListener(); 1609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 1619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson errHandler.warning(new TransformerException(formattedMsg, 1629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson (SAXSourceLocator)xctxt.getSAXLocator())); 1639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 1649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 1659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 1669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Overide the superclass method to allow one or two arguments. 1679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 1689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 1699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param argNum Number of arguments passed in 1709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 1719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @throws WrongNumberArgsException 1729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 1739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public void checkNumberArgs(int argNum) throws WrongNumberArgsException 1749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 1759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if ((argNum > 3) || (argNum < 2)) 1769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson reportWrongNumberArgs(); 1779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 1789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 1799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 1809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Constructs and throws a WrongNumberArgException with the appropriate 1819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * message for this function object. 1829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 1839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @throws WrongNumberArgsException 1849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 1859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson protected void reportWrongNumberArgs() throws WrongNumberArgsException { 1869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson throw new WrongNumberArgsException(XSLMessages.createMessage(XSLTErrorResources.ER_TWO_OR_THREE, null)); //"2 or 3"); 1879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 1889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson} 189