Skip Headers
Oracle® Application Development Framework Developer's Guide For Forms/4GL Developers
10g (10.1.3.1.0)

Part Number B25947-01
Go to Documentation Home
Home
Go to Book List
Book List
Go to Table of Contents
Contents
Go to Index
Index
Go to Master Index
Master Index
Go to Feedback page
Contact Us

Go to previous page
Previous
Go to next page
Next
View PDF

26.9 Implementing Custom Validation Rules

ADF Business Components comes with a base set of built-in declarative validation rules that you can use. However, the most powerful feature of the validator architecture for entity objects is that you can create your own custom validation rules. When you notice that you or your team are writing the same kind of validation code over and over, you can build a custom validation rule class that captures this common validation "pattern" in a parameterized way. Once you've defined a custom validation rule class, you can register it in JDeveloper so that it is as simple to use as any of the built-in rules. In fact, as you see in the following sections, you can even bundle your custom validation rule with a custom UI panel that JDeveloper will leverage automatically to facilitate developers' using and configuring the parameters your validation rule might require.

26.9.1 How To Create a Custom Validation Rule

To write a custom validation rule for entity objects, create a Java class that implements the JboValidatorInterface in the oracle.jbo.rules package. As shown in Example 26-18, this interface contains one main validate() method, and a getter and setter method for a Description property.

Example 26-18 All Validation Rules Must Implement the JboValidatorInterface

package oracle.jbo.rules;
public interface JboValidatorInterface {
        void validate(JboValidatorContext valCtx) { }
        java.lang.String getDescription() { }
        void setDescription(String description) { }
}

If the behavior of your validation rule will be parameterized to make it more flexible, then add additional bean properties to your validator class for each parameter. For example, the SRDemo application contains a custom validation rule called DateMustComeAfterRule which validates that one date attribute must come after another date attribute. To allow developer's using the rule to configure the names of the date attributes to use as the initial and later dates for validation, this class defines two properties initialDateAttrName and laterDateAttrName.

Example 26-19 shows the code that implements the custom validation rule. It extends the AbstractValidator to inherit support for working automatically with the entity object's custom message bundle, where JDeveloper will automatically save the validation error message when a developer uses the rule on one of their entity objects.

The validate() method of the validation rule gets invoked at runtime whenever the rule class should perform its functionality. The code performs the following basic steps:

  1. Ensures validator is correctly attached at the entity level.

  2. Gets the entity row being validated.

  3. Gets the values of the initial and later date attributes.

  4. Validate sthat initial date is before later date.

  5. Throws an exception if the validation fails.

Example 26-19 Custom DateMustComeAfterRule in the SRDemo Application

package oracle.srdemo.model.frameworkExt.rules;
// NOTE: Imports omitted
public class DateMustComeAfterRule extends AbstractValidator
       implements JboValidatorInterface {
  /**
   * This method is invoked by the framework when the
   * validator should do its job.
   */
  public void validate(JboValidatorContext valCtx) {
    // 1. If validator is correctly attached at the entity level...
    if (validatorAttachedAtEntityLevel(valCtx)) {
      // 2. Get the entity row being validated
      EntityImpl eo = (EntityImpl)valCtx.getSource();
      // 3. Get the values of the initial and later date attributes
      Date initialDate = (Date) eo.getAttribute(getInitialDateAttrName());
      Date laterDate = (Date) eo.getAttribute(getLaterDateAttrName());
      // 4. Validate that initial date is before later date
      if (!validateValue(initialDate,laterDate)) {
        // 5. Throw the validation exception
        RulesBeanUtils.raiseException(getErrorMessageClass(),
                                      getErrorMsgId(),
                                      valCtx.getSource(),
                                      valCtx.getSourceType(),
                                      valCtx.getSourceFullName(),
                                      valCtx.getAttributeDef(),
                                      valCtx.getNewValue(),
                                      null, null);
      }
    }
    else {
      throw new RuntimeException("Rule must be at entity level");
    }
  }
  /**
   * Validate that the initialDate comes before the laterDate.
   */
  private boolean validateValue(Date initialDate, Date laterDate) {
    return (initialDate == null) || (laterDate == null) ||
    (initialDate.compareTo(laterDate) < 0);
  }
  /**
   * Return true if validator is attached to entity object
   * level at runtime.
   */
  private boolean validatorAttachedAtEntityLevel(JboValidatorContext ctx) {
    return ctx.getOldValue() instanceof EntityImpl;
  }
  // NOTE: Getter/Setter Methods omitted
  private String description;
  private String initialDateAttrName;
  private String laterDateAttrName;
}

For easier reuse of your custom validation rules, you would typically package them into a JAR file for reference by applications that make use of the rules. In the SRDemo application, the FrameworkExtensions project contains a DateMustComeAfterRule.deploy deployment profile that packages the rule class into a JAR file named DateMustComeAfterRule.jar for use at runtime and design time.

26.9.2 Adding a Design Time Bean Customizer for Your Rule

Since a validation rule class is a bean, you can implement a standard JavaBean customizer class to improve the design time experience of setting the bean properties. In the example of the DateMustComeAfter rule in the previous section, the two properties developers will need to configure are the initialDateAttrName and laterDateAttrName properties.

Figure 26-4 illustrates using JDeveloper's visual designer for Swing to create a DateMustComeAfterRuleCustomizer using a JPanel with a titled border containing two JLabel prompts and two JComboBox controls for the dropdown lists. The code in the class populates the dropdown lists with the names of the Date-valued attributes of the current entity object being edited in the IDE. This will allow a developer who adds a DateMustComeAfterRule validation to their entity object to easily pick which date attributes should be used for the starting and ending dates for validation.

Figure 26-4 Using JDeveloper's Swing Visual Designer to Create Validation Rule Customizer

Image of visually creating validation rule customizer

To associate a customizer with your DateMustComeAfterRule Java Bean, you follow the standard practice of creating a BeanInfo class. As shown in Example 26-20, the DateMustComeAfterRuleBeanInfo returns a BeanDescriptor that associates the customizer class with the DateMustComeAfter bean class.

You would typically package your customizer class and this bean info in a separate JAR file for design-time-only use. The FrameworkExtensions project in the SRDemo application contains a deployment profile that packages these classes in a DateMustComeAfterRuleDT.jar.

Example 26-20 BeanInfo to Associate a Customizer with a Custom Validation Rule

package oracle.srdemo.model.frameworkExt.rules;
import java.beans.BeanDescriptor;
import java.beans.SimpleBeanInfo;
public class DateMustComeAfterRuleBeanInfo extends SimpleBeanInfo {
  public BeanDescriptor getBeanDescriptor() {
    return new BeanDescriptor(DateMustComeAfterRule.class,
                              DateMustComeAfterRuleCustomizer.class);
  }
}

26.9.3 Registering and Using a Custom Rule in JDeveloper

To use a custom validation rule in a project containing entity objects, follow these steps:

  1. Define a project-level library for the rule JAR files.

  2. Add that library to your project's library list.

  3. Use the Business Components > Registered Rules panel of the Project Properties dialog to add a one or more validation rules.

    When adding a validation rule, provide the fully-qualified name of the validation rule class, and supply a validation rule name that will appear in JDeveloper's list of available validators.

Figure 26-5 shows the Validation panel of the Entity Object editor for the SRDemo application's ServiceRequest entity object. When you edit the DateMustComeAfter rule, you can see the custom editing panel is automatically discovered from the rule class' BeanInfo and used at design time to show the developer the starting and ending attribute names. JDeveloper provides the support for capturing the translatable error message that will be shown to the end-user if the validation rule fails at runtime.

Figure 26-5 Custom Validation Rule with Custom Editor Panel in JDeveloper

Image shows Edit Validation Rule for custom validation rule