分享
 
 
 

Velocity A template engine OR A Rule engine OR Both

王朝java/jsp·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

March 2005

Discussion

Velocity: A template engine OR A Rule engine OR Both?

Most of the developers must be familiar with Velocity as a great open source template engine and I don’t think I need to say much about its uses and features as a template engine. This paper compiles its features as a rule engine.

I have been working with java for the past 6 years and recently, I got an opportunity to design and develop an Entitlement Application.

An entitlement is the result of the execution of a formula, or rule that specifies what must be considered when deciding whether a given user has rights to manipulate or use a given resource (or object). This rule may be composed of one or more conditions that might only be evaluated with application context specific data. In addition, a rule evaluation may result in more than simple yes/no answers and contain additional information that would be required by an application to now perform the requested access to the resource. These are called obligations. Therefore an Entitlement Service can be used both as a rule evaluator and a privilege data service.

In its simplest form an Entitlement Service performs standard authorization calls. For example, can a user perform a simple action against a named resource? In its more complicated form an entitlement may be a rule on how an object such as a financial transaction may be manipulated. In this rule the specific parameters of the transaction may be compared against set limits or current financial data. The rule in this case may be a representation of business logic.

There are four types of entitlement:

Coarse-grained entitlement - The control of access to broad categories of resources, for example, an entire application, an entire subsystem, or access to specific web pages.

Fine-grained entitlement - The granting or withholding of individual resources like buttons, links, menu choices on a page or screen, or functions within a program.

Transactional entitlement - An entitlement that checks privilege to manipulate a resource by examining very specific parameters about a ‘transaction’ upon that resource. The characteristics of or relationships between these parameters could be expressed numerically (<, >, =, …), using date and time information, or even as part of a formula (*,%,/,-,+).

Dynamic entitlement - Where a parameter of a ‘transaction’ represents information that must be calculated or retrieved from an external source. This information may be retrieved by a call to an application specific service.

So according to the requirements, this application has to have:

Some logic to return the stored data (Users, User Groups, Resources, Resource Groups, Permissions etc) based on some filters. For example return me all the users who have an access on this resource. Logic to check the permission. Permissions are Boolean in nature and don’t require any complex logic to process. Although, permission are very simple they are quiet powerful for building an entitlement application and cater to most of the cases of Coarse-grained and Fine-grained entitlements. A rule based engine to handle Transactional and Dynamic entitlements. Now, we will directly focus on the uses of Velocity as a rule engine as this article is not about developing an entitlement application.

So, instead of developing my own rule engine I started looking around to find out a decent rule engine that can fulfill my requirements. And I began to explore rule engines like:

JEL ( http://galaxy.fzu.cz/JEL ), Bean Shell (http://www.beanshell.org/home.html), EL ( http://java.sun.com/j2ee/1.4/docs/tutorial/doc/JSPIntro7.html ) and many more, especially the ones with open sources because my management did not want to spend too much money on this application.

What I was looking for was an engine with the following features:

Ease of use in development. Should reduce my development time. Easy and flexible in terms of configuration. It should have very easy and familiar language to write rules especially for a non-technical admin to maintain. Easily extendable. Clear separation between admin (Rule author) and developer. Tested and reliable. Great community support. Nobody is perfect and everybody needs Help :) But I couldn’t find anything good enough out there. Suddenly, Velocity got my attention. I have already used Velocity to generate my GUI. However, this time, I was looking at it with a different point of view. I was compiling its features in terms of a rule engine and it seemed to me a considerable fit for this new framework. Then it became a perfect fit when I realized its uses of toolbox concept as well. The toolbox concept provides the power to rule an author to access any EIS or application (almost anything) at runtime and with a complete transparency to the author.

Now lets go over a real life example and use Velocity as rule engine. Before we go ahead, lets configure Velocity.

Velocity can be used as a servlet in a web application or as a utility in a standalone application. In our case, we will use it as a standalone application. Now, as a standalone application, you can use it in two ways. One is singleton another is separate runtime instance. I used it as singleton. Following is the code sample:

public class RuleEngineVelocityImpl implements RuleEngine

{

public RuleEngineVelocityImpl

{

try

{

// Initialize Velocity.

Velocity.init();

}catch(Exception e){

//Do something.

}

}

public String execute(String ruleId ,Map params)

{

// get the velocity template from some storage.

String template = getFromSomewhere(ruleId );

// Create a Context object.

VelocityContext context = new VelocityContext( params );

// Get a template as stream.

StringWriter writer = new StringWriter();

StringReader reader = new StringReader( template );

// ask Velocity to evaluate it.

boolean result = Velocity.evaluate( context, writer, ruleId, reader );

String strResult = null;

if( result ){

strResult = writer.getBuffer().toString();

}

return strResult;

}

public static void main( String[ ] args)

{

// add the variable and their values which is being referred in

// template/rule.

Map params = new HashMap();

params.put("Anykey", AnyObject );

// Initialize Rule Engine and execute the rule.

RuleEngine engine= new RuleEngineVelocityImpl ();

String result = engine.execute( "MyRule", params);

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

}

}

Now, we will write a rule to check a credit limit for some user. A VTL template/rule for this may look like this:

#if( $creditLimit > 1000 )

Over limit. You can't complete this transaction.

##OR just a Boolean value like false##

#else

#set ( $creditLimit = 1000 - $creditLimit )

Now, your balance is ${creditLimit }.

##OR just a Boolean value like true##

#end

You can store the rules in a file or in a database or in any another data storage. In my case, I stored these rules/templates in a RDBMS and I provided an Admin GUI to maintain them. Lets assume database table, ‘Rule’ with two columns, RuleId and Template. I insert a rule with RuleId “Chk_Credit_Limit”.

Now, lets modify the main method of “RuleEngineVelocityImpl “ class.

public static void main( String[ ] args)

{

Map params = new HashMap();

params.put("creditLimit", new Integer(200));

// Initialize Rule Engine and execute the rule.

RuleEngine engine= new RuleEngineVelocityImpl ();

String result = engine.execute( "Chk_Credit_Limit", params);

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

}

The output will be:

Now, your balance is 800.

Doesn’t it sounds very familiar and easy? It has to be. It is velocity, dude!!!

Now, lets see the power of toolbox concept.

Naturally, Velocity only supports integer but Velocity tools project adds the power to Velocity to do any kind of Math, Date processing and formatting which you will need to use for the rule engine.

Since a toolbox is extendable and it’s very easy to write a tool (almost any class with public method can be used as tool) you have unlimited opportunities to write N numbers of tools corresponding to your application/requirements context and all will be available to rule author for writing the smart rules. For example, lets say an airline company has come up with a business rule for year 2005 that states:

If booking date is on a special day list then get the discounted rate, otherwise use the normal fare.

Lets assume this discounted rate and special day list is stored in some database and both are being maintained by some other application. This special rate is valid only for year 2005 and it may change or can be completely eliminated in year 2006. In such case it will not be wise to build the application to cater to the above business requirements and change it later.

So lets address this problem with the rules. Before we write a rule we need two values available at a runtime. One is a special day list and the other is the discount rate. Lets write a Tool class (com.RateHelper) similar to what we have already in Velocity tools: Math, Date etc. The signature of this class would be as follows:

public Double getRate() ;

public boolean isInSpecialDayList( String day );

Any class with public method can behave like a tool in Velocity. That’s the magic of introspection :)

After writing this class lets add it as a tool in Velocity engine. We already have a beauty called “XMLToolboxManager” to add N number of tools in Velocity automatically. We just need to specify our tools in an xml file called toolbox.xml.

<toolbox>

<tool>

<key> rateHelper </key>

<scope>application</scope>

<class>com.RateHelper</class>

</tool>

</toolbox

Now, lets modify our RuleEngineVelocityImpl class to load this toolbox by adding the below line in the constructor after initializing Velocity.

XMLToolboxManager toolboxManager = new XMLToolboxManager();

toolboxManager.load(this.getClass().getClassLoader().getResourceAsStream("toolbox.xml") );

toolboxContext = toolboxManager.getToolboxContext(null);

And now replace the below line in execute method:

VelocityContext context = new VelocityContext( params );

with the this line:

VelocityContext context = new VelocityContext( toolboxContext, params );

This is context chaining. Please refer the apache documentation for more information on it.

Okay, we are all set. Lets write the business rule (using our custom tool) and store it in our database with RuleId “get_price”

#if( $rateHelper.isInSpecialDayList( $day ) )

$rateHelper.getRate()

#else

2500 ##Regular price##

#end

Now, lets modify the main method again to execute our new rule.

public static void main( String[ ] args)

{

Map params = new HashMap();

params.put("day","02/28/05");

// Initialize Rule Engine and execute the rule.

RuleEngine engine= new RuleEngineVelocityImpl ();

String result = engine.execute( "get_price", params);

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

}

The output will be (if 02/28/05 is not in special day list): 2500

Isn’t it easy and powerful?

In addition to toolbox, I associated properties (key-value pair) to objects like User, User Group, Resource, Resource Group which I made available to rule author. This gives the author more flexibility to write smarts rules. For example, there is a user group in a company where some of the users can only “buy” the product and some of them can only “sell” the product and the rest of them can do both. We can associate a property called “ActionDirection” with every user of the group and the possible values for the property will be like “BUY”, “SELL” and “BOTH”. A rule author can use it freely in his rules to distinguish among the user actions.

Velocity was intensely written as a template engine and it’s one of pioneers in this area but you can see that it is also a great Rule engine. Combination of properties, toolbox and parameters makes it more powerful and perfectly suitable for this task. And most importantly, somebody has used it successfully as rule engine.

Reference: 1)http://jakarta.apache.org/velocity/index.html

Thanks to: -Marc and Norm who brought me into this project.

-Margaret for her editing. :)

origional link: Velocity: A template engine OR A Rule engine OR Both?

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有