<?xml version="1.0" encoding="UTF-8"?>
<org.eclipse.epf.uma:ContentDescription xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:org.eclipse.epf.uma="http://www.eclipse.org/epf/uma/1.0.6/uma.ecore" xmlns:epf="http://www.eclipse.org/epf" epf:version="1.5.1" xmlns:rmc="http://www.ibm.com/rmc" rmc:version="7.5.1" xmi:id="-H6wteXNcAgxFYU3xQqceZw" name="new_guideline,_IuFgEIm-Ed2dvb7--2nAHw" guid="-H6wteXNcAgxFYU3xQqceZw" authors="Jerome Boyer" changeDate="2011-09-28T12:00:06.662-0700" version="7.5.0">
  <mainDescription>&lt;p>&#xD;
    The goal of this &lt;a href=&quot;http://jcp.org/aboutJava/communityprocess/review/jsr094/index.html&quot;&#xD;
    target=&quot;_blank&quot;>specification&lt;/a> aims to make the client code for simple rule-based applications less dependent on&#xD;
    rule engine vendor-specific classes. The basic interactions with a rule engine are typically parsing the rules in scope&#xD;
    of a rule set, adding object references to one engine, firing the rules and getting results from the engine.&lt;br />&#xD;
    JSR94 defines a rule set as a &lt;em>rule execution set&lt;/em> which can be loaded from external resources like URIs, Input&#xD;
    streams, XML streams and readers. A rule execution set is a collection of rules. Another important JSR94 concept is the&#xD;
    &lt;em>rule session&lt;/em> which is a runtime connection between a client and a rule engine. A rule session is associated&#xD;
    with a single rule execution set, consumes rule engine resources and must be explicitly released when the client no&#xD;
    longer requires it. Session can be stateless or stateful. Stateless executes a rule execution set with a list of input&#xD;
    objects in one call. Stateful is designed to maintain a long time conversation between the client and the engine and&#xD;
    provides mechanism to assert / retract input object to the session.&lt;br />&#xD;
&lt;/p>&#xD;
&lt;p>&#xD;
    The client code may run on server layer like a servlet controller, in a service tier part of an EJB or POJO, or in a&#xD;
    standalone JSE JVM. The &lt;em>javax.rules&lt;/em> API divides interaction with rule engines into administrative and runtime&#xD;
    interactions. The basic operations supported by JSR-94 are:&lt;br />&#xD;
    • Acquiring a rule session for a registered rule execution set.&lt;br />&#xD;
    • Deploying and undeploying rulesets into a rule engine instance&lt;br />&#xD;
    • Querying simple metadata about a ruleset&lt;br />&#xD;
    • Executing a ruleset in either a stateful or stateless mode&lt;br />&#xD;
&lt;/p>&#xD;
&lt;h5>&#xD;
    The client code for run time execution&#xD;
&lt;/h5>&#xD;
&lt;p>&#xD;
    &lt;br />&#xD;
    From the client point of view the interaction with a rule engine is done using the rule session. But the first part is&#xD;
    to get an instance of the rule engine implementation. The service provider manager helps to get a rule service provider&#xD;
    which in turn helps to get rule run time and rule administration implementations. Every specific implementation exposes&#xD;
    an uniquely identifier for the service provider URL.&#xD;
&lt;/p>&#xD;
&lt;p class=&quot;codeSample&quot;>&#xD;
    &lt;br />&#xD;
    // Get the rule service provider from the provider manager&lt;br />&#xD;
    Class.forName(&quot;ilog.rules.bres.jsr94.IlrRuleServiceProvider&quot;);&#xD;
&lt;/p>&#xD;
&lt;p class=&quot;codeSample&quot;>&#xD;
    RuleServiceProvider serviceProvider = RuleServiceProviderManager.getRuleServiceProvider(“ilog.rules.bres.jsr94”);&#xD;
&lt;/p>&#xD;
&lt;p>&#xD;
    • For the reference implementation the URL is org.jsp.jsr94.ri.RuleServiceProvider&lt;br />&#xD;
    • For JRules the is ilog.rules.bres.jsr94.IlrRuleServiceProvider, and the service provider name is&#xD;
    ilog.rules.bres.jsr94&lt;br />&#xD;
    • For JBoss-drools the is org.drools.jsr94.rules.RuleServiceProviderImpl and the service provider name is&#xD;
    http://drools.org.&lt;br />&#xD;
    The code above is used for JSE deployment, as in JEE environment runtime clients should resolve the RuleRuntime and&#xD;
    RuleAdministrator services directly using JNDI lookup.&#xD;
&lt;/p>&#xD;
&lt;p class=&quot;codeSample&quot;>&#xD;
    Javax.naming.InitialContext initialContext = new InitialContext();&lt;br />&#xD;
    RuleRuntime ruleRuntime =&lt;br />&#xD;
    (RuleRuntime) PortableRemoveObject.narrow(&lt;br />&#xD;
    initialContext.lookup(&quot;org.jcp.jsr94.ri.RuleRuntime&quot;),RuleRuntime.class );&#xD;
&lt;/p>&#xD;
&lt;p>&#xD;
    In JSE we can use an inversion of control pattern and get those URL references from a properties file or a file&#xD;
    descriptor.&lt;br />&#xD;
    The next step is to get a rule engine run time.&#xD;
&lt;/p>&#xD;
&lt;p class=&quot;codeSample&quot;>&#xD;
    &lt;br />&#xD;
    // Get a RuleRuntime and invoke the rule execution.&lt;br />&#xD;
    RuleRuntime ruleRuntime = serviceProvider.getRuleRuntime();&#xD;
&lt;/p>&#xD;
&lt;p>&#xD;
    &lt;br />&#xD;
    The RuleRuntime interface exposes the method to create a rule session given a previously registered RuleExecutionSet&#xD;
    URI. It is possible to execute the rule engine in stateless or stateful mode using different type of rule session. We&#xD;
    need to specify the rule execution set URI and the session type.&#xD;
&lt;/p>&#xD;
&lt;p class=&quot;codeSample&quot;>&#xD;
    &lt;br />&#xD;
    StatelessRuleSession statelessRuleSession = (StatelessRuleSession) ruleRuntime.createRuleSession(ruleExecutionSetURI,&#xD;
    rulesessionProperties,RuleRuntime.STATELESS_SESSION_TYPE);&#xD;
&lt;/p>&#xD;
&lt;p>&#xD;
    The second parameter is optional and is used to add some additional properties to the session. In JRules it is used to&#xD;
    give the references to the rule set parameters and to specify if the RuleSession is a J2SE POJO rule session or a J2EE&#xD;
    POJO rule session:&#xD;
&lt;/p>&#xD;
&lt;p class=&quot;codeSample&quot;>&#xD;
    &lt;br />&#xD;
    Map rulesessionProperties = new HashMap(); rulesessionProperties.put(&quot;loan&quot;, loan);&lt;br />&#xD;
    rulesessionProperties.put(&quot;borrower&quot;, borrower);&lt;br />&#xD;
&lt;/p>&#xD;
&lt;p>&#xD;
    A stateless rules session exposes a stateless rule execution API to an underlying rules engine with two different&#xD;
    methods to call the execution of the rule:&#xD;
&lt;/p>&#xD;
&lt;p class=&quot;codeSample&quot;>&#xD;
    &lt;br />&#xD;
    public java.util.List executeRules(java.util.List objects)&lt;br />&#xD;
    throws InvalidRuleSessionException,java.rmi.RemoteException&#xD;
&lt;/p>&#xD;
&lt;p>&#xD;
    &lt;br />&#xD;
    The list of objects set as parameters will be inserted in the engine's working memory. The list returned includes all&#xD;
    the objects created by the executed rules. The only things we can retrieve with JSR94 from an execution are the objects&#xD;
    in the working memory. The second API uses a filter of objects the client code can supply to select those objects that&#xD;
    should be returned from the rule engine.&lt;br />&#xD;
&lt;/p>&#xD;
&lt;h4>&#xD;
    Filtering objects&#xD;
&lt;/h4>&#xD;
&lt;p>&#xD;
    To filter out objects from the list of returned objects from the rule execution call, the client code needs to provide&#xD;
    an implementation of the ObjectFilter interface. The implementing class receives callback methods that allow filtering&#xD;
    out objects as desired. Here is a simple filter class that removes any loan which does not have messages.&#xD;
&lt;/p>&#xD;
&lt;p class=&quot;codeSample&quot;>&#xD;
    &lt;br />&#xD;
    public class MyObjectFilter implements ObjectFilter {&lt;br />&#xD;
    &lt;br />&#xD;
    @Override&lt;br />&#xD;
    public Object filter(Object obj) {&lt;br />&#xD;
    if (obj instanceof Loan) {&lt;br />&#xD;
    Loan loan = (Loan)obj;&lt;br />&#xD;
    if (loan.getMessages().size() != 0)&lt;br />&#xD;
    return obj;&lt;br />&#xD;
    }&lt;br />&#xD;
    return null;&lt;br />&#xD;
    }&lt;br />&#xD;
&lt;/p>&#xD;
&lt;h4>&#xD;
    Get rule execution set meta data&#xD;
&lt;/h4>&#xD;
&lt;p>&#xD;
    &lt;br />&#xD;
    RuleRuntime can also being used to get the list of URIs that currently have rule execution set registered with them&#xD;
    using the API List listURIs=ruleRuntime.getRegistrations();&lt;br />&#xD;
    The other object involved is the RuleExecutionSetMetadata interface which exposes metadata about a Rule Execution Set&#xD;
    to runtime clients of a RuleSession like the name, URI and description of the rule execution set.&#xD;
&lt;/p>&#xD;
&lt;p class=&quot;codeSample&quot;>&#xD;
    &lt;br />&#xD;
    RuleExecutionSetMetadata metadata=statelessRuleSession&lt;br />&#xD;
    .getRuleExecutionSetMetadata();&lt;br />&#xD;
    metadata.getName();&lt;br />&#xD;
    metadata.getDescription();&lt;br />&#xD;
    metadata.getUri()&lt;br />&#xD;
&lt;/p>&#xD;
&lt;h4>&#xD;
    Stateful session&#xD;
&lt;/h4>&#xD;
&lt;p>&#xD;
    &lt;br />&#xD;
    Client code can use stateful session to conduct long running conversation with the engine, and control the working&#xD;
    memory with new facts. Input Objects can be progressively added to the StatefulRuleSession through the addObject&#xD;
    method. Output Objects can be progressively retrieved though the getObject method.&lt;br />&#xD;
&lt;/p>&#xD;
&lt;p class=&quot;codeSample&quot;>&#xD;
    StatefulRuleSession statefulRuleSession= (StatefulRuleSession) getRuleRuntime()&lt;br />&#xD;
    .createRuleSession(ruleExecutionSetURI, getProperties(loan, borrower),RuleRuntime.STATEFUL_SESSION_TYPE);&lt;br />&#xD;
    //first call the normal execution&lt;br />&#xD;
    statefulRuleSession.executeRules();&lt;br />&#xD;
    Loan l2 = new Loan(250000,240,7.25);&lt;br />&#xD;
    Handle hdl=statefulRuleSession.addObject(l2);&lt;br />&#xD;
    statefulRuleSession.executeRules();&#xD;
&lt;/p>&#xD;
&lt;p>&#xD;
    &lt;br />&#xD;
    Objects that have been added to the StatefulRuleSession must be removed and updated using the removeObject and&#xD;
    updateObject methods. A client must test for the existence of an added Object using the containsObject method. The&#xD;
    removeObject, updateObject, and containsObject methods must all use a javax.rules.Handle implementation&amp;nbsp;instances&#xD;
    to refer to and identify Object instances. Handle are used to ensure that Object instances can be unambiguously&#xD;
    identified in the event of multiple class loaders being used or the StatefulRuleSession being serialized. The addObject&#xD;
    methods returns a Handle instance for an Object added to a StatefulRuleSession, so that it can be used in the remove&#xD;
    API for example.&lt;br />&#xD;
    In JRules Ruleset parameters and objects added to the RuleSession when it is created are uniquely identified by an&#xD;
    instance of the IlrRuleSessionHandle class.&#xD;
&lt;/p>&#xD;
&lt;h4>&#xD;
    &lt;br />&#xD;
    Administrate rule execution set&#xD;
&lt;/h4>&#xD;
&lt;p>&#xD;
    &lt;br />&#xD;
    Administrative tasks supported by the API javax.rules.admin include instantiating the rule engine and loading rules. To&#xD;
    get the rule administrator we use the service provider such as: RuleAdministrator ruleAdministrator =&#xD;
    serviceProvider.getRuleAdministrator();&lt;br />&#xD;
    &lt;br />&#xD;
    The RuleAdministrator allows RuleExecutionSet instances to be registered against a URI for use from the runtime API, as&#xD;
    well as methods to retrieve a RuleExecutionSetProvider and a LocalRuleExecutionSetProvider implementation. The&#xD;
    RuleExecutionSetProvider interface defines methods to create a RuleExecutionSet from a number of Serializable sources&#xD;
&lt;/p>&#xD;
&lt;p class=&quot;codeSample&quot;>&#xD;
    LocalRuleExecutionSetProvider ruleExecutionSetProvider =&#xD;
    ruleAdministrator.getLocalRuleExecutionSetProvider(null);&lt;br />&#xD;
    RuleExecutionSet ruleSet = ruleExecutionSetProvider.createRuleExecutionSet( inputStream, null );&lt;br />&#xD;
    ruleAdministrator.registerRuleExecutionSet( ruleSet.getName(),ruleSet,null );&lt;br />&#xD;
&lt;/p>&#xD;
&lt;p>&#xD;
    The local rule execution set provider sends a local execution set to a remote engine using serialization and&#xD;
    marshaling. The API get(Local)RuleExecutionSetProvider takes an argument of type Map, which is documented as&#xD;
    &quot;additional properties&quot; and used for setting the JNDI properties. The source for the rule can come from&#xD;
    non-Serializable resources, such as binary InputStreams or character-based Readers. Registering the execution set to a&#xD;
    URI helps to create session to an execution set. The rules registered using the rules admin API are the only rules&#xD;
    accessible to the runtime clients.&lt;br />&#xD;
    The following code gets the name and description of the execution set deployed:&#xD;
&lt;/p>&#xD;
&lt;p class=&quot;codeSample&quot;>&#xD;
    &lt;br />&#xD;
    ruleSet.getDescription();&lt;br />&#xD;
    ruleSet.getName();&lt;br />&#xD;
&lt;/p>&#xD;
&lt;p>&#xD;
    getName() in the case of JRules Rule Execution server deployment returns the rule set path. From the rules set we can&#xD;
    get all the rules in a list and then for each rule its name and description.&lt;br />&#xD;
    Rule.getName()returns in the case of JRules a string which specify the language name and the name space for this rule,&#xD;
    like for example “IRL/validation/maximum_amount-brl.irl”. The rule.getDescription() returns the rule in the language of&#xD;
    the rule engine vendor. For JRules it is the Ilog rule language such as:&#xD;
&lt;/p>&#xD;
&lt;p class=&quot;codeSample&quot;>&#xD;
    &lt;br />&#xD;
    package validation {&lt;br />&#xD;
    &amp;nbsp;&amp;nbsp;&amp;nbsp; rule maximum_amount {&lt;br />&#xD;
    &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; property status = &quot;new&quot;;&lt;br />&#xD;
    &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; when {&lt;br />&#xD;
    &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;miniloan.Loan() from loan;&lt;br />&#xD;
    &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; evaluate (loan.amount &amp;gt; 1000000);&lt;br />&#xD;
    &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } then {&lt;br />&#xD;
    &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; loan.addToMessages(&quot;The loan cannot exceed&#xD;
    1,000,000&quot;);&lt;br />&#xD;
    &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; loan.reject();&lt;br />&#xD;
    &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br />&#xD;
    &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br />&#xD;
    }&lt;br />&#xD;
    &lt;br />&#xD;
    &lt;br />&#xD;
    &amp;nbsp;&#xD;
&lt;/p></mainDescription>
</org.eclipse.epf.uma:ContentDescription>
