Tag: Web Determination

OPA – Quiz Question #1 OR

[vc_row][vc_column][vc_column_text]

A Quiz Question for you

Stepping away from our series on Entities this week, I am sharing with you all a question I often ask during the Oracle Policy Automation training to my students. I ask it for three main reasons

  1. It helps to understand the Engine and the inferencing process
  2. It’s fun and a great way to challenge yourself
  3. It is good preparation for the sort of question that you might get in the Certification examination.

Of course this is an easy one – it is meant to be – but it certainly helps get students thinking about how to optimize the Web Determination experience and how to structure their work. I am also a great believer in the need to include this sort of thing in training sessions. Too often nowadays it has become a “knowledge transfer” with someone reading out loud a script and a bunch of slides. I find it hard to believe that the new “virtual learning” revolution has come down to that.

Anyway enjoy and we will be back in the Workshop for more Entities Adventures very soon.[/vc_column_text][/vc_column][/vc_row][vc_row][vc_column][vc_video link=”https://youtu.be/MNDEP_Mo1HU” title=”OPA Quiz Question 1 – Web Determinations”][/vc_column][/vc_row][vc_row][vc_column][vc_column_text]

Something to think about

The Oracle Policy Automation Certification, as it is sometimes called (incorrectly) is in fact actually called “Oracle Policy Automation 10 Rule Developer Essentials 1Z0-534” and as such is focuses for the major part on rule development. The exam study guide seems to have gone 404 on the Oracle University Website but the corresponding guide in the partner website is still useful.[/vc_column_text][/vc_column][/vc_row]

OPA – Web Determinations – Properties Files

OPA – Web Determinations – Properties Files

Open Oracle Policy Modelling, click File > New Project. Name the project, taking care to choose the English American language and a folder that is appropriate for your computer, and then right-click the Folder Structure and Add Existing File – add the Rulebase file “Rules.doc” from Microsoft Word and then add the Properties file “Properties.xsrc”.

You should also right-click and Add a New Screens File. Give it a good name for your Project. For the moment we will not use it, but it will be modified later in this series..

Oracle Policy Modelling Starting Point
Oracle Policy Modelling

Before we start to investigate the advanced possibilities, let us take a moment to review the out of the box features that will help us improve the look and feel of our Web Determiination. It is excellent practice to take advantage of these before doing anything else!

First of all, launch your Web Determination Session. Ctrl+F5, and make sure Web Determination is selected. Observe the default, automatically created pages and their User Interface style.

Automatic Screen
Automatic Screen

The first place to consider making changes is the “appearances.properties” file. This file will be in the folder of your Project,

\Release\web-determinations\WEB-INF\configuration\

In this file, a line preceded by a # is a comment, anything else will affect your Web Determination look and feel. To begin, let us change the following items.

show-rulebase-build-time =false
show-policy-modeling-version =false
# progress options
show-progress-bar =true
show-progress-stages =true

These are just examples to illustrate the features of the file. We switch on the progress bar, a small visual indicator of progress, and we remove a couple of text items from the status bar. Further down the file we can change the title logo, the text used in screen readers and the alternative text used if the image does not display, and some color choices :-

header-image=copy-Logo2.png
header-alt=ODE Motor Race Management
header-title=ODE Motor Race
header-text-color=#205eb6
headers-font-weight=bold
header1-font-size=x-large
header2-font-size=large

The image can be one of your choosing, or the one provided in the materials. Place this image in the folder :

\Release\web-determinations\WEB-INF\classes\images

Now let us see the results of our work. Ctrl-F5 again to review the changes. Already we have made significant progress. Not all our changes are visible on this first page. Click one of the goals to see a more representative page. Notice the color changes, the new logo and the progress bar in the top right section of the menu bar.

First Enhancements
First Enhancements

Clearly there is more work to do, however the file we have been modifying offers a large number of easy to follow changes. Of course, you should keep a record of the changes by adding # comments to the file, and keeping backups. But these changes cost little and provide benefit. Working to change a variety of options in this file can avoid costly development.

Policy Automation – Live Substitution in Question Screens

In the Policy Automation training, we discuss (and we have discussed on this Blog) the subject of Substitution. Put simply, if you have created a Customer called “Bob”, you want to see “Bob’s invoice” not “the customer’s invoice” in your Web Determination.

Fresh with this knowledge, students go and create a new
Rulebase and they put 4 attributes on one Screen in their
Screens File, like this:

OPA - Bob in the Screen Editor

They Build and Debug their rulebase and they get terribly
excited because it works, the name is substituted
automatically and Bob is displayed instead of the mournful
“the customer #1”.

OPA - Bob in the Debug Window

So the students then proceed to Build and Run their Web
Determination. Up pops the Web interface and their faces
drop. The substitution doesn’t work. You just get this:

OPA - Brenda with no Substitution

They ask you what is wrong, why does it not work. Why does it not say Brenda’s order number? And you say, “Well of course it doesn’t! The Web Determination user interface is plain old HTML, without anything fancy, so you can only get a substitution to work if you put the questions on different pages” (Thereby allowing a refresh between pages).

And people are quite unhappy. Well of course they are! If you
have Web, and as we have seen in the previous post you can
use jQuery UI to enhance the Web Determination, why can’t you
have a live substitution when the user enters a key piece
of information?

And so it begins. Let’s think about the challenge. Before we
dive into details, I am not a programmer, so the code I am
about to work through is probably inefficient and clunky. And
I know myself that mixing Apache Velocity and jQuery is messy
and confusing, and I should have make use of Velocity’s
ability to include files in other files using the #parse
directive.

Anyway let us think about the problem. In the screenshot
above, the first question is the important one – what is the
customer’s name. All the other questions should update when
the name is entered. If no name is entered, then the labels
should not be updated. And finally, if you update the Name
but change your mind and enter another Name, then of course
the labels should change again.

And finally, this should be robust enough that it can cope
with the second or the third question, not the first, being
the important one. And it must cope with different questions
and different entities.

At first glance the idea is apparently simple. For example,
use a Regular Expression to replace the baseline text “the
customer” with the Name entered by the user. For example
something like:

var exp = /( + "the customer" + )+/g;

Or you could even just use a simple text search and replace, assuming you have the current label stored in a variable :

var mysubstitute = "the customer";
var fieldvalue = //whatever the user has entered
var newlabel = currentlabel.replace(mysubstitute, 
fieldvalue);

And that would work fine. But it will only work once. For
example, the user changes the Name to Bob. The text gets
updated to “Bob’s Order Number” and so on. Then the user goes
back and changes it to “Steve”. Our replace is still looking
for “the customer” so the replace will not replace anything
as “the customer” does not exist as a substring of the label
any more.

So we have identified two issues. One, when the interview
starts, we need to know what the “baseline” text is – “the
customer” in this case. We can safely use that for the first
Name update. Then, we need to save the new Name “Bob”
somewhere and if the user changes the name again, “Bob” needs
to be our substring to substitute. And we need to save the
new Name “Steve”. And so on.

If the user does not enter any Name (so the text box remains
empty) then it should not result in “the customer’s Order
Number” becoming “‘s Order Number” – their should only be a
substitution when there is something in the text box. And if they have entered a Name but have now deleted it, it should revert to the baseline text.

To achieve something like this we need several steps. We must
identify

  • The Attribute that is the Master Key for our magic.
    In our case it would be the Name Attribute. When the Name
    changes, so should our labels.
  • The Substitution Baseline. When the user enters a Name for
    the first time, what text should be replaced? In our case
    “the customer” should be replaced. So the customer’s Order
    Number should become Bob’s Order Number.

We could expose these pieces of informtion from Policy Modelling to the Browser through Custom Properties. One for
the Screen to identify the Substitution Baseline, and another
on the Control to identify the Substitution Key.

OPA - Custom Screen Property for Substitution Baseline

OPA - Custom Control Property to Indentify Substitution Key

Then we need to consider how to store the new Name (“Bob”) as
the Substitution Baseline. So that if the Name is changed to
“Steve”, we replace “Bob” our new Baseline with “Steve”, and so
on. Custom Properties are static and can be read but we
cannot use them in a dynamic fashion to hold changes in value. So we need another solution.

  • Store the current Substitution Baseline somewhere on the
    page in a hidden attribute. For example, store it using the
    “tag” attribute of Label or the Input Box. We can update it
    and access it but it is not visible. There are other ways to
    achieve the same effect in code. jQuery offers data() which would be a good fit as well.
  • The code should operate on any text question (TextInput).
    In fact the same concept could be extended to any Input Type
    with a little more work, remembering that each InputType is a separate VM file.

So how might we implement it as a sand-box learning example?

Firstly, identify the TextInputControl.vm file for your
Rulebase in the templates folder of your Release.

At the top of the file, we might enter

// Get the Baseline Substitution Text
#set($jqSubstBase = $screen.getProperty("JQSubstitute", 
"nobaseline"))
// Get the Key Question Control
#set($jKey = $control.getProperties().get("jQMaster"))

With these two pieces from Apache Velocity, we can recover
the values of the Custom Properties set in the Policy
Modeller.

Now we seek out the HTML that actually creates the Text Input
boxes:

<input type="text" id="${control.getEncodedID()}" 
tag="${jqSubstBase}" name="${control.getId()}" 
${readOnlyString} value="${control.getDisplayValue()}" 
alt="${control.getText()}" tabindex="#tabIndex()" 
size="${text-control-width}" ${styleAttribute} 
${classAttribute}>

And as shown above, we add a tag to hold the Baseline
Substitution. Note that this method will result in every Text
Input storing the current Baseline as Tag value.

Next we would write some code, in the jQuery(document).ready event of the browser to ensure that we don’t start doing anything before the page is loaded.

In pseudocode, we might

  • Check the control currently being processed to see if it
    is the Key Control
  • if the keycode = 1, then Create an event handler on this textbox for the “blur” event. When the user mouse or keyboard leave the Key Control, run this code:
    • If the Input Box is empty, do nothing
      If the Input Box is not empty, load all the question labels into an array to prepare for substituton

So far so good. The “tag” attribute or the jQuery data() sounds like a reasonable way to store the Baseline Substitution. We could also update
the “tag” with the new Name. But what happens if there has
been a name, say “Steve”, and then the user deletes the Name
from the Text Input. We would want to revert to the baseline,
and again not find ourselves with “‘s Order Number”. If we
have already overwritten the “tag” then we would no longer
have the original Baseline Substitution.

So perhaps we will do it in two parts – when we load the
page, the Input Box will receive the “tag” of the original
Custom Property. If we have updated the Name, we will keep
this “tag” and use the Label instead. Or we will use data() to store old values and work with the new ones.

  • If the Input Box has a tag but the Label does not, then it is
    the first edit of the Name.
  • If the Input Box has a tag and we have a record of the previous data entry it is not the first edit.
  • If the Input Box is emptied by the user, switch to the Baseline text to restore the text to it’s original wording.

Phew – what else?

Aside from the above, we will use jQuery to do the legwork of
actually getting the text strings and updating the Labels and
tags, with code like:

jQuery(this).text(newlabel); //update the Label
jQuery($this).attr('tag', fieldvalue); // update a Tag

We can also use Velocity to help us. Given that this code
will run in the Velocity template called TextInputControl, we
will need to identify which control we are dealing with (if
we have 5 controls for example).

var fv = jQuery("#${control.getEncodedID()}").val();

For clarity in the above example and to avoid conflict you
will notice jQuery (not $) as Velocity uses $ as you can see
in the control.getEncodedID() statement.

Thanks to the the Custom Property we created earlier to
identify the Key Field, it will be easier to create an event
handler on the important Input Box (in our case, the Name)
and not on the other Input Boxes.

// Control Custom Property to identify the Key  Field
 #set($jqkey= $control.getProperties().get("jQMaster"))
 var myjqflag = "${jqkey}";

// The Custom Property example uses 2 values "1" for the Key Field and "0" for the others

 if (myjqflag == "1") 
{ jQuery("#${control.getEncodedID()}").blur(function (e) {...} 
}

So now we are able to detect the change to the Key Field, and
to manage the different cases (first change, further change,
empty Input Box). Different tools will help us in managing
the different scenarios.

jQuery(".question > label").each(function () {}

In a lot of cases we will need to iterate explicitly through
multiple labels, so we might use the different class names of Policy Automation HTML Pages and perform a nested selection like the one above, to go through each Label

Like I said I definitely am little more than an interested
amateur when it comes to programming, but the examples above
will hopefully give you the right impression – it is easy to
build for one rulebase (since much of your logic can be hard
coded) but it is much harder if you are trying to design a
bullet-proof version that will work in any Screen with any Entity.

If you are interested in the code (at your own risk) you will
find it in the OPA Extras section of your Profile Page.

In the meantime, have a look at the end result in all it’s
glory. [Edit – the video now has audio]

Policy Automation – Value Selections and jQuery

Value Selections and jQuery

A question that often comes up during the Oracle Policy Automation Essentials I and II   training perhaps en route to certification,  concerns the limitations of the Web Determination user interface. In fact many questions come up. The entire standard Web Determination user interface is driven by Apache Velocity. The front page of the Apache Velocity project describes it thus

“Velocity is a Java-based template engine. It permits anyone to use a simple yet powerful template language to reference objects defined in Java code.

When Velocity is used for web development, Web designers can work in parallel with Java programmers to develop web sites …

Well, to put it simply, the pages you see in the Web Determinations are generated from templates (with the file extension VM) that you can find in a standard deployment of a rulebase in the templates folder, unsurprisingly. Here is an extract from one of the standard Templates.

 #if( $control.isReadOnly() )
 #set( $readOnlyString = "readonly" )
 #else
 #set( $readOnlyString = "" )
 #end
 #parse( "investigation/input-style-overrides.vm" )
<div class="question">#parse("investigation/identifier-text.vm")<label for="${control.getEncodedID()}">#parse("investigation/control-text.vm")</label></div>
 <div class="info">
 #if($control.isMandatory() == "true" || $control.isMandatory() == "True")
<span class="mandatory">${mandatory-text}</span> 
#end
&nbsp;

Siebelites and other coders  will see the familiar pattern of HTML “<div>” and application “#parse” and “#if” that is reminiscent of the Web Templates we are used to handling for example in a Siebel project, but other Enterprise Applications use similar patterns to generate standard pages of output via templating.

The basic UI of Web Determinations is pretty, well, basic. The interface is static and rather plain, and almost all data controls are presented as text controls, even dates and numbers.

OPA - Boring Web Interface

 

Of course you can configure high-level visual elements to some degree using the different application properties files which we have covered in our popular blog, and these should be our first port of call, since they permit improvement without any coding or customization.

OPA - Less Boring Web Interface

Even with these changes however, the Web Determinations UI remains a rather plain Web 1.0 world. If you look at the example screenshot above, most of the changes (colors, images, logo text, links) have been achieved without any coding – for example using the appearances.properties file or the messages.properties files for your chosen locale.

OPA - Appearance Properties

OPA - Messages Properties

But looking more closely in the myriad template files we come across a very happy line :-

OPA - jQueryThe sign that jQuery is hanging out in the template files provides us with a new and effective way to improve them. For example, the standard date displays in the Web Determination do not offer the possibility to “choose” a date. The standard and familiar jQuery UI date picker makes things easier for the user even if this requires careful handling if your Web Determination is used in multiple locales. Three lines of <script> and <link> to link to the files and stylesheet, one line to instance the .datepicker and we are done.

 $(function() {
 $( "#date-${control.getEncodedID()}" ).datepicker({
 showOn: "both",
 buttonImage: "http://yourserver.com/calendar.gif",
 buttonImageOnly: true, dateFormat:"dd/mm/yy"
 });

OPA - jQuery Date Picker

We can even go so far as to implement some of the useful features found for example in the Siebel Open UI framework (which itself massively leverages jQuery). This will prove beneficial in the case of an integration between Siebel Open UI and OPA, as the two interfaces may appear together in the same CRM application and the OPA Web Determination will frankly look very ugly in comparison. Another example concerns the dropdown list of options used in the second image above.

Again, leveraging the autocomplete functionality in a combobox is achieved in just a few lines of code. For the sake of maintenance, these lines of code can be placed in files independent of the main templates. Aside from the habitual <script> and <link> tags to reference the necessary javascript files and stylesheet, the effect shown in the image below can be achieved in the following lines.

<script>
jQuery("#${control.getEncodedID()}").combobox(); // Velocity call
//for the correct ID wrapped by jQuery UI combobox call
</script>

The result is much nicer for the end users.

OPA - Combobox Typeahead3

 

 

 

Until next time, have fun!

 

 

Policy Automation – Gender in Policy Modelling

In previous posts we looked at a variety of different traps and challenges that Policy Modelling rule writers face as they work through the exercises of their Oracle Policy Modelling training. This post aims to clarify a concept which is not mentioned in the training, but which extends the ideas discussed last time – designing for the context of the rulebase.

Perhaps the simplest form of context is one that we all learn quite early  – the notion of gender. Consider possessive pronouns (in English, his or her or its, for example) – their use can considerably enhance the delivery of a Policy Modelling web determination:

Claimant : Janet Smith

Has Janet completed her complaints form?

Claimant : Bob Jones

Has Bob completed his complaints form?

Setting up the functionality comes in four parts which we will look at in this post. It does not require us to rewrite our rules or think up some convoluted way of getting round the problem.

Part One – Create the Attribute

Creating the “gender” Attribute is quite straightforward. In the example below you will see a standard Entity called “the customer”, with the default identifying Attribute displayed as well as a manually created text Attribute called “the customer’s gender”. For the sake of good practice we have given Public Names to the Entity and the Attributes.

OPA - Customer Gender Setup

Part Two – Assigning the Gender Attribute

In the next screenshot, we have selected the identifying Attribute for our customer Entity and we have selected the “gender” Attribute in the relevant Property. So the customer has now an assigned Gender Attribute.

OPA - Identifying Attribute with Gender

Part Three – Displaying the Gender Attribute

Of course in order to make this worthwhile we need to let Web Determination users select a value for the Customer gender. When you add the gender Attribute to a Question Screen you will notice a telltale icon to reveal that Policy Modelling has understood that this is gender Attribute. In addition you will see that List of Values has automatically been added to your Question Screen for the collection of the Attribute value.

OPA - Question Screen with Gender Attribute Collected

Part Four – Collecting the Gender

Now that our gender Attribute is in place, we can see the result when we implement a rulebase. The rule below will serve as a simple demonstration.

OPA - Example Rule for Gender Post

The key statement is “the customer has completed the customer’s complaints form if”. The second “the customer” will be affected by our new functionality.

Remember that to ensure you are able to enter your Customer instances and supply their gender, you will have to create an Entity Instance Collection Screen.

OPA - Entity Instance Collection Question Screen

OPA - Customer Collection Screen

Finally make sure you add the global goal (“the interview is complete”) to your Assessment Summary Screen before you Build and Run a Web Determination.

OPA - Assessment Summary Screen

Alternatively you can run a Build and Debug session instead. In both cases you should see a result similar to that shown below.

OPA - Debug Gender

 

OPA - Bob and His Complaints Form

Oops!

If you do not provide a mechanism whereby the gender can systematically be collected, what will happen? The side-effect of forgetting to add your gender Attribute to the relevant Question Screen will be something like the text shown below. Of course you would prefer it to look something like this, so make sure you collect the gender!

OPA - His Her Its

Substitution

Finally, now that you have set up this feature in your rulebase, you can use substitution to display the correct gender pronoun using the following documented syntax.

%custid% and %custid:his/her/its% complaints form 

Until next time, have fun!

Policy Automation and CRM On Demand #2

We return to the subject of Policy Automation with Siebel “in the cloud” (the original) CRM On Demand. In the previous post in this series we looked at how you can use a CRM On Demand WSDL generated from the Administration Screen to build a Data Model for your Policy Automation Project.

In this second post we will look at a practical example, taking a Project created in this way to the execution of an interview in CRM On Demand to create data. The Policy Automation Web Determination user interface provides a simple and streamlined way to enter data in a style that is somewhat reminiscent of Siebel Task UI in certain respects.

Our example concerns the Account and Activity objects. We have exported the Account WSDL as shown previously and we are about to import it into Policy Modelling.

OPA - CRM On Demand Saving Data

In the above example you can see we have selected Save for the behavior of a particular element. This element will be calculated and the result will be saved back into CRM On Demand by the CRM On Demand data adapter plugin for Policy Automation. In our simple rulebase we calculate the value this way:

OPA - CRM On Demand Simple Rule

In addition, we have created a simple CRM On Demand Web Applet  to display the Question Screen from our Interview. Note the caseID variable which is mapped to the Account Id, and this Web Applet is going to be displayed as a Detail element of the Account Page Layout.

OPA - CRM On Demand Web AppletSo now when we navigate to the corresponding page we see the following in CRM On Demand.

OPA - CRM On Demand Web Applet in Place

Entering or validating the information in the interview is easy thanks to the Question Screen we created in our rulebase.

OPA - CRM On Demand Interview running

And clicking the Save button at the end of the interview saves the inferred value of the the Priority attribute to the mapped CRM On Demand field, showing when we refresh our page. The Save button click can be removed and automated as documented here.

OPA - CRM On Demand After UpdateIf it is the first time you have deployed a rulebase to the crmod-web-determinations server application (not the generic,web-determinations application), you will also need to configure the Policy Automation connection to CRM On Demand and encrypt it as documented in this page.

 

Oracle Policy Automation – Commentary Plugin

Oracle Policy Automation – Commentary Plugin

Many consultants have been spending quality time with Oracle Policy Automation either as part of a Siebel project or for their own benefit to broaden their vision of CRM in general. One of the most commonly needed features in Oracle Policy Automation, just like in all CRM or IT projects, is help. I mean of course Help, as in Assistance. Web Determinations are complex beasts in many cases, and the end user may be faced with the challenge of understanding what they being asked, and should be asking, as well as understanding how it all fits together into the interview.

Let’s face it, if I asked you to enter item PA124 on a tax assessment form, you might need some help too.  Many Oracle Policy Automation Web Determination rulebases use the Commentary feature which automatically generates a set of HTML pages for editing, and displaying in the Web Determination session, based on key pages and attributes of your rulebase.

Generate Commentary Files

And the result can be seen below.

Commentary Standard

However the number of potential files that could be generated (and therefore that have to be managed), might mean quite another headache especially if you intend to release this with multiple translation files attached.

So it is good to note that the Oracle Policy Automation Web Determination Engine offers developers, (after a careful assessment of the business requirement and using all the standard options to try and reach a solution without customizing) , the ability to create a custom Commentary Plugin to replace the standard one.

The format of this plugin is documented online, although it is not entirely up-to-date. Here is a small example of what your Plugin might do:-

Get Commentary Data from an MS SQL Server Database

Storing Commentary in a database has many advantages. Make sure that the relevant JDBC libraries are available to your project. You can download them from Microsoft. Of course your platform might not be the same as mine but they generally can be found here.

Without going into unnecessary detail, I have a database with three columns that are of interest for this demonstration :-

COMMENTLOCATION, COMMENTCONTENT and COMMENTLOCALE

  • Comment Location will be the page identifier in the Web Determination session (so screen/summary is a location)
  • Comment Content will be the HTML we will send the Web Determination session (just some valid HTML for our Assistance text)
  • Comment Locale is the code of the session “en-US” or “fr-FR” for example.

So our table will support any number of items in any number of locales.

Table of Commentary

Coding the Plugin

Our Commentary Plugin will use three key methods to get the job done:- hasCommentary, getCommentaryContent, and RegisterInterviewPlugin. The first will identify if the current location has some Commentary text available in our table, and the second will return the Commentary HTML.

The final RegisterInterviewPlugin will ensure that our code is only used in the case of our special rulebase. All other rulebases will continue to use the standard Commentary system.

Some example Code

package com.oracle.determinations.interview.engine.plugins.commentary;
/* your imports go here
/**
 * Tutorials and Examples - Plugins - Commentary - Sample
 * Code(RedirectCommentary)
 * Adapted from the web example with corrections and adaptations for SQL Server
 * On Demand Education Ltd 2013
 */
public class ODECommentary implements CommentaryProviderPlugin {
private String driver = "com.microsoft.sqlserver.jdbc.SQLServerDriver";
 private Connection connection = null;
 private Statement statement;
 public ODECommentary() {
 try {
 Class.forName(driver);
 System.out.println(driver + "loaded.");
 } catch (ClassNotFoundException e) {
 System.err.print("Class not found: " + e.getMessage());
 }
 }
 /**
 * Connects to the database and creates a statement
 * Uses MS SQL JDBC driver 
 * @throws SQLException
 */
 private void connectDBObjects() throws SQLException {
 connection =DriverManager.getConnection("jdbc:sqlserver://XXX.XXX.XXX.XXX:1433;databaseName=XXXX;user=ODED;password=XXXX");
 /** Output lots of things - just here for debugging
 * remember you can see them using the View > Embedded Web Server Output
 */ 
 System.out.println("Connected to database");
 statement = connection.createStatement();
 }
/**
 * Closes database objects and terminates the connection
 *
 * @throws SQLException
 */
 private void closeDBObjects() throws SQLException {
 statement.close();
 connection.close();
 System.out.println("Closed connection");
 }
 private TypedInputStream executeSQL(String sql, String filter, String field)
 throws RuntimeException {
 TypedInputStream content = null;
 try {
 connectDBObjects();
 if (statement.execute(String.format(sql, filter))) {
 ResultSet result = statement.getResultSet();
 if (result.next()) {
 content = new TypedInputStream(
 "text/html",
 new StringBufferInputStream(new String(result.getString(field))));
 }
 result.close();
 }
 } catch (Exception e) {
 throw new RuntimeException(e.getMessage());
 } finally {
 try {
 closeDBObjects();
 } catch (SQLException e) {
 throw new RuntimeException(e.getMessage());
 }
 }
 return content;
 }
 /** ******************************** */
 /* Web-determinations method calls */
 /** ******************************** */
/**
 * Returns the commentary content for the target if hasCommentary(session,
 * target) is satisfied
 */
 public TypedInputStream getCommentaryContent(InterviewSession session,
 String target) {
 TypedInputStream commentContent = null;
 try {
 /**
 * use the target and separate the locale for multilingual Web Determinations
 * with Commentary in our table
* retrieve Commentary Content for whatever page has Commentary when the user looks at it
 */

 commentContent = executeSQL(
 "select COMMENT_CONTENT from OPACOMMENTS where COMMENT_LOCATION='%s'AND COMMENTLOCALE ='" + session.getLocale() + "'",
 target,
 "COMMENT_CONTENT"
 );
 } catch (RuntimeException e) {
 throw e;
 }
 return commentContent;
 }
 /**
 * Should not be called at all because we are returning false in
 * isCommentaryRedirect(session, target)
 */
 public String getCommentaryURL(InterviewSession session, String target) {
 throw new UnsupportedException(
 "Should not call getCommentaryURL when is isCommentaryRedirect returns false.");
 }
/**
 * Returns true if the commentary for the target is available
 */
 public boolean hasCommentary(InterviewSession session, String target) {
 TypedInputStream commentLocation = null;
 /**
 * use the target and separate the locale for multilingual Web Determinations
 * with Commentary in our table
 */
 try {
 commentLocation = executeSQL(
 "select COMMENT_LOCATION from OPACOMMENTS where COMMENT_LOCATION='%s' AND COMMENTLOCALE='" + session.getLocale() + "'",
 target,
 "COMMENT_LOCATION"
 );
 } catch (RuntimeException e) {
 throw e;
 }
 return (commentLocation != null);
 }
/**
 * Returns true if the commentary for this Web Determinations Interview is
 * available
 */
 public boolean isCommentaryEnabled(InterviewSession session) {
 // check database connection
 try {
 connectDBObjects();
 closeDBObjects();
 return true;
 } catch (Exception e) {
 return false;
 }
 }
/**
 * The example always returns false because the plugin doesn't redirect to
 * another URL to fetch commentary content.
 */
 public boolean isCommentaryRedirect(InterviewSession session, String target) {
 return false;
 }
/**
 * Registers the plugin if and only if the rulebase is
 * 'WHATEVERYOURRULEBASENAMEIS'
 */
 public InterviewSessionPlugin getInstance(InterviewSessionRegisterArgs args) {
 System.out.println("Rulebase identifier is " + args.getSession().getRulebase().getIdentifier());
 if (args.getSession().getRulebase().getIdentifier().equals("WHATEVERYOURRULEBASENAMEIS")) {
 return new ODECommentary();
 }
 return null;
 }
}

Setting it Up

Of course this is not professionally coded and should not be used for anything beyond a learning exercise. After compiling your JAR file, drop it into the

Release\web-determinations\WEB-INF\classes\plugins

folder of your rulebase to test it. Don’t forget that the rulebase name is in the code, to only use our custom Plugin when a certain rulebase is loaded.

Make sure that you have placed edited the section of the code that mentions your server, database and the SQL query.Move any SQL Server drivers into the relevant classpath for your Server (again, for this demonstration we will not deploy on a live server, we will use the embedded one that comes with Oracle Policy Automation) so it might be that your sqljdbc4.jar or similar needs to go in a folder  like

C:Program Files\OraclePolicy Modeling\EmbeddedTomcat\lib

Running the Plugin

Enter at least two lines into your Database Table, preferably using the example (the Summary Screen) for simplicity. Make sure each of the lines has a Locale. Ensure that your rulebase provides either base content or translation files to cover your two Locales.

Run the Web Determination Session from Oracle Policy Modelling with Ctrl + F5. Of course you will need least one question ready to  be asked in your Web Determination session.

ODE Commentary Plugin

In our case as you saw above we are ready to run our session. In the english version we see the text from the appropriate table in our Determination Window.

And the same for the French version, but with the appropriate Commentary of course. For multi-lingual projects particularly this might open up a more manageable, ongoing and interactive approach to Commentary content.

There is a very short video on the web to see what the example looks like here. Happy Commentarying!


Note: The attached files have been removed. If you are interested in them contact the author

Worldwide
Logo by Southpaw Projects LLC