Expression4j Expression4J

Sample > External configuration

About
Documentation
Sample
    Simple expression
    Agregated expression
    Predefined function
    User define function
    Custom element
    Custom operator
    External configuration
Download

External configuration is used to store and load expression in XML format.

So it is used to externalise the definition of operation outside the main program (like Inversion Of Control, Expression4j can be used to do an Inversion Of Traitement, so dont do it, I do it for you). It can be assimiled as a rule manager (in futur).

Instead of doing expression in you application like

        protected double computeValue(double srcValue, int year) {
double result = srcValue * 0.5;

if (year < 1950) {
result = srcValue * 0.23;
}
if (year >= 1950 && year <2000) {
result = srcValue * 0.36;
}

return result;
}

public double getManufacturingValue(Date date) {
final double constant = 23.4;

Calendar calendar = Calendar.getInstance();
calendar.setTime(date);

double consolidedManufacturingValue = computeValue(constant,
calendar.get(Calendar.YEAR));

...
}

you can delegate it to Expression4j like

        public double getManufacturingValue(Date date) {
//create parameter to give to the expression
Parameters parameters = ExpressionFactory.createParameters();
parameters.addParameter("x",
NumberFactory.createReal(consolidedManufacturingValue));

//get expression (can be stored on a static field)
Catalog defaultCatalog = ExpressionFactory.getCatalog();
Expression expression = defaultCatalog.getExpression("h");

//compute value
MathematicalElement result = expression.evaluate(parameters);

//do the next
...
}
and if in the futur the computeValue evolve the you have only to update the configuration file.


But to do that you must store the expression in a configuration referentiel (in file or other).

Avantages are that:
  •  you can update your expression without compiling programm just by updating the configuration.
  • you can update your expression without stoping your program.
  • you can easily test your computing expression outside your code.
  • you can distribute your computing on several server (in near futur :) )
  • you can use expression defined by other person
The only constraint is to define your expression, custom expression element and custom operator :). You can easily use Beans in expression if you have define custom expression element who manage it. you also can define "if" function if you want ...

Generate the XML content of the configuration

        public static void main(String[] args) {
try {
//create expressions and constant
ExpressionFactory.createExpression("f(a,b,x)=2*a*x+b");
ExpressionFactory.createExpression("g(r)=2*pi*r");
Catalog catalog = ExpressionFactory.getCatalog();
catalog.addConstant("maConstante",
NumberFactory.createReal((54)));
ExpressionFactory.createExpression("h(x)=x-maConstante");

//store configuration in file
OutputStream outStream =
new
FileOutputStream("c:/config.xml");
ConfigurationUtil.saveConfig(outStream);
outStream.close();

}
catch (Exception e) {
System.out.println("Error: " + e);
}

}

Load the XML content of the configuration

        public static void main(String[] args) {
try {
InputStream inputStream =
new
FileInputStream("c:/config.xml");
ConfigurationUtil.loadConfig(inputStream);

Parameters parameters =
ExpressionFactory.createParameters();
parameters.addParameter("x", NumberFactory.createReal(30));

Catalog defaultCatalog = ExpressionFactory.getCatalog();

Expression expression = defaultCatalog.getExpression("h");

MathematicalElement result = expression.evaluate(parameters);

System.out.println("Result: " + result);

} catch (Exception e) {
System.out.println("Error: " + e);
System.out.println("error: " + e.getCause());
}

}

Configuration XML associated to the previous sample

<?xml version="1.0" encoding="UTF-8"?>
<con:configuration xmlns:con="http://expression4j.fr/config">
<con:operators>
<con:operator name="Plus" symbol="+" unary="false"/>
<con:operator name="Multiply" symbol="*" unary="false"/>
<con:operator name="Pow" symbol="^" unary="false"/>
<con:operator name="Divide" symbol="/" unary="false"/>
<con:operator name="UnaryPlus" symbol="+" unary="true"/>
<con:operator name="UnaryMinus" symbol="-" unary="true"/>
<con:operator name="Minus" symbol="-" unary="false"/>
</con:operators>
<con:operator-managers>
<con:operator-manager name="default">
<con:operator-impl-class>fr.expression4j.basic.operatorimpl.complex.OperatorPlusComplexComplex</con:operator-impl-class>
<con:operator-impl-class>fr.expression4j.basic.operatorimpl.real.OperatorUnaryPlusReal</con:operator-impl-class>
<con:operator-impl-class>fr.expression4j.basic.operatorimpl.real.OperatorPowRealReal</con:operator-impl-class>
<con:operator-impl-class>fr.expression4j.basic.operatorimpl.complex.OperatorMultiplyComplexComplex</con:operator-impl-class>
<con:operator-impl-class>fr.expression4j.basic.operatorimpl.realcomplex.OperatorMinusRealComplex</con:operator-impl-class>
<con:operator-impl-class>fr.expression4j.basic.operatorimpl.real.OperatorMinusRealReal</con:operator-impl-class>
<con:operator-impl-class>fr.expression4j.basic.operatorimpl.complex.OperatorUnaryMinusComplex</con:operator-impl-class>
<con:operator-impl-class>fr.expression4j.basic.operatorimpl.real.OperatorPlusRealReal</con:operator-impl-class>
<con:operator-impl-class>fr.expression4j.basic.operatorimpl.real.OperatorMultiplyRealReal</con:operator-impl-class>
<con:operator-impl-class>fr.expression4j.basic.operatorimpl.realcomplex.OperatorMultiplyRealComplex</con:operator-impl-class>
<con:operator-impl-class>fr.expression4j.basic.operatorimpl.realcomplex.OperatorDivideRealComplex</con:operator-impl-class>
<con:operator-impl-class>fr.expression4j.basic.operatorimpl.complex.OperatorMinusComplexComplex</con:operator-impl-class>
<con:operator-impl-class>fr.expression4j.basic.operatorimpl.realcomplex.OperatorPlusRealComplex</con:operator-impl-class>
<con:operator-impl-class>fr.expression4j.basic.operatorimpl.real.OperatorDivideRealReal</con:operator-impl-class>
<con:operator-impl-class>fr.expression4j.basic.operatorimpl.complex.OperatorDivideComplexComplex</con:operator-impl-class>
<con:operator-impl-class>fr.expression4j.basic.operatorimpl.complex.OperatorUnaryPlusComplex</con:operator-impl-class>
<con:operator-impl-class>fr.expression4j.basic.operatorimpl.real.OperatorUnaryMinusReal</con:operator-impl-class>
</con:operator-manager>
</con:operator-managers>
<con:models>
<con:model name="default">
<con:unary-operator-class-name>UnaryPlus</con:unary-operator-class-name>
<con:unary-operator-class-name>UnaryMinus</con:unary-operator-class-name>
<con:binary-operator priority="1">
<con:operator-class-name>Plus</con:operator-class-name>
<con:operator-class-name>Minus</con:operator-class-name>
</con:binary-operator>
<con:binary-operator priority="2">
<con:operator-class-name>Multiply</con:operator-class-name>
<con:operator-class-name>Divide</con:operator-class-name>
</con:binary-operator>
<con:binary-operator priority="3">
<con:operator-class-name>Pow</con:operator-class-name>
</con:binary-operator>
<con:expression-element evaluation-order="1">
<con:expression-element-class-name>fr.expression4j.basic.impl.ComplexOrRealExpressionElement</con:expression-element-class-name>
</con:expression-element>
<con:expression-element evaluation-order="2">
<con:expression-element-class-name>fr.expression4j.basic.impl.FunctionExpressionElement</con:expression-element-class-name>
</con:expression-element>
<con:expression-element evaluation-order="3">
<con:expression-element-class-name>fr.expression4j.basic.impl.ConstantOrVariableExpressionElement</con:expression-element-class-name>
</con:expression-element>
<con:expression-element evaluation-order="4">
<con:expression-element-class-name>fr.expression4j.basic.impl.ParenthesisExpressionElement</con:expression-element-class-name>
</con:expression-element>
</con:model>
</con:models>
<con:catalogs>
<con:catalog name="general">
<con:expression>
<con:expression-name>abs</con:expression-name>
<con:expression-value>Predefine</con:expression-value>
<con:expression-model>Predefine</con:expression-model>
<con:expression-class>fr.expression4j.core.predefine.AbsFunction</con:expression-class>
</con:expression>
<con:expression>
<con:expression-name>acos</con:expression-name>
<con:expression-value>Predefine</con:expression-value>
<con:expression-model>Predefine</con:expression-model>
<con:expression-class>fr.expression4j.core.predefine.AcosFunction</con:expression-class>
</con:expression>
<con:expression>
<con:expression-name>asin</con:expression-name>
<con:expression-value>Predefine</con:expression-value>
<con:expression-model>Predefine</con:expression-model>
<con:expression-class>fr.expression4j.core.predefine.AsinFunction</con:expression-class>
</con:expression>
<con:expression>
<con:expression-name>atan</con:expression-name>
<con:expression-value>Predefine</con:expression-value>
<con:expression-model>Predefine</con:expression-model>
<con:expression-class>fr.expression4j.core.predefine.AtanFunction</con:expression-class>
</con:expression>
<con:expression>
<con:expression-name>ceil</con:expression-name>
<con:expression-value>Predefine</con:expression-value>
<con:expression-model>Predefine</con:expression-model>
<con:expression-class>fr.expression4j.core.predefine.CeilFunction</con:expression-class>
</con:expression>
<con:expression>
<con:expression-name>cos</con:expression-name>
<con:expression-value>Predefine</con:expression-value>
<con:expression-model>Predefine</con:expression-model>
<con:expression-class>fr.expression4j.core.predefine.CosFunction</con:expression-class>
</con:expression>
<con:expression>
<con:expression-name>cosh</con:expression-name>
<con:expression-value>Predefine</con:expression-value>
<con:expression-model>Predefine</con:expression-model>
<con:expression-class>fr.expression4j.core.predefine.CoshFunction</con:expression-class>
</con:expression>
<con:expression>
<con:expression-name>exp</con:expression-name>
<con:expression-value>Predefine</con:expression-value>
<con:expression-model>Predefine</con:expression-model>
<con:expression-class>fr.expression4j.core.predefine.ExpFunction</con:expression-class>
</con:expression>
<con:expression>
<con:expression-name>floor</con:expression-name>
<con:expression-value>Predefine</con:expression-value>
<con:expression-model>Predefine</con:expression-model>
<con:expression-class>fr.expression4j.core.predefine.FloorFunction</con:expression-class>
</con:expression>
<con:expression>
<con:expression-name>log</con:expression-name>
<con:expression-value>Predefine</con:expression-value>
<con:expression-model>Predefine</con:expression-model>
<con:expression-class>fr.expression4j.core.predefine.LogFunction</con:expression-class>
</con:expression>
<con:expression>
<con:expression-name>random</con:expression-name>
<con:expression-value>Predefine</con:expression-value>
<con:expression-model>Predefine</con:expression-model>
<con:expression-class>fr.expression4j.core.predefine.RandomFunction</con:expression-class>
</con:expression>
<con:expression>
<con:expression-name>sin</con:expression-name>
<con:expression-value>Predefine</con:expression-value>
<con:expression-model>Predefine</con:expression-model>
<con:expression-class>fr.expression4j.core.predefine.SinFunction</con:expression-class>
</con:expression>
<con:expression>
<con:expression-name>sinh</con:expression-name>
<con:expression-value>Predefine</con:expression-value>
<con:expression-model>Predefine</con:expression-model>
<con:expression-class>fr.expression4j.core.predefine.SinhFunction</con:expression-class>
</con:expression>
<con:expression>
<con:expression-name>sqrt</con:expression-name>
<con:expression-value>Predefine</con:expression-value>
<con:expression-model>Predefine</con:expression-model>
<con:expression-class>fr.expression4j.core.predefine.SqrtFunction</con:expression-class>
</con:expression>
<con:expression>
<con:expression-name>tan</con:expression-name>
<con:expression-value>Predefine</con:expression-value>
<con:expression-model>Predefine</con:expression-model>
<con:expression-class>fr.expression4j.core.predefine.TanFunction</con:expression-class>
</con:expression>
<con:expression>
<con:expression-name>f</con:expression-name>
<con:expression-value>f(a,b,x)=2*a*x+b</con:expression-value>
<con:expression-model>ExpressionModel</con:expression-model>
<con:expression-class>fr.expression4j.core.impl.ExpressionImpl</con:expression-class>
</con:expression>
<con:expression>
<con:expression-name>g</con:expression-name>
<con:expression-value>g(r)=2*pi*r</con:expression-value>
<con:expression-model>ExpressionModel</con:expression-model>
<con:expression-class>fr.expression4j.core.impl.ExpressionImpl</con:expression-class>
</con:expression>
<con:constant>
<con:constant-name>pi</con:constant-name>
<con:constant-property name="realValue" value="3.141592653589793"/>
</con:constant>
<con:constant>
<con:constant-name>e</con:constant-name>
<con:constant-property name="realValue" value="2.718281828459045"/>
</con:constant>
</con:catalog>
</con:catalogs>
</con:configuration>




SourceForge.net Logo Support This Project