[
https://issues.apache.org/jira/browse/FREEMARKER-232?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17946371#comment-17946371
]
Sune Keller commented on FREEMARKER-232:
----------------------------------------
Right now, as long as I do
{code:java}
cfg.setNumberFormat("@bob");{code}
I do not have to explicitly adapt my template contents as long as my
expressions are at least simple.
If I have a class {{FreeMarkerEvaluator}} with the following method, using the
en-GB locale:
{code:java}
@Slf4j
@Component
@RequiredArgsConstructor
public class FreemarkerEvaluator {
public String evaluate(String templateHtml, Map<String, Object> data)
throws TemplateException, IOException {
StringWriter out = new StringWriter(templateHtml.length());
final var cfg = getConfiguration();
cfg.setLocale(Locale.of("en", "GB"));
Template template = new Template(UUID.randomUUID().toString(),
templateHtml, cfg);
template.process(data, out);
log.debug("Successfully evaluated section: {}, using data: {}",
templateHtml, data);
return out.toString();
}
private @NonNull Configuration getConfiguration() {
... (as in the comment above)
}
} {code}
then the following unit tests pass:
{code:java}
@ParameterizedTest
@CsvSource(value = {
"123.45000; 17.5; 124.45000; 19.5",
"12300000000000000.45000; 1700000000000000.500000000000000;
12,300,000,000,000,001.45000; 1,700,000,000,000,002.500000000000000",
}, delimiter = ';')
void
evaluate_givenTemplateWithBigDecimalInArithmeticExpression_thenReturnsEvaluatedString(
String input1,
String input2,
String output1,
String output2) throws TemplateException, IOException {
// Given
String template = "value1 is ${value1 + 1}, value2 is ${value2 + 2}";
final var v1 = new BigDecimal(input1);
final var v2 = new BigDecimal(input2);
Map<String, Object> model = Map.of("value1", v1, "value2", v2);
// When
String result = freemarkerEvaluator.evaluate(template, model);
// Then
assertEquals("value1 is %s, value2 is %s".formatted(output1, output2),
result);
}
@Test
void evaluate_givenTemplateWithOtherNumberFormat_thenReturnsEvaluatedString()
throws TemplateException, IOException {
// Given
String template = "The value is ${value}";
Map<String, Object> model = Map.of("value", new BigInteger("12345000"));
// When
String result = freemarkerEvaluator.evaluate(template, model);
// Then
assertEquals("The value is 12,345,000", result);
} {code}
> Add configuration option to skip call to stripTrailingZeros on BigDecimal
> Numbers
> ---------------------------------------------------------------------------------
>
> Key: FREEMARKER-232
> URL: https://issues.apache.org/jira/browse/FREEMARKER-232
> Project: Apache Freemarker
> Issue Type: Improvement
> Components: engine
> Affects Versions: 2.3.32
> Reporter: Sune Keller
> Priority: Major
>
> When evaluating a template in which the model contains a field for which the
> value is a simple BigDecimal with a given scale and trailing zeros within
> that scale, the trailing zeros are stripped away by the implementation in
> {{{}freemarker.core.CTemplateNumberFormat#formatToPlainText{}}}:
> {code:java}
> } else if (num instanceof BigDecimal) {
> BigDecimal bd = ((BigDecimal) num).stripTrailingZeros();
> int scale = bd.scale();
> if (scale <= 0) {
> // A whole number. Maybe a long ID in a database or other system, and
> for those exponential form is not
> // expected generally, so we avoid that. But then, it becomes too
> easy to write something like
> // 1e1000000000000 and kill the server with a terra byte long
> rendering of the number, so for lengths
> // that realistically aren't ID-s or such, we use exponential format
> after all:
> if (scale <= -100) {
> return bd.toString(); // Will give exponential form for this scale
> }
> return bd.toPlainString(); // Never gives exponential form
> }
> // `db` is not a whole number. Note that `bd` is already normalized to
> not have trailing zeroes.
> return bd.toString(); // Gives exponential form of the absolute value of
> the number is less than 1E-7 {code}
> It would be wonderful to be able to configure whether any trailing zeros are
> stripped or not by way of some configuration option, so as to avoid having to
> copy and re-implement this final non-public class.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)