Welcome!

ColdFusion Authors: Maureen O'Gara, Hovhannes Avoyan, Yakov Fain, Pat Romanski, Liz McMillan

Related Topics: ColdFusion

ColdFusion: Article

Playing With(in) the Rules

The Rule Manager Façade

Making Sense of It All
To put this all in perspective, what I'm describing is for many of us a radical shift from the world of billing for custom-software to the world of licensing self-serve enterprise applications. An email client is a good example of the need: if you designed a webmail client you might want to provide the ability to automatically filter incoming messages into different folders when mail is downloaded, however you wouldn't want to be responsible for changing the filters for each of your clients. Instead you would create a flexible filtering engine to allow individual clients to select the criteria on which messages are filtered. This is the sole purpose of the RuleManager application: to provide a flexible interface for users to assign the criteria on which other interactions occur within your application. With this in mind I'll address the application flow.

You operate a hosting company and provide email with a built-in webmail interface. A user signs up for hosting and logs in to the webmail application. Within the application they create several folders for their incoming email, then want to assign filters to automatically move incoming email into these folders when messages are downloaded. After selecting the "filters" link they are presented with an empty list page, and a link to add a new filter (index.cfm).

Once the user selects the "add new filter" link they are brought to the edit-filter page (ruleedit.cfm) where they are presented with a simple form allowing them to provide a name and a description for their new filter. Once they've saved this basic rule information they are returned to the same page with an additional form below, containing a list of different types of criteria that they can add to their new rule. This list of criteria is provided by the RuleManager.cfc, which was probably created in the session scope when they logged in (since email rules only apply to the current user).

After selecting a criteria type (Text) and selecting the "Add Criteria" button the user is again returned to the same edit-filter page. At this point a third form is presented to the user below the previous form for general filter information (name, description) and the "add criteria" form. Although the third form is ultimately created by a criteria.text.cfc object the RuleManager.cfc façade simplifies this process by instantiating the desired criteria-type CFC and calling its criteria.getForm() method within RuleManager.getCriteriaForm(). This encapsulates a significant amount of the functionality of determining the location of the criteria-type CFC and caching it in memory so that individual pages can treat the RuleManager and its criteria as a "black box."

The presented form is unique to Text criteria types - you can see this by selecting the Date criteria type in the "add criteria" form. The Text criteria form contains three elements - text to search (Sender, Subject, Message, Recipient), a user-defined expression, and a selection to determine how the expression is matched against the text (comparison). Although the expression is entered by the user and the types of comparison are defined by the criteria-type CFC, the list of available text properties that can be matched with a Text criteria are provided by the "email" context (EmailRuleContext.cfc).

When the user selects the "apply criteria" button the form is submitted to the criteria-update template (criteriaupdate.cfm). Like the criteria form, the RuleManager façade also simplifies this update template by providing a singular interface to inject the new (or modified) criteria into the specified rule. This is handled by the RuleManager.setCriteriaNode() method. This method internally determines which criteria-type CFC is needed (stored in memory before displaying the form) and uses the appropriate CFC object to generate the XML for the criteria node, which is then injected into ruleset XML document the RuleManager uses as the format for its rules. The RuleManager object doesn't know where this XML document will be stored (file or database - the sample documents use a file, although in a real application email filters would likely be stored in a database), so the criteria-update template then stores the updated XML document and returns the user to the edit-rule page.

After applying the first criteria for the new rule, the user is presented with the general-information and add-criteria forms and a list of the criteria attached to the current rule (with links to edit or delete each criteria). Again because there is no way of knowing how many types of rule criteria may exist or apply to a given rule, it is necessary for the RuleManager façade to rely on the individual criteria-type CFCs to generate a text description of the applied criteria for the user to read. These text-descriptions of the mechanics of each rule-criteria could be omitted on pain of many sleepless nights with technical support calls, however as most of us enjoy our sleep the RuleManager.cfc again determines the appropriate criteria-type CFCs for each applied criteria and uses their criteria.describe() methods to generate the query returned by the RuleManager.getRuleCriteria() method.

The user can now continue on to apply as many additional criteria as they like to their rules, such as the "or" criteria, which allows them to apply mutually exclusive sets of conditions in which the filter is applied. At this point however the entire workflow of the user-interface is satisfied. All that remains is the application or integration of the rules into the flow of the application.

In the sample case a webmail application would contain a template (or CFC method or custom tag) for downloading email from the server. In order to filter the incoming email messages into the appropriate folders, the download process must loop over the downloaded messages and for each message must loop over and test each of the user's email filter rules. Again the RuleManager façade simplifies the process by providing a single method, RuleManager.ruleApplies(ruleid [, context]), which loops over the criteria for an individual rule and tests the applicability of each criterion to provide a boolean value which may be used by the application to determine if the message is filtered.

More Stories By Isaac Dealey

Isaac Dealey has worked with ColdFusion since 1997 (version 3) for clients from small businesses to large enterprises, including MCI and AT&T Wireless. He evangelizes ColdFusion as a volunteer member of Team Macromedia, is working toward becoming a technical instructor, and is available for speaking engagements.

Comments (0)

Share your thoughts on this story.

Add your comment
You must be signed in to add a comment. Sign-in | Register

In accordance with our Comment Policy, we encourage comments that are on topic, relevant and to-the-point. We will remove comments that include profanity, personal attacks, racial slurs, threats of violence, or other inappropriate material that violates our Terms and Conditions, and will block users who make repeated violations. We ask all readers to expect diversity of opinion and to treat one another with dignity and respect.