in core/cocoon-core/src/main/java/org/apache/cocoon/transformation/I18nTransformer.java [1985:2131]
private String formatNumber(Map params) throws SAXException {
if (params == null) {
throw new SAXException(
this.getClass().getName()
+ ": i18n:number - error in element attributes."
);
}
// from pattern
String srcPattern = (String)params.get(I18N_SRC_PATTERN_ATTRIBUTE);
// to pattern
String pattern = (String)params.get(I18N_PATTERN_ATTRIBUTE);
// the number value
String value = (String)params.get(I18N_VALUE_ATTRIBUTE);
if (value == null) return "";
// type
String type = (String)params.get(I18N_TYPE_ATTRIBUTE);
// fraction-digits
int fractionDigits = -1;
try {
String fd = (String)params.get(I18N_FRACTION_DIGITS_ATTRIBUTE);
if (fd != null)
fractionDigits = Integer.parseInt(fd);
} catch (NumberFormatException nfe) {
getLogger().warn("Error in number format with fraction-digits", nfe);
}
// parsed number
Number numberValue;
// locale, may be switched locale
Locale loc = getLocale(params, I18N_LOCALE_ATTRIBUTE);
Locale srcLoc = getLocale(params, I18N_SRC_LOCALE_ATTRIBUTE);
// currency locale
Locale currencyLoc = getLocale(params, CURRENCY_LOCALE_ATTRIBUTE);
// decimal and grouping locale
Locale dgLoc = null;
if (currencyLoc != null) {
// the reasoning here is: if there is a currency locale, then start from that
// one but take certain properties (like decimal and grouping seperation symbols)
// from the default locale (this happens further on).
dgLoc = loc;
loc = currencyLoc;
}
// src format
DecimalFormat from_fmt = (DecimalFormat)NumberFormat.getInstance(srcLoc);
int int_currency = 0;
// src-pattern overwrites locale format
if (srcPattern != null) {
from_fmt.applyPattern(srcPattern);
}
// to format
DecimalFormat to_fmt;
char dec = from_fmt.getDecimalFormatSymbols().getDecimalSeparator();
int decAt = 0;
boolean appendDec = false;
if (type == null || type.equals( I18N_NUMBER_ELEMENT )) {
to_fmt = (DecimalFormat)NumberFormat.getInstance(loc);
to_fmt.setMaximumFractionDigits(309);
for (int i = value.length() - 1;
i >= 0 && value.charAt(i) != dec; i--, decAt++) {
}
if (decAt < value.length())to_fmt.setMinimumFractionDigits(decAt);
decAt = 0;
for (int i = 0; i < value.length() && value.charAt(i) != dec; i++) {
if (Character.isDigit(value.charAt(i))) {
decAt++;
}
}
to_fmt.setMinimumIntegerDigits(decAt);
if (value.charAt(value.length() - 1) == dec) {
appendDec = true;
}
} else if (type.equals( I18N_CURRENCY_ELEMENT )) {
to_fmt = (DecimalFormat)NumberFormat.getCurrencyInstance(loc);
} else if (type.equals( I18N_INT_CURRENCY_ELEMENT )) {
to_fmt = (DecimalFormat)NumberFormat.getCurrencyInstance(loc);
int_currency = 1;
for (int i = 0; i < to_fmt.getMaximumFractionDigits(); i++) {
int_currency *= 10;
}
} else if ( type.equals( I18N_CURRENCY_NO_UNIT_ELEMENT ) ) {
DecimalFormat tmp = (DecimalFormat) NumberFormat.getCurrencyInstance( loc );
to_fmt = (DecimalFormat) NumberFormat.getInstance( loc );
to_fmt.setMinimumFractionDigits(tmp.getMinimumFractionDigits());
to_fmt.setMaximumFractionDigits(tmp.getMaximumFractionDigits());
} else if ( type.equals( I18N_INT_CURRENCY_NO_UNIT_ELEMENT ) ) {
DecimalFormat tmp = (DecimalFormat) NumberFormat.getCurrencyInstance( loc );
int_currency = 1;
for ( int i = 0; i < tmp.getMaximumFractionDigits(); i++ )
int_currency *= 10;
to_fmt = (DecimalFormat) NumberFormat.getInstance( loc );
to_fmt.setMinimumFractionDigits(tmp.getMinimumFractionDigits());
to_fmt.setMaximumFractionDigits(tmp.getMaximumFractionDigits());
} else if (type.equals( I18N_PERCENT_ELEMENT )) {
to_fmt = (DecimalFormat)NumberFormat.getPercentInstance(loc);
} else {
throw new SAXException("<i18n:number>: unknown type: " + type);
}
if(fractionDigits > -1) {
to_fmt.setMinimumFractionDigits(fractionDigits);
to_fmt.setMaximumFractionDigits(fractionDigits);
}
if(dgLoc != null) {
DecimalFormat df = (DecimalFormat)NumberFormat.getCurrencyInstance(dgLoc);
DecimalFormatSymbols dfsNew = df.getDecimalFormatSymbols();
DecimalFormatSymbols dfsOrig = to_fmt.getDecimalFormatSymbols();
dfsOrig.setDecimalSeparator(dfsNew.getDecimalSeparator());
dfsOrig.setMonetaryDecimalSeparator(dfsNew.getMonetaryDecimalSeparator());
dfsOrig.setGroupingSeparator(dfsNew.getGroupingSeparator());
to_fmt.setDecimalFormatSymbols(dfsOrig);
}
// pattern overwrites locale format
if (pattern != null) {
to_fmt.applyPattern(pattern);
}
try {
numberValue = from_fmt.parse(value);
if (int_currency > 0) {
numberValue = new Double(numberValue.doubleValue() / int_currency);
} else {
// what?
}
} catch (ParseException pe) {
throw new SAXException(this.getClass().getName() + "i18n:number - parsing error.", pe);
}
// we have all necessary data here: do formatting.
String result = to_fmt.format(numberValue);
if (appendDec) result = result + dec;
if (getLogger().isDebugEnabled()) {
getLogger().debug("i18n:number result: " + result);
}
return result;
}