Developing Personalization using User Segments, Campaigns, Placeholders, and Content Selectors can be done with JSP tags with very little Java coding. There might be times, however, when you want more flexibility in your Personalization.You can achieve this by creating and deploying a rule set, which uses the Rules Controls and the RulesManager
EJB.
This chapter contains the following sections:
The Rules service can help you create advanced Personalization features, which can help control each user's path through a Page Flow or using runtime information as dynamic input to conditional logic in your code. You must possess a working knowledge of XML and schemas (an advanced version of DTDs), as well as an intermediate understanding of Java development.
WebLogic Portal provides a set of tools to personalize the user experience in your portal applications. You have control over the content each user sees, the automatic e-mail messages each receives, and, in a commerce application, the type of discounts each user gets.
WARNING: | Discount actions are part of the Commerce API, which is deprecated with WebLogic Portal 10.0. The API is replaced by AquaLogic Commerce Services, which is available as a product separate from WebLogic Portal. |
To achieve these Personalization results, you create User Segments, Content Selectors, and Campaigns in WorkSpace Studio. Developing Personalization with these tools involves very little Java coding because you can use JSP tags. After this type of Personalization is developed, portal administrators can use the WebLogic Portal Administration Console to modify the behavior of the Personalization with no coding at all.
There may be times, however, when you want even more power and flexibility in the Personalization you develop. For example, you may want to use Personalization to control each user's path through a Page Flow or use run-time information as dynamic input to conditional logic in your code.
You can access the Rules Service by using the following two types of components:
RulesManager
EJB, are the preferred way to interact with the Rules Service. However, if you want to use the Rules Service somewhere besides a Page Flow or Web service, you can use the RulesManager
EJB directly in your code to access the Rules Service.This overview section includes the following topics:
Table 10-4 describes the personalization tools provided by WebLogic Portal. User Segments, Campaigns, Content Selectors, and Personalization JSP tags are described only to highlight the increased programmatic power you have by directly accessing the Rules Service.
The Input Objects and Action columns in Table 10-4 show the flexibility and power you have with the rules controls and the RulesManager
EJB.
Campaign rules can be defined with User Segments, User Profile properties, HTTP session or request properties, event characteristics, date or time values and ranges, shopping cart or catalog conditions, and random sampling.
|
|||||
The Rules Executor control lets you evaluate any input objects (such as a user's profile properties) against a predefined set of rules (rule set). If the rules evaluate to "true" based on the input objects, any predefined action(s) can be triggered (such as assigning the user to a certain classification). The Rules Manager control lets you look up information about rule sets. The rules controls serve as an interface to the RulesManager EJB.
|
Unlimited types of input objects: You can use the rules you create in XML to evaluate any object put into working memory (See Invoking the Rules Service to Evaluate Objects).
|
Unlimited types of actions: Can filter objects in working memory (see Filtering the Results) and perform any action defined in the rule set XML.
|
|||
The Rules Service reads objects you have put into working memory and evaluating those objects against a set of rules you have predefined in an XML file. (Working memory is the place where objects are temporarily stored as the Rules Service is processing the rules.) If the objects in memory match the conditions defined in the rule set (which can be made up of multiple rules), the corresponding rule set actions are triggered. For example, if you put a user's credit score into working memory (from the User Profile, from the return of a Web service calculation, or any other way), a rule in the rule set can be defined in XML to perform the following action: If the user has a credit score equal to or greater than 10, classify that user as a `gold customer'.
You can use the results of this rule processing in your applications any way you choose. For example, if you are developing a Page Flow, you can send a "gold customer" to the gold.jsp
and send all other customers to another JSP.
true
. The Rules Manager control provides methods for getting rule set information.Note: | The Rules Manager control is most useful as a rules development debugging tool. |
RulesManager
EJB is the interface into the Rules Service. The rules controls delegate calls to the RulesManager EJB. Use the RulesManager
EJB if you want to use the Rules Service in code outside of a Page Flow or Web service.The Rules Service is based on the Rete algorithm, which is optimized for forward chaining reasoning. In the rule evaluation process outlined in the following steps, the Rules Executor control is used as an example:
all
), and optionally, whether to filter the results. These are all parameters that can be configured on the control.evaluate*()
method.com.bea.p13n.usermgmt.profile.ProfileWrapper
are returned.Figure 10-11 provides a basic illustration of the rule evaluation process with the Rules Executor control used in a Page Flow. The returned results from the Rules Service process are used to determine the user's path through the Page Flow. In the figure, natural language is used instead of code for illustration purposes. (To see the actual parameterization and invocation of the control in a Page Flow, see Using the Control to Determine the User's Path in the Page Flow.)
The Rules Service is more dynamic than a simple conditional in your code. After a Web application or some other application component has been hard-coded with condition statements (if/then), there is no way to change that without recompiling the code and re-deploying the application. In comparison, rules can be changed and loaded as the Portal server is running. This means the administrator may get the business logic from domain experts, formulate a rule to reflect that logic, and load the rule into the application without ever having to stop the server.
This section shows you how to develop personalization using the rules controls and RulesManager EJB. The following steps are involved and are described in this section:
Rule sets are sets of instructions written in XML that the Rules Service uses to evaluate objects in working memory. A rule set determines if something in working memory meets certain conditions and performs an action.
There are two methods you can use to create a rule set:
Creating a Rule Set in WorkSpace Studio
You can use WorkSpace Studio to create and manage a .rls
file that contains rules, conditions, and actions.
Perform the following steps to create a rule set in WorkSpace Studio:
.rls
file extension. A rule set can exist anywhere in your data directory.
You can create a rule set manually. Rule sets must conform to particular schema. (The rule set schemas are located in the p13n_app.jar
file in the <WEBLOGIC_HOME>\common\p13n\lib
directory.) The language of the rules is actually a usage of the WebLogic Portal expressions package, extended to meet additional requirements for the Rules Service. See the com.bea.p13n.expression.operator.*
packages in WebLogic Portal
Javadoc for descriptions of the expressions you can use.
Rule set XML files, which must end in .rls
, all contain the following required elements:
<rule>
.<rule>
contains its own if/then clauses that consist of at least one <condition>
(if) and one or more <action>
(then). The Rules Service evaluates the objects in working memory against the conditions. If an object meets a condition, the related actions are executed. Listing 10-2 contains a simple rule set example that says, If the string `Make an Integer 10' is in working memory, add an Integer object `10' to working memory.
<?xml version="1.0" encoding="UTF-8"?>
<!-- edited with XMLSPY v5 rel. 4 U (http://www.xmlspy.com) by Your Name (Your Company) -->
<rule-set xmlns="http://www.bea.com/servers/p13n/xsd/rules/core/2.1.1" xmlns:exp="http://www.bea.com/servers/p13n/xsd/expression/expressions/2.1.1" xmlns:literal="http://www.bea.com/servers/p13n/xsd/expression/literal/1.0.1" xmlns:string="http://www.bea.com/servers/p13n/xsd/expression/string/1.0.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.bea.com/servers/p13n/xsd/rules/core/2.1.1
rules-core-2_1_1.xsd" is-complete="true">
<rule is-complete="true">
<name>Add Integer</name>
<description>Test Rule</description>
<conditions>
<exp:equal-to>
<exp:variable>
<exp:type-alias>java.lang.String</exp:type-alias>
</exp:variable>
<literal:string>Make an Integer 10</literal:string>
</exp:equal-to>
</conditions>
<actions>
<add-object>
<exp:type-alias>java.lang.Integer</exp:type-alias>
<exp:arguments>
<literal:string>10</literal:string>
</exp:arguments>
</add-object>
</actions>
</rule>
</rule-set>
Unless you are adept at reading schemas and manually constructing valid XML according to the schema's rules, use an XML editor such as XMLSpy (which can be installed from the WebLogic Platform product CD). An XML editor reads a schema, as well as all the schemas the schema imports, and shows you elements and attributes that can be added to an XML document at any location, showing you available elements and attributes and helping you create a valid XML rule set.
Tip: | The easiest way to create a rule set is to start with an existing one and modify it. Several example rule sets exist on the dev2dev web site at
http://dev2dev.bea.com/products/wlportal81/articles/portalrulesservice.jsp. |
Before you begin to create the rule set in XML, write out the rule in natural language to understand all its pieces (conditions and actions) and types of data. What is being put into working memory? What conditions do you want the objects to meet, and what should happen (actions) when objects in working memory meet the conditions?
Use the following guidelines to create a rule set (or modify an existing rule set) with an XML editor:
p13n_app.jar
file in the <WEBLOGIC_HOME>\common\p13n\lib
directory into the same directory where you will create your rule set:
lib/schema/expression*.xsd
lib/schema/rules*.xsd
rules-core-2_1_1.xsd
schema. This schema also includes imports of other schemas, especially expression schemas, that are helpful in building rule sets.
In a new XML document, your XML editor should automatically insert the XML header, automatically import any schemas listed for import, and insert required base elements, such as <rule-set>
, <rule>
, <name>
, <conditions>
, and <actions>
.
<conditions>
and <rules>
elements and begin building (or modifying) the conditions and rules.
Figure 10-13 shows a rule set being built in XMLSpy. With the <exp:greater-than-or-equal-to>
element selected, the Elements section shows which elements can be added as children. The Attributes section shows the attributes that can be set on the element.
META-INF/data
directory, or to one of its subdirectories. For example, create a META-INF/data/rulesets
directory and save the rule set there.Table 10-5 shows how an XML rule set uses a method to retrieve a User Profile property value so it can be evaluated by the Rules Service.
Use the following information when working on the mapping between the XML and the method:
<exp:type-alias>
identifies the type of object the method will work on. For a list of object type mappings defined in the parser-mapping-type.properties
file in p13n_app.jar
, see Using Type Mappings.<exp:instance-method>
indicates a method, and the <exp:name>
provides the name of the method.Note: | To invoke methods from a rule, the appropriate classes must be imported in the calling code. |
<exp:argument>
includes two <literal:string>
elements that provide the String arguments to the method.<literal:integer>
identifies a value that the Rules Service uses. The evaluation of the object in working memory (in this case the User Profile CreditScore
value) determines if the rule's action is fired.CreditScore
. If the value is greater than or equal to 10, in this example, the associated actions are fired.If a rule set does not validate, you can see the invalid area. Perform the following steps to fix the invalid rule set:
.rls
file. Those schemas are listed at the top of the *.rls
file. The schemas must be in the same directory as the .rls
file..rls
file are valid according to the schema. You can open the schema in XMLSpy to check your .rls
against the schema definitions. In XMLSpy, you can view the schema in Design view for a graphical representation of the schema. You can view the .rls
in Text view and Enhanced Grid view.Note: | There is no guarantee that a rule set validated in an XML editor will be validated in the Rules Service. |
This section explains how to deploy a rule set in development (WorkSpace Studio) and in Staging or Production environments.
This section contains the following topics:
After you create a rule set and store it in your application's META-INF/data
directory (or in a subdirectory you create, such as the META-INF/data/rulesets
directory), the rule set is automatically deployed if the server is running. If the server is not running, the rule set is automatically deployed at server startup. (The META-INF/data
directory also contains the User Segments, Content Selectors, Campaigns, and other application metadata you have created.) Rule sets must be deployed to the data
directory, and rule set file names must have an .rls
extension to be used by the Rules Service.
When you modify a rule set in the data
directory, the rule set is automatically refreshed on the running server.
Perform the following steps to add, modify, or remove a rule set that exists in a deployed application:
Rule sets must have objects in working memory to evaluate. For example, a rule set might contain a rule that has the following condition: "If the user's credit score is greater than 10." This implies there is either the credit score input, or there is a way to get at the credit score. We could add a credit score to working memory in one of two ways:
You could provide a credit score value in your code in the following ways:
You could then create a rule condition that evaluates the value
Integer.
Retrieving a credit score from a User Profile is more flexible and dynamic. First, you would use code to retrieve the User Profile and put it into working memory:
ProfileWrapper pw = SessionHelper.getProfile(request);
Object [] inputObjects = { pw }; (This is a required argument to the evaluate*() methods.)
In your rule set, you would then create a condition that uses a method (getProperty)
that retrieves a specific property (CreditScore
) from a specific property set (CreditPropertySet
). See the code example in
Table 10-5. The condition in the code example checks to see if the retrieved CreditScore
is greater than or equal to the <literal:integer>
value of 10
.
Note: | The User type is actually an alias for an object of class ProfileWrapper . This mapping of User to ProfileWrapper , along with the mappings of other well-known types, are defined in the parser-mapping-type.properties file in the p13n_app.jar file, shown in Using Type Mappings. |
The following object type mappings are from the parser-mapping-type.properties
file in the p13n_app.jar
file:
Listing 10-3 shows mappings for <type-alias>
tags.
WARNING: | The Commerce API is deprecated with WebLogic Portal 10.0. The API is replaced by AquaLogic Commerce Services, which is available as a product separate from WebLogic Portal. |
User=com.bea.p13n.usermgmt.profile.ProfileWrapper
Classifier=com.bea.p13n.user.Classification
Capability=com.bea.p13n.entitlements.common.Capability
Role=com.bea.p13n.entitlements.common.Role
Context=com.bea.p13n.rules.internal.engine.Context
Email=com.bea.campaign.rules.MailActionDef
Placeholders=com.bea.campaign.rules.AddAdToPlaceholderActionDef
Discount=com.bea.commerce.ebusiness.campaign.AddUserDiscountActionDef
EndScenario=com.bea.campaign.rules.EndScenarioActionDef
CatalogQuery=com.beasys.commerce.ebusiness.catalog.rules.CatalogQueryWrapper
ContentQueryAdvice=com.bea.p13n.content.advislets.ContentQueryAdvice
ShoppingCartFacade=com.beasys.commerce.ebusiness.shoppingcart.ShoppingCartRulesFacade
The code examples in Listing 10-2 and
Table 10-4 show the <type-alias>
element with a User
type.
Listing 10-4 shows mappings for <variable>
tags.
user=com.bea.p13n.usermgmt.profile.ProfileWrapper
request=com.bea.p13n.http.Request
session=com.bea.p13n.http.Session
event=com.bea.p13n.events.Event
randomNumber=java.lang.Number
classification=com.bea.p13n.user.Classification
date=com.bea.p13n.xml.schema.Date
time=com.bea.p13n.xml.schema.Time
timeInstant=com.bea.p13n.xml.schema.TimeInstant
role=com.bea.p13n.entitlements.common.Role
resource=java.lang.String
shoppingCart=com.beasys.commerce.ebusiness.shoppingcart.ShoppingCart
After you have created a rule set and you have objects in working memory, you can invoke the Rules Service to evaluate the objects in working memory with the rules you created. This section provides an example to show you how to invoke the Rules Service with the Rules Executor control in a Page Flow.
The example used throughout the Invoking the Rules Service to Evaluate Objects section assumes that a rule set already exists in the /data/rulesets
directory that classifies users as "GoldCardMembers" or "SilverCardMembers" by reading a User's Profile (similar to the example used in Adding a Credit Score to Working Memory from a User Profile). The Page Flow example in this section shows the User Profile being added to working memory. Since the User's Profile is needed in this example, you should assume the Profile Control was added to an existing Page Flow to enable the getting and setting of User Profile properties.
This sample also uses the User Login Control for authentication so that the Page Flow knows which User Profile to retrieve.
For instructions on creating a Page Flow and adding a Portal Control to the Page Flow, see the Javadoc.
When you insert a control in a Page Flow (a .jpf
file in WorkSpace Studio), all the Actions that are part of that control are available to use.
The Rules Executor Control contains two actions:
When you are looking at a Page Flow in Action View, you can select a control you have inserted (by selecting the control's border) and set properties on that control. The Property Editor is a convenient way to send arguments to the RulesManager
EJB (which interfaces directly with the Rules Service) without writing Java code.
For example, Table 10-6 shows how the Rules Executor Control properties shown in Figure 10-11 map to method and constructor arguments in the RulesManager
EJB.
RulesManager EJB methods (see
com.bea.p13n.rules.manager)
|
|
---|---|
Filter constructors (see
com.bea.p13n.rules.manager.RuleResultClassFilter)
|
The RulesManager
EJB has the same Actions contained in the Rules Executor Control: evaluateRule()
and evaluateRuleSet()
. The difference is that the Rules Executor Control Actions take only one argument—for example, evaluateRuleSet(Object[] inputObjects)
—and provide the rule and filter arguments through the control properties.
If you set the filterResults
property to true
on the Rules Executor Control, the EJB method with the filter
argument is used and the filtering properties you enter are automatically sent to that argument.
The filterClassName
and filterClassNames
properties are different options for populating the filter
argument (with one or more types of filters). Set either filterClassName
or filterClassNames
on the control, but do not set both.
Use the filterRuleName property to filter on the results of a specific rule in a rule set that has fired. If you use this property, the RuleResultClassFilter
constructor is called. Notice that the constructor is overloaded to use either a single class filter (that you entered in the filterClassName
) property or multiple class filters (that you entered in the filterClassNames
) property. The result of using the filterRuleName
property is that you not only filter the results of a specific rule that has fired, you can also filter on specific data types.
Following are more detailed definitions of the control properties:
META-INF/data
directory. For example, if you created a rule set called myruleset.rls
and stored it in a data/rulesets
directory, the URI would be /rulesets/myruleset.rls
. Use the Rules Manger Control to list rule sets and rules.null
.false
, all objects remaining in working memory are returned. The default is false
. For information on filtering, see Filtering the Results.java.lang.String
) of the type of results to return. If this is left empty, results are not filtered. Specify this or the filterClassNames, but not both.java.lang.String,java.lang.Integer
). If this is left empty, results are not filtered. Specify this or the filterClassName, but not both.Understanding how properties map to methods and constructors can help you understand the benefits of using the Rules Executor control. Filling in property values provides the following benefits:
For more information on the Rules Executor Control, see the Javadoc.
After you add the Rules Executor Control to the Page Flow, set the properties on the control, and select one of the control's execute* actions to use, you should verify that all other prerequisite details are in place (see Using an Existing Rule Set). Then you can add code to the Page Flow that sends users to a different page depending on the classification they receive from the rule evaluation process.
The sample Page Flow code in Listing 10-5 shows how a user is directed to a particular page based on the results from the Rules Service. A similar sample is included in The Portal Rules Service on dev2dev at
http://dev2dev.bea.com/products/wlportal81/articles/portalrulesservice.jsp (in the examples/pageFlows/classifyAndFlow
subdirectory).
public class Controller extends PageFlowController
{
/**
* @common:control
*/
private com.bea.p13n.controls.login.UserLoginControl userLoginControl;
/**
* @common:control
*/
private com.bea.p13n.controls.profile.ProfileControl myProfileControl;// The Rules Executor control is added. Properties are configured
// in the Property Editor.
// This is all done in the Page Flow's Action View.
/**
* @common:control
* @jc:rules-executor filterClassName="com.bea.p13n.user.Classification"
filterResults="true" rulesetUri="/rulesets/myruleset.rls"
*/
private com.bea.p13n.controls.rules.RulesExecutorControl
myRulesExecutorControl;/**
// Start with an empty list into which we add objects to populate
* @jpf:action
* @jpf:forward name="default" path="default.jsp"
* @jpf:forward name="goldCard" path="goldCard.jsp"
* @jpf:forward name="silverCard" path="silverCard.jsp"
* @jpf:catch type="com.bea.p13n.controls.exceptions.P13nControlException" path="error.jsp"
* @jpf:forward name="error" path="error.jsp"
*/
protected Forward evaulateRuleSetAction(EvaluateRuleSetActionForm form)
throws P13nControlException
{
// the working memory of the Rules ServiceList wmObjects = new ArrayList();
// This one will be the condition that fires the rule
ProfileWrapper pw = myProfileControl.getProfileFromRequest(this.getRequest());
if ( pw == null)
{
throw new P13nControlException("Undable to retrieve profile from
request. " + "Make sure PortalServletFilter is configured
in web.xml for an anonymous user, " + "or that a user
has logged in.");
}Integer value = new Integer(6);
myProfileControl.setProperty(pw, "FooPropertySet", "CreditScore", value);
wmObjects.add(pw);
// Evaulate all rules in the rule set. Parameters have been declared on the
// control in the Page Flow Property Editor (in Action View).Iterator iter = myRulesExecutorControl.evaluateRuleSet(wmObjects.toArray());
// Let's say we're looking for GoldCardMembers
List results = new ArrayList();Classification goldCardMembers = new Classification("GoldCardMembers");
// And we'll direct them to a certain page depending
Classification silverCardMembers = new Classification("SilverCardMembers");
// on how the rule evaluatesClassification classification = (Classification)iter.next();
// Now you would do something with that,
// like show them a different pageif (classification.equals(goldCardMembers))
// Direct them to high-price stuff
{return new Forward("goldCard");
// Direct them to lower-price stuff
}
else if (classification.equals(silverCardMembers))
{return new Forward("silverCard");
// Otherwise, it defaults. Something went wrong.
}
// Check the rule conditions or turn off filtering on the control
// to see what's in working memory}
}
return new Forward("default");
}
If you want to use only a specific type of object in working memory after the Rules Service has stopped, you can filter the objects in working memory. Filtering is set using Java types. On the Rules Executor Control, you can set the filter type in the Property Editor.
Get more information on the following subjects:
When you execute the Rules Service to evaluate objects in working memory, as described in Invoking the Rules Service to Evaluate Objects, you can filter the objects in working memory when the Rules Service has stopped running to return only the objects of a specific type.
Objects exist in working memory as a result of one of the following actions:
When the Rules Service has stopped, several objects might remain in working memory, including those the user initially added. For example, your rule may instantiate a new Classification object into working memory if the rule evaluates to true
. Another example is that a rule action might have updated the User's Profile, so you need to retrieve the profile from working memory.
When the Rules Service's API executes a rule, it returns an Iterator over the entire contents of working memory unless you filter the results. If you are looking only for Classification objects, then you can specify a filter that returns only Classification objects. You can design this filter based on a single class name, multiple class names, or a given rule, as described in Inserting the Control in the Page Flow.
When you implement the Rules Executor Control, the control takes care of constructing the filter automatically. You need to specify whether to filter and the filter class names as control properties. The filter is applied for you automatically by the control, if you specify this.
Filtering with the RulesManager
EJB is a more cumbersome than filtering with the Rules Service, because you must design the filter yourself with the RulesManager
EJB. Listing 10-6 shows how to design a filter.
String filterRuleName = null;
Class filterClass = com.bea.p13n.user.Classification.class;
ObjectFilter filter = new RuleResultClassFilter(filterRuleName, filterClass);
Class [] filterClasses = { java.lang.String.class, com.bea.p13n.usermgmt.profile.ProfileWrapper.class};
ObjectFilter filter = new RuleResultClassFilter(filterRuleName, filterClasses);
The filter can then be used as part of the RulesManager
EJB, as shown in the following example:
public Iterator evaluateRule(String ruleSetUri, String ruleName, Object[] inputObjects, ObjectFilter filter)
If you filtered the results, the Iterator should only contain results of the class types you specified. The code sample in Listing 10-7 shows a Classification object of SilverCardMembers.
while (iter.hasNext())
{
Classification c = (Classification)iter.next();
if (c.equals(silverCardMembers))
{
// do something
}
}
The Rules Service makes decisions for you at run-time. The rules framework is more flexible than hard-coding logic (if/then) into your components, because you can modify rules without modifying your code.
Following are some examples of using rules and rule results:
For additional code examples of the Rules Controls and RulesManager
EJB, see The Portal Rules Service on dev2dev at
http://dev2dev.bea.com/products/wlportal81/articles/portalrulesservice.jsp.
You can use the Rules Control elements to provide Personalization in your portal application. Table 10-7 lists the control names and all possible values you can use to create rules.