1 52 53 package freemarker.core; 54 55 import java.io.IOException ; 56 import java.text.NumberFormat ; 57 import java.util.Locale ; 58 import freemarker.template.*; 59 60 64 final class NumericalOutput extends TemplateElement { 65 66 private final Expression expression; 67 private final boolean hasFormat; 68 private final int minFracDigits; 69 private final int maxFracDigits; 70 private volatile FormatHolder formatCache; 72 NumericalOutput(Expression expression) { 73 this.expression = expression; 74 hasFormat = false; 75 this.minFracDigits = 0; 76 this.maxFracDigits = 0; 77 } 78 79 NumericalOutput(Expression expression, 80 int minFracDigits, 81 int maxFracDigits) 82 { 83 this.expression = expression; 84 hasFormat = true; 85 this.minFracDigits = minFracDigits; 86 this.maxFracDigits = maxFracDigits; 87 } 88 89 void accept(Environment env) throws TemplateException, IOException 90 { 91 Number num = EvaluationUtil.getNumber(expression, env); 92 93 FormatHolder fmth = formatCache; if (fmth == null || !fmth.locale.equals(env.getLocale())) { 95 synchronized(this) { 96 fmth = formatCache; 97 if (fmth == null || !fmth.locale.equals(env.getLocale())) { 98 NumberFormat fmt = NumberFormat.getNumberInstance(env.getLocale()); 99 if (hasFormat) { 100 fmt.setMinimumFractionDigits(minFracDigits); 101 fmt.setMaximumFractionDigits(maxFracDigits); 102 } else { 103 fmt.setMinimumFractionDigits(0); 104 fmt.setMaximumFractionDigits(50); 105 } 106 fmt.setGroupingUsed(false); 107 formatCache = new FormatHolder(fmt, env.getLocale()); 108 fmth = formatCache; 109 } 110 } 111 } 112 env.getOut().write(fmth.format.format(num)); 116 } 117 118 public String getCanonicalForm() { 119 StringBuffer buf = new StringBuffer ("#{"); 120 buf.append(expression.getCanonicalForm()); 121 if (hasFormat) { 122 buf.append(" ; "); 123 buf.append("m"); 124 buf.append(minFracDigits); 125 buf.append("M"); 126 buf.append(maxFracDigits); 127 } 128 buf.append("}"); 129 return buf.toString(); 130 } 131 132 public String getDescription() { 133 return getSource(); 134 } 135 136 boolean heedsOpeningWhitespace() { 137 return true; 138 } 139 140 boolean heedsTrailingWhitespace() { 141 return true; 142 } 143 144 private class FormatHolder { 145 final NumberFormat format; 146 final Locale locale; 147 148 FormatHolder(NumberFormat format, Locale locale) { 149 this.format = format; 150 this.locale = locale; 151 } 152 } 153 } 154 | Popular Tags |