Thursday, April 23, 2009

A Regular Expression Validation

Data Validation Manager is great, but what would validation be without Regular Expressions? Here's how I used both to meet a business requirement.


The requirement arose from some errors logged when Siebel would attempt to send email to invalid addresses. We wanted to notify a user who entered invalid characters in the email address field. Of course, this edit wouldn't guarantee that addresses entered would actually exist, but it would at least ensure that people wouldn't separate two addresses with a colon (':') instead of a semicolon (';'), which is what was happening.


Step 1: Create a Business Service


Create a new Business Service with a method containing the following code snippet:

var sPattern = Inputs.GetProperty("Pattern");
var sSample = Inputs.GetProperty("Sample");
var rExp = new RegExp(sPattern);


if(rExp.test(sSample))
{
    Outputs.SetProperty("Result", 1);
}
else
{
    Outputs.SetProperty("Result", 0);
}


Step 2: Create a Data Validation Rule


Our Data Validation Rule Set is called "Employee Email Validation". In the data validation rule, use the new business service to test a business component field against a regular expression pattern. Use the following syntax for the pattern:


InvokeServiceMethod("ABC Validation Service", "Validate", "Pattern='^(([a-zA-Z0-9_\-\.]+)@([a-zA-Z0-9_\-\.]+)\.([a-zA-Z]{2,5}))+([;,](([a-zA-Z0-9_\-\.]+)@([a-zA-Z0-9_\-\.]+)\.([a-zA-Z]{2,5}))+)*$', Sample=eval([EMail Addr])", "Result")<>0


The regular expression pattern above was adapted from one available on the website http://www.regular-expressions.info/, where you can quickly learn how to get started with regular expressions. Also note the use of the eval() function, which will result in the contents of the Business Component Field being passed to the business service instead of the literal field name. See Metalink Doc ID 782338.1 (login required) for Oracle's How-To article for using eval() with InvokeServiceMethod() for a very similar application.


Step 3: Create a Runtime Event


Your next step is to create a Runtime Event manually through the Administration - Runtime Events screen. For our data validation, we created an Action Set for the Employee WriteRecord event.


  • Action Type: BusService

  • Business Service Name: Data Validation Manager

  • Business Service Method: Validate

  • Business Service Context: "Rule Set Name", "Employee Email Validation", "Enable Log", "Y"

Please note that although we did our validation on the Employee BusComp, it doesn't work on the Administration - User -> Employees. We have a custom view created on the Employee BusComp that exposes the email field. I'm not actually sure why it doesn't work in the vanilla view, but I'll post an update if I find out.


Step 4: Update Enterprise Parameter


A security feature introduced with Siebel 7.7 restricts the InvokeServiceMethod function to only business services that are registered on the Query Access List. The parameter can be set at the enterprise level or the component (e.g., Object Manager) level. However, since component-level settings always override enterprise settings, setting the parameter at the component level would preclude the use of any other business services that are registered at the enterprise.


  • Enterprise Parameter Name: Business Service Query Access List

  • Enterprise Parameter Value: ABC Validation Service

A common Siebel software limitation applies here. Only a maximum of 100 characters can be used to specify business service names in this parameter. You should carefully plan which business services you want to use with InvokeServiceMethod. Do not leave spaces between multiple business service names, but separate names with commas, and do not use quote marks.


Conclusion


After setting up a very simple business service to evaluate regular expressions, we can create any number of complex validations to display a message when a pattern is matched, with no additional scripting at all. For example, another requirement to validate the format of an identification number in a free text field was accomplished with a second data validation using the same business service.


If you are new to regular expressions, take a look. They are incredibly useful.

6 comments:

Ersin ERSOY said...

Hi,

Thanks for this post. It is great.

I have a question, did you solve the problem that is validation is not working on vanilla Employee view?

ankIT WALiA said...

Nice post Jim.

Cindy Dy said...

Man I love this site. It is just so awesome. Whatever you want, all are available here.

www.imarksweb.org

Unknown said...

Thanks for this post.
Email Validation

Neil Simpson said...

Hi,

I was able to recreate this, and I have the Business Service successfully returning 0 or 1 depending on if this is valid. However, after the debugger leaves the BS, I get the error:

[1]Wrong field values or value types detected in field FIELDNAME. Please re-enter your field values. If you need additional assistance, please refer to the documentation.(SBL-UIF-00299)
[2]The method 'Regex' is not supported on Business Service 'Validation Service'.(SBL-DAT-00323)

I'm confused here because it still definitely steps through my code, so it must be supported.

If I include a `return (CancelOperation);`, I get the following error:

[1]Wrong field values or value types detected in field FIELDNAME. Please re-enter your field values. If you need additional assistance, please refer to the documentation.(SBL-UIF-00299)
[2]The value 'testtest' for field 'FIELDNAME' is required to be 'InvokeServiceMethod("Validation Service", "Regex", "pattern='^([a-zA-Z]{2}\-{0,1}\d{7}|[a-zA-Z0-9]{12})$', value=eval([FIELDNAME])", "isValid") <> 0'
Please enter a value that is 'InvokeServiceMethod("Validation Service", "Regex", "pattern='^([a-zA-Z]{2}\-{0,1}\d{7}|[a-zA-Z0-9]{12})$', value=eval([FIELDNAME])", "isValid") <> 0'.(SBL-DAT-00521)

If I have it do a `return (ContinueOperation);`, nothing happens and it accepts the field value, correct or not.

Does anybody know what might be wrong here?

Neil Simpson said...

I found the issue. I was using a Virtual BC for this. When Using a regular BC, the proper validation message showed up.