|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
学习JAVA的目的更多的是培养自身的工作能力,我觉得工作能力的一个核心就是:独立思考能力,因为只有独立思考后,才会有自己的见解
March2005
Discussion
Velocity:AtemplateengineORARuleengineORBoth?
MostofthedevelopersmustbefamiliarwithVelocityasagreatopensourcetemplateengineandIdon’tthinkIneedtosaymuchaboutitsusesandfeaturesasatemplateengine.Thispapercompilesitsfeaturesasaruleengine.
Ihavebeenworkingwithjavaforthepast6yearsandrecently,IgotanopportunitytodesignanddevelopanEntitlementApplication.
Anentitlementistheresultoftheexecutionofaformula,orrulethatspecifieswhatmustbeconsideredwhendecidingwhetheragivenuserhasrightstomanipulateoruseagivenresource(orobject).Thisrulemaybecomposedofoneormoreconditionsthatmightonlybeevaluatedwithapplicationcontextspecificdata.Inaddition,aruleevaluationmayresultinmorethansimpleyes/noanswersandcontainadditionalinformationthatwouldberequiredbyanapplicationtonowperformtherequestedaccesstotheresource.Thesearecalledobligations.ThereforeanEntitlementServicecanbeusedbothasaruleevaluatorandaprivilegedataservice.
InitssimplestformanEntitlementServiceperformsstandardauthorizationcalls.Forexample,canauserperformasimpleactionagainstanamedresource?Initsmorecomplicatedformanentitlementmaybearuleonhowanobjectsuchasafinancialtransactionmaybemanipulated.Inthisrulethespecificparametersofthetransactionmaybecomparedagainstsetlimitsorcurrentfinancialdata.Theruleinthiscasemaybearepresentationofbusinesslogic.
Therearefourtypesofentitlement:
Coarse-grainedentitlement-Thecontrolofaccesstobroadcategoriesofresources,forexample,anentireapplication,anentiresubsystem,oraccesstospecificwebpages.
Fine-grainedentitlement-Thegrantingorwithholdingofindividualresourceslikebuttons,links,menuchoicesonapageorscreen,orfunctionswithinaprogram.
Transactionalentitlement-Anentitlementthatchecksprivilegetomanipulatearesourcebyexaminingveryspecificparametersabouta‘transaction’uponthatresource.Thecharacteristicsoforrelationshipsbetweentheseparameterscouldbeexpressednumerically(<,>,=,…),usingdateandtimeinformation,orevenaspartofaformula(*,%,/,-,+).
Dynamicentitlement-Whereaparameterofa‘transaction’representsinformationthatmustbecalculatedorretrievedfromanexternalsource.Thisinformationmayberetrievedbyacalltoanapplicationspecificservice.
Soaccordingtotherequirements,thisapplicationhastohave:
Somelogictoreturnthestoreddata(Users,UserGroups,Resources,ResourceGroups,Permissionsetc)basedonsomefilters.Forexamplereturnmealltheuserswhohaveanaccessonthisresource.Logictocheckthepermission.PermissionsareBooleaninnatureanddon’trequireanycomplexlogictoprocess.Although,permissionareverysimpletheyarequietpowerfulforbuildinganentitlementapplicationandcatertomostofthecasesofCoarse-grainedandFine-grainedentitlements.ArulebasedenginetohandleTransactionalandDynamicentitlements.
Now,wewilldirectlyfocusontheusesofVelocityasaruleengineasthisarticleisnotaboutdevelopinganentitlementapplication.
So,insteadofdevelopingmyownruleengineIstartedlookingaroundtofindoutadecentruleenginethatcanfulfillmyrequirements.AndIbegantoexploreruleengineslike:
JEL(http://galaxy.fzu.cz/JEL),BeanShell(http://www.beanshell.org/home.html),EL(http://java.sun.com/j2ee/1.4/docs/tutorial/doc/JSPIntro7.html)
andmanymore,especiallytheoneswithopensourcesbecausemymanagementdidnotwanttospendtoomuchmoneyonthisapplication.
WhatIwaslookingforwasanenginewiththefollowingfeatures:
Easeofuseindevelopment.Shouldreducemydevelopmenttime.Easyandflexibleintermsofconfiguration.Itshouldhaveveryeasyandfamiliarlanguagetowriterulesespeciallyforanon-technicaladmintomaintain.Easilyextendable.Clearseparationbetweenadmin(Ruleauthor)anddeveloper.Testedandreliable.Greatcommunitysupport.NobodyisperfectandeverybodyneedsHelp:)
ButIcouldn’tfindanythinggoodenoughoutthere.Suddenly,Velocitygotmyattention.IhavealreadyusedVelocitytogeneratemyGUI.However,thistime,Iwaslookingatitwithadifferentpointofview.Iwascompilingitsfeaturesintermsofaruleengineanditseemedtomeaconsiderablefitforthisnewframework.ThenitbecameaperfectfitwhenIrealizeditsusesoftoolboxconceptaswell.ThetoolboxconceptprovidesthepowertoruleanauthortoaccessanyEISorapplication(almostanything)atruntimeandwithacompletetransparencytotheauthor.
NowletsgooverareallifeexampleanduseVelocityasruleengine.Beforewegoahead,letsconfigureVelocity.
Velocitycanbeusedasaservletinawebapplicationorasautilityinastandaloneapplication.Inourcase,wewilluseitasastandaloneapplication.Now,asastandaloneapplication,youcanuseitintwoways.Oneissingletonanotherisseparateruntimeinstance.Iuseditassingleton.Followingisthecodesample:
publicclassRuleEngineVelocityImplimplementsRuleEngine{publicRuleEngineVelocityImpl{try{//InitializeVelocity.Velocity.init();}catch(Exceptione){//Dosomething.}}publicStringexecute(StringruleId,Mapparams){//getthevelocitytemplatefromsomestorage.Stringtemplate=getFromSomewhere(ruleId);//CreateaContextobject.VelocityContextcontext=newVelocityContext(params);//Getatemplateasstream.StringWriterwriter=newStringWriter();StringReaderreader=newStringReader(template);//askVelocitytoevaluateit.booleanresult=Velocity.evaluate(context,writer,ruleId,reader);StringstrResult=null;if(result){strResult=writer.getBuffer().toString();}returnstrResult;}publicstaticvoidmain(String[]args){//addthevariableandtheirvalueswhichisbeingreferredin//template/rule.Mapparams=newHashMap();params.put("Anykey",AnyObject);//InitializeRuleEngineandexecutetherule.RuleEngineengine=newRuleEngineVelocityImpl();Stringresult=engine.execute("MyRule",params);System.out.println("Result:"+result);}}
Now,wewillwritearuletocheckacreditlimitforsomeuser.AVTLtemplate/ruleforthismaylooklikethis:
#if($creditLimit>1000)Overlimit.Youcantcompletethistransaction.##ORjustaBooleanvaluelikefalse###else#set($creditLimit=1000-$creditLimit)Now,yourbalanceis${creditLimit}.##ORjustaBooleanvalueliketrue###end
Youcanstoretherulesinafileorinadatabaseorinanyanotherdatastorage.Inmycase,Istoredtheserules/templatesinaRDBMSandIprovidedanAdminGUItomaintainthem.Letsassumedatabasetable,‘Rule’withtwocolumns,RuleIdandTemplate.IinsertarulewithRuleId“Chk_Credit_Limit”.
Now,letsmodifythemainmethodof“RuleEngineVelocityImpl“class.
publicstaticvoidmain(String[]args){Mapparams=newHashMap();params.put("creditLimit",newInteger(200));//InitializeRuleEngineandexecutetherule.RuleEngineengine=newRuleEngineVelocityImpl();Stringresult=engine.execute("Chk_Credit_Limit",params);System.out.println("Result:"+result);}
Theoutputwillbe:
Now,yourbalanceis800.
Doesn’titsoundsveryfamiliarandeasy?Ithastobe.Itisvelocity,dude!!!
Now,letsseethepoweroftoolboxconcept.
Naturally,VelocityonlysupportsintegerbutVelocitytoolsprojectaddsthepowertoVelocitytodoanykindofMath,Dateprocessingandformattingwhichyouwillneedtousefortheruleengine.
Sinceatoolboxisextendableandit’sveryeasytowriteatool(almostanyclasswithpublicmethodcanbeusedastool)youhaveunlimitedopportunitiestowriteNnumbersoftoolscorrespondingtoyourapplication/requirementscontextandallwillbeavailabletoruleauthorforwritingthesmartrules.Forexample,letssayanairlinecompanyhascomeupwithabusinessruleforyear2005thatstates:
Ifbookingdateisonaspecialdaylistthengetthediscountedrate,otherwiseusethenormalfare.
Letsassumethisdiscountedrateandspecialdaylistisstoredinsomedatabaseandbotharebeingmaintainedbysomeotherapplication.Thisspecialrateisvalidonlyforyear2005anditmaychangeorcanbecompletelyeliminatedinyear2006.Insuchcaseitwillnotbewisetobuildtheapplicationtocatertotheabovebusinessrequirementsandchangeitlater.
Soletsaddressthisproblemwiththerules.Beforewewritearuleweneedtwovaluesavailableataruntime.Oneisaspecialdaylistandtheotheristhediscountrate.LetswriteaToolclass(com.RateHelper)similartowhatwehavealreadyinVelocitytools:Math,Dateetc.Thesignatureofthisclasswouldbeasfollows:
publicDoublegetRate();publicbooleanisInSpecialDayList(Stringday);
AnyclasswithpublicmethodcanbehavelikeatoolinVelocity.That’sthemagicofintrospection:)
AfterwritingthisclassletsadditasatoolinVelocityengine.Wealreadyhaveabeautycalled“XMLToolboxManager”toaddNnumberoftoolsinVelocityautomatically.Wejustneedtospecifyourtoolsinanxmlfilecalledtoolbox.xml.
<toolbox><tool><key>rateHelper</key><scope>application</scope><class>com.RateHelper</class></tool></toolbox
Now,letsmodifyourRuleEngineVelocityImplclasstoloadthistoolboxbyaddingthebelowlineintheconstructorafterinitializingVelocity.
XMLToolboxManagertoolboxManager=newXMLToolboxManager();toolboxManager.load(this.getClass().getClassLoader().getResourceAsStream("toolbox.xml"));toolboxContext=toolboxManager.getToolboxContext(null);
Andnowreplacethebelowlineinexecutemethod:
VelocityContextcontext=newVelocityContext(params);
withthethisline:
VelocityContextcontext=newVelocityContext(toolboxContext,params);
Thisiscontextchaining.Pleaserefertheapachedocumentationformoreinformationonit.
Okay,weareallset.Letswritethebusinessrule(usingourcustomtool)andstoreitinourdatabasewithRuleId“get_price”
#if($rateHelper.isInSpecialDayList($day))$rateHelper.getRate()#else2500##Regularprice###end
Now,letsmodifythemainmethodagaintoexecuteournewrule.
publicstaticvoidmain(String[]args){Mapparams=newHashMap();params.put("day","02/28/05");//InitializeRuleEngineandexecutetherule.RuleEngineengine=newRuleEngineVelocityImpl();Stringresult=engine.execute("get_price",params);System.out.println("Result:"+result);}
Theoutputwillbe(if02/28/05isnotinspecialdaylist):2500
Isn’titeasyandpowerful?
Inadditiontotoolbox,Iassociatedproperties(key-valuepair)toobjectslikeUser,UserGroup,Resource,ResourceGroupwhichImadeavailabletoruleauthor.Thisgivestheauthormoreflexibilitytowritesmartsrules.Forexample,thereisausergroupinacompanywheresomeoftheuserscanonly“buy”theproductandsomeofthemcanonly“sell”theproductandtherestofthemcandoboth.Wecanassociateapropertycalled“ActionDirection”witheveryuserofthegroupandthepossiblevaluesforthepropertywillbelike“BUY”,“SELL”and“BOTH”.Aruleauthorcanuseitfreelyinhisrulestodistinguishamongtheuseractions.
Velocitywasintenselywrittenasatemplateengineandit’soneofpioneersinthisareabutyoucanseethatitisalsoagreatRuleengine.Combinationofproperties,toolboxandparametersmakesitmorepowerfulandperfectlysuitableforthistask.Andmostimportantly,somebodyhasuseditsuccessfullyasruleengine.
Reference:
1)http://jakarta.apache.org/velocity/index.html
Thanksto:
-MarcandNormwhobroughtmeintothisproject.
-Margaretforherediting.:)
origionallink:Velocity:AtemplateengineORARuleengineORBoth?
j2EE和asp比较,其实也没什么比的,原因和我上面说那些比较差不了多少,也是稳定性,安全性,J2EE比asp高,速度上比不过asp,asp也是延续着它的拖拽控件的方法,提高速度。 |
|