# The Validation Service

Validation of EMF models is performed by invocation of the validation service. The ModelValidationService provides IValidators that a client may use to validate a selection of elements. The kinds of elements that are validated depends on the nature of the validator, as determined by the EvaluationMode requested by the client.

> [as SVG]

## Validation Modes

The EMF Validation Framework provides two modes of constraint evaluation, defined by the EvaluationMode enumeration: BATCH and LIVE. The batch mode is used for static validation of a selection of model elements, usually in response to some user action such as selecting a Validate menu item or performing some transformation that requires validation of the model as precondition.

The live mode is used to validate changes to objects in some interval that may loosely be called a "transaction." In fact, the EMF Model Transaction API uses the live evaluation mode to implement validation of its transactions when they are committed. In general, though, it is up to a client of the validation framework to determine what are the semantics of a "transaction" and what it means to validate the changes in it.

## The Batch Validator

Upon requesting a validator for the batch mode, a client may safely cast the validator to the IBatchValidator interface to configure it as necessary. The input to batch validation is a collection of EObjects (model elements) to be validated. The output is an IStatus carrying any problems reported by individual validation constraints; this result often is a multi-status.

    List objects = myResource.getContents(); // objects to validate

    // create a validator
    IValidator validator = ModelValidationService.getInstance().newValidator(EvaluationMode.BATCH);

    // use it!
    IStatus results = validator.validate(objects);

    if (!results.isOK()) {
        ErrorDialog.openError(null, "Validation", "Validation Failed", results);
    }

When performing a batch validation operation, it may be important to evaluate any live-mode validation constraints that may have been missed during manipulation of the model. For example, a model may have been imported from another application that didn't apply the same constraints. Simply as the batch validator to include live constraints. The batch validator also supports reporting progress via a progress monitor, which the generic validator interface does not:

    // create a validator.  We know it is a batch validator because we are
    // asking for batch mode
    final IBatchValidator validator = (IBatchValidator) ModelValidationService.getInstance()
            .newValidator(EvaluationMode.BATCH);

    validator.setIncludeLiveConstraints(true);

    getWorkbench().getProgressService().run(true, true, new IRunnableWithProgress() {
        public void run(IProgressMonitor monitor) {
            List objects = myResource.getContents();

            IStatus results = validator.validate(objects, monitor);

            if (!results.isOK()) {
                ErrorDialog.openError(null, "Validation", "Validation Failed", results);
            }
        }});

## The Live Validator

Upon requesting a validator for the live mode, a client may safely cast the validator to the IBatchValidator interface to configure it as necessary. The input to live validation is a collection of Notifications representing discrete changes to model elements (the notifiers). These notifications primarily determine which constraints are applied to an element. For efficiency, live-mode constraints should declare the changes that trigger them, but they still validate the notifying object as a whole (to support optional invocation in batch mode).

    List notifications = transaction.getChanges(); // changes in some hypothetical transaction scope

    // create a validator
    IValidator validator = ModelValidationService.getInstance().newValidator(EvaluationMode.LIVE);

    // use it!
    IStatus results = validator.validate(notifications);

    if (!results.isOK()) {
        ErrorDialog.openError(null, "Validation", "Validation Failed", results);
    }

> [as SVG]

The live validator also can be supplied with a filter, to weed out notifications that should not be considered for validation. The default filter, when none is provided by the client, filters out notifications from objects that are not (or no longer are) attached to a Resource.

    List notifications = transaction.getChanges(); // changes in some hypothetical transaction scope

    // create a validator
    ILiveValidator validator = (ILiveValidator) ModelValidationService.getInstance()
            .newValidator(EvaluationMode.LIVE);

    // validate only changes to containment references
    validator.setNotificationFilter(new FilteredCollection.Filter() {
            public boolean accept(Object element) {
                Object feature = ((Notification) element).getFeature();

                return feature instanceof EReference && ((EReference) feature).isContainment();
            }
        });

    IStatus results = validator.validate(notifications);

    if (!results.isOK()) {
        ErrorDialog.openError(null, "Validation", "Validation Failed", results);
    }

## Constraint Filtering

In either batch or live validation scenarios, a client may have a need to evaluate only some well-defined subset of the constraints that are available. For this, a validator can be configured with any number of IConstraintFilters. Only constraints that match all of the filters are validated. There is no default filter. For example, to check only for severe problems (e.g., to evaluate preconditions of some model transformation):

    List objects = myResource.getContents(); // objects to validate

    IValidator validator = ModelValidationService.getInstance().newValidator(EvaluationMode.BATCH);

    // validate only error severity and worse
    validate.addConstraintFilter(new IConstraintFilter() {
            public boolean accept(IConstraintDescriptor constraint, EObject target) {
                ConstraintSeverity sev = constraint.getSeverity();
                return sev.toIStatusSeverity() >= IStatus.ERROR.
            }
        });

    IStatus results = validator.validate(objects);

    if (!results.isOK()) {
        ErrorDialog.openError(null, "Validation", "Validation Failed", results);
    }

Copyright (c) 2000, 2007 IBM Corporation and others. All Rights Reserved.