Java Formula Parsing (BeanShell + commons-digester)
Part of the Code is from the ibm bsh tutorial
2010.4.1. 10:42:58 @ hz
Formulas. xml
<? XML version = "1.0" encoding = "UTF-8"?> <Br/> <formulas> <br/> <formula id = "1001" name = "f_discount"> <br/> <resulttype> double </resulttype> <br/> <parameters> <br/> <parameter type = "double" name = "price"/> <br/> <parameter type = "double" name = "discount"/> <br/> </parameters> <br/> <MCE: script Type = "text/JavaScript"> <! -- <Br/> result = calculator. mutiply (price, discount) <br/> // --> </MCE: SCRIPT> <br/> </formula> <br/> <formula id = "1002" name = "f_bonus"> <br/> <resulttype> double </resulttype> <br/> <parameters> <br/> <parameter type = "double" name = "sale"/> <br/> <parameter type = "double" name = "score" /> <br/> </parameters> <br/> <MCE: script Type = "text/JavaScript"> <! -- <Br/> result = calculator. add (calculator. mutiply (sale, 0.1), calculator. mutiply (score, 10000) <br/> // --> </MCE: SCRIPT> <br/> </formula> <br/> </formulas> <br/>
Formulas-rules.xml
<? XML version = "1.0" encoding = "UTF-8"?> <Br/> <digester-rules> <br/> <pattern value = "formulas"> <br/> <object-create-Rule classname = "My. test. study. bsh. formulas "/> <br/> <pattern value =" formula "> <br/> <bean-property-setter-Rule pattern =" resulttype "/> <br/> <object-create-Rule classname = "My. test. study. bsh. formula "/> <br/> <set-properties-rule/> <br/> <pattern value =" parameters/parameter "> <br/> <object-create-rule <br/> classname = "My. test. study. bsh. parameter "/> <br/> <set-properties-rule/> <br/> <set-next-Rule methodname =" addparameter "/> <br/> </Pattern> <br/> <bean-property-setter-Rule pattern = "script"/> <br/> <set-next-Rule methodname = "addformula"/> <br/> </pattern> <br/> </digester-rules>
Paramter. java
Public class parameter {<br/> private string type; <br/> private string name; <br/> Public String tostring () <br/>{< br/> return this. type + "" + this. name; <br/>}< br/>
Formula. java
Import Java. util. vector; </P> <p> public class formula {<br/> private string ID; </P> <p> private string name; </P> <p> private string resulttype; <br/> private string script; </P> <p> private vector parameters; </P> <p> Public void addparameter (parameter) {<br/> parameters. add (parameter); <br/>}</P> <p> Public formula () {<br/> parameters = new vector (); <br/>}</P> <p> Public String parameterstostring () <br/ >{< Br/> stringbuffer _ result = new stringbuffer (""); <br/> object [] _ paramsarray = parameters. toarray (); <br/> for (INT _ I = 0; _ I <_ paramsarray. length; _ I ++) <br/>{< br/> If (_ I! = 0) <br/>{< br/> _ result. append (","); <br/>}< br/> _ result. append (parameter) _ paramsarray [_ I]). tostring (); <br/>}< br/> return _ result. tostring (); <br/>}</P> <p >}< br/>
Formulas. java
Package my. test. study. bsh; </P> <p> Import Java. io. ioexception; <br/> Import java.net. URL; <br/> Import Java. util. hashtable; </P> <p> Import Org. apache. commons. digester. digester; <br/> Import Org. apache. commons. digester. xmlrules. digesterloader; <br/> Import Org. XML. sax. saxexception; </P> <p> public class formulas {<br/> private final static URL formulasurl = new formulas (). getclass (). getclassloader (). getresource ("formulas. XML "); <br/> private final static URL ruleurl = new formulas (). getclass (). getclassloader (). getresource ("formulas-rules.xml"); <br/> Public hashtable formulas; <br/> Public formulas () <br/>{< br/> formulas = new hashtable (); <br/>}< br/> Public void addformula (formula F) <br/>{< br/> formulas. put (F. GETID (), f); <br/>}< br/> Public static formulas getformulasbybean () <br/>{< br/> formulas result = new formulas (); <br/> digester = new digester (); <br/> try {<br/> digester. push (result); <br/> digester. addobjectcreate ("formulas/formula", formula. class); <br/> digester. addsetproperties ("formulas/formula"); <br/> digester. addbeanpropertysetter ("formulas/formula/resulttype", "resulttype"); </P> <p> digester. addobjectcreate ("formulas/formula/parameters/parameter", parameter. class); <br/> digester. addsetproperties ("formulas/formula/parameters/parameter"); <br/> digester. addsetnext ("formulas/formula/parameters/parameter", "addparameter"); </P> <p> digester. addbeanpropertysetter ("formulas/formula/script", "script"); </P> <p> digester. addsetnext ("formulas/formula", "addformula"); <br/> result = (formulas) digester. parse (formulasurl); <br/>}< br/> catch (ioexception e) {<br/> E. printstacktrace (); <br/>}< br/> catch (saxexception e) {<br/> E. printstacktrace (); <br/>}< br/> return result; <br/>}< br/> Public formula loadformulabybean (string ID) {<br/> formulas result = new formulas (); <br/> return (formula) result. getformulasbybean (). formulas. get (ID); <br/>}< br/> Public formula loadformulabyrules (string ID) {<br/> formulas _ formulas = new formulas (); <br/> return (formula) _ formulas. getformulasbyrules (). formulas. get (ID); <br/>}< br/> Public formula loadformula (string ID) {<br/> formulas fa = new formulas (); <br/> // return fa. loadformulabybean (ID); <br/> return fa. loadformulabyrules (ID); <br/>}< br/> Public static formulas getformulasbyrules () <br/>{< br/> formulas _ formulas = new formulas (); <br/> digester; <br/> try {<br/> digester = digesterloader. createdigester (ruleurl); <br/> _ formulas = (formulas) digester. parse (formulasurl); <br/>}< br/> catch (ioexception e) {<br/> E. printstacktrace (); <br/>}< br/> catch (saxexception e) {<br/> E. printstacktrace (); <br/>}< br/> return _ formulas; <br/>}< br/>
FormulaParser. java
Import java. util. enumeration; <br/> import java. util. hashtable; <br/> import java. util. iterator; <br/> import java. util. vector; </p> <p> import bsh. interpreter; </p> <p> public class FormulaParser {<br/> public double caculateByFormula (Formula formula, Hashtable parameters) {<br/> double result = 0.0; <br/> try {<br/> Interpreter I = new Interpreter (); <br/> I. eval ("import my. test. study. bsh. parse. *; "); <br/> V Ector para = formula. getParameters (); <br/> Iterator it = para. iterator (); <br/> while (it. hasNext () {<br/> Parameter dec = (Parameter) it. next (); <br/> String declare = dec. getType () + "" + dec. getName (); <br/> I. eval (declare); <br/> String value = (Double) parameters. get (dec. getName ())). toString (); <br/> if (value! = Null) {<br/> String assign_value = dec. getName () + "=" + value; <br/> System. out. println (assign_value); <br/> I. eval (assign_value); <br/>}< br/> else {<br/> System. out. println ("caculateByFormula ():" + dec. getName () + "the parameter name does not match or the parameter does not exist"); <br/> System. exit (1); <br/>}< br/> System. out. println (formula. getScript (); <br/> I. eval (formula. getScript (); <br/> Double rst = (Double) I. get ("result"); <br/> result = rst. doubleValue (); <br/>}< br/> catch (Exception e) {<br/> System. out. println ("caculateByFormula ():" + e. getMessage (); <br/>}< br/> return result; <br/>}</p> <p> public Formula loadFormula (String id) {<br/> Formulas fa = new Formulas (); <br/> // return fa. loadFormulaByBean (id); <br/> return fa. loadFormulaByRules (id); <br/>}< br/> Formulas fa; <br/> public FormulaParser () <br/>{< br/> if (fa = null) fa = new Formulas (); <br/>}</p> <p> public static String mountAllFuction () <br/>{< br/> String clsHead = "public class Formula {/n/t"; <br/> String funcHead = "public static "; <br/> String funcBodyH = "/n/t {/n/t return"; <br/> String funcbodyE = ";}/ n/t "; <br/> StringBuffer result = new StringBuffer (clsHead); <br/> Enumeration _ e = Formulas. getFormulasByBean (). formulas. elements (); <br/> // Enumeration _ e = Formulas. getFormulasByRules (). formulas. elements (); </p> <p> while (_ e. hasMoreElements () <br/>{< br/> Formula _ f = (Formula) _ e. nextElement (); <br/> result. append (funcHead); <br/> result. append (_ f. getResulttype (); <br/> result. append ("" + _ f. getName (); <br/> result. append ("("); <br/> result. append (_ f. parametersToString (); <br/> result. append (")"); <br/> result. append (funcBodyH); <br/> result. append (_ f. getScript (); <br/> result. append (funcbodyE); <br/>}< br/> result. append ("}"); <br/> return result. toString (); <br/>}</p> <p >}< br/>
TestParser. java
Import Java. util. hashtable; </P> <p> Import bsh. evalerror; <br/> Import bsh. interpreter; </P> <p> public class testparser {<br/> Public static void main (string ARGs []) <br/>{< br/> formulaparser fp = new formulaparser (); <br/> hashtable paras = new hashtable (); <br/> paras. put ("price", new double (100.0); <br/> paras. put ("discount", new double (0.9); <br/> system. out. println ("Calculation Result:" + FP. caculatebyformula (FP. loadformula ("1001"), paras); <br/> formulaparser FP1 = new formulaparser (); <br/> hashtable paras1 = new hashtable (); <br/> paras1.put ("sale", new double (11000.0); <br/> paras1.put ("score", new double (0.8 )); <br/> formula fa = fp1.loadformula ("1002"); <br/> system. out. println ("Calculation Result:" + fp1.caculatebyformula (FA, paras1); <br/> interpreter I = new interpreter (); <br/> string STR = "Calculator. add (calculator. mutiply (11000.0, 0.1), calculator. mutiply (0.8, 10000) "; <br/> // instantiate a beanshell interpreter <br/> try {<br/> I. eval ("Import my. test. study. bsh. parse. *; "); <br/> string result = I. eval (STR ). tostring (); <br/> system. out. println (result); </P> <p> string functions = FP. mountallfuction (); <br/> I. eval (functions); <br/> STR = "formula. f_bonus (11000.0, 0.8) "; <br/> result = I. eval (STR ). tostring (); <br/> system. out. println (functions); <br/> system. out. println (result); <br/>}< br/> catch (evalerror e) {<br/> E. printstacktrace (); <br/>}</P> <p >}< br/>