All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.fathzer.soft.javaluator.examples.LocalizedEvaluator Maven / Gradle / Ivy

package com.fathzer.soft.javaluator.examples;

import java.text.NumberFormat;
import java.text.ParseException;
import java.util.Locale;

import com.fathzer.soft.javaluator.DoubleEvaluator;
import com.fathzer.soft.javaluator.Parameters;

/** An example of how to localize an existing evaluator to match French locale.
 * 
As a French, I prefer "moyenne" to "avg" and "somme" to "sum". *
As the default argument function (',') is used as decimal separator in France, * I may also change it to ';'. *
Here is how I can do that very easily. */ public class LocalizedEvaluator extends DoubleEvaluator { /** Defines the new function (square root).*/ private static final Parameters PARAMS; static { // Gets the default DoubleEvaluator's parameters PARAMS = DoubleEvaluator.getDefaultParameters(); // adds the translations PARAMS.setTranslation(DoubleEvaluator.SUM, "somme"); PARAMS.setTranslation(DoubleEvaluator.AVERAGE, "moyenne"); // Change the default function separator PARAMS.setFunctionArgumentSeparator(';'); } private final NumberFormat format; private final char effectiveThousandsSeparator; public LocalizedEvaluator() { super(PARAMS); // Create a French number formatter format = NumberFormat.getInstance(Locale.FRENCH); format.setGroupingUsed(true); // Unfortunately, Java treatment of French thousands separator is ... weird: // Most French people (like me some years ago) think the separator is a space. // But java thought (at least until java 8) it was Non-breaking space. But since // (at least Java 17) they changed their mind and now it's "Espace fine insécable". // As they have other priorities than the stability of their API, trying to parse // with the wrong category of space gives a wrong result. // Let's try to be kind with or users: We will replace all kind of spaces by the one java accepts effectiveThousandsSeparator = format.format(1000.0).charAt(1); } @Override protected Double toValue(String literal, Object evaluationContext) { // Override the method that converts a literal to a number, in order to match with // the French decimal separator try { // For a strange reason, Java thinks that only "fine non breaking spaces" or "non breaking spaces" are // French thousands separators. So, we will replace all kind of spaces in the literal by the java one literal = literal.replace(' ', effectiveThousandsSeparator); literal = literal.replace((char)0x00A0, effectiveThousandsSeparator); literal = literal.replace((char)0x202F, effectiveThousandsSeparator); return format.parse(literal).doubleValue(); } catch (ParseException e) { // If the number has a wrong format, throw the right exception. throw new IllegalArgumentException(literal+" is not a number"); } } public static void main(String[] args) { // Test that all this stuff is ok LocalizedEvaluator evaluator = new LocalizedEvaluator(); String expression = "3 000 +moyenne(3 ; somme(1,5 ; 7 ; -3,5))"; System.out.println (expression+" = "+evaluator.format.format(evaluator.evaluate(expression))); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy