X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=core%2Fsrc%2Fde%2Fcongrace%2Fexp4j%2FExpressionBuilder.java;fp=core%2Fsrc%2Fde%2Fcongrace%2Fexp4j%2FExpressionBuilder.java;h=8ecf1b5cfa65bea3dbe651d164c627282ff084c5;hb=9349577cdfdff682b2aabd6daa24fdc3a7449b58;hp=0000000000000000000000000000000000000000;hpb=30ba0a882f0c061176ba14dbf86d3d6fad096c02;p=debian%2Fopenrocket diff --git a/core/src/de/congrace/exp4j/ExpressionBuilder.java b/core/src/de/congrace/exp4j/ExpressionBuilder.java new file mode 100644 index 00000000..8ecf1b5c --- /dev/null +++ b/core/src/de/congrace/exp4j/ExpressionBuilder.java @@ -0,0 +1,135 @@ +package de.congrace.exp4j; + +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; + +/** + * This is Builder implementation for the exp4j API used to create a Calculable + * instance for the user + * + * @author ruckus + * + */ +public class ExpressionBuilder { + private VariableSet variables = new VariableSet(); + private final Set customFunctions = new HashSet(); + + private String expression; + + /** + * Create a new ExpressionBuilder + * + * @param expression + * the expression to evaluate + */ + public ExpressionBuilder(String expression) { + this.expression = expression; + } + + /** + * build a new {@link Calculable} from the expression using the supplied + * variables + * + * @return the {@link Calculable} which can be used to evaluate the + * expression + * @throws UnknownFunctionException + * when an unrecognized function name is used in the expression + * @throws UnparsableExpressionException + * if the expression could not be parsed + */ + public Calculable build() throws UnknownFunctionException, UnparsableExpressionException { + if (expression.indexOf('=') == -1 && !variables.isEmpty()) { + + // User supplied an expression without leading "f(...)=" + // so we just append the user function to a proper "f()=" + // for PostfixExpression.fromInfix() + StringBuilder function = new StringBuilder("f("); + for (String name : variables.getVariableNames()) { + function.append(name).append(','); + } + expression = function.deleteCharAt(function.length() - 1).toString() + ")=" + expression; + } + // create the PostfixExpression and return it as a Calculable + PostfixExpression delegate = PostfixExpression.fromInfix(expression, customFunctions); + for (Variable var : variables ) { + delegate.setVariable(var); + for (CustomFunction fn:customFunctions){ + if (fn.getValue().equalsIgnoreCase(var.getName())){ + throw new UnparsableExpressionException("variable '" + var + "' cannot have the same name as a custom function " + fn.getValue()); + } + } + } + return delegate; + } + + /** + * add a custom function instance for the evaluator to recognize + * + * @param function + * the {@link CustomFunction} to add + * @return the {@link ExpressionBuilder} instance + */ + public ExpressionBuilder withCustomFunction(CustomFunction function) { + customFunctions.add(function); + return this; + } + + public ExpressionBuilder withCustomFunctions(Collection functions) { + customFunctions.addAll(functions); + return this; + } + + /** + * set the value for a variable + * + * @param variableName + * the variable name e.g. "x" + * @param value + * the value e.g. 2.32d + * @return the {@link ExpressionBuilder} instance + */ + public ExpressionBuilder withVariable(Variable value) { + variables.add(value); + return this; + } + + /* + * Provided for backwards compatibility + */ + @Deprecated + public ExpressionBuilder withVariable(String variableName, double value) { + variables.add(new Variable(variableName, value)); + return this; + } + + /** + * set the variables names used in the expression without setting their + * values. Usefull for building an expression before you know the variable values. + * + * @param variableNames + * vararg {@link String} of the variable names used in the + * expression + * @return the ExpressionBuilder instance + */ + + public ExpressionBuilder withVariableNames(String... variableNames) { + for (String name : variableNames) { + variables.add( new Variable(name, Double.NaN) ); + } + return this; + } + + + /** + * set the values for variables + * + * @param variableMap + * a map of variable names to variable values + * @return the {@link ExpressionBuilder} instance + */ + public ExpressionBuilder withVariables(VariableSet variables) { + this.variables = variables; + return this; + } +}