h2(#Integration). OCL Integration

The "OCLinEcore Editor":#OCLinEcore editor enables OCL to be embedded in Ecore. This section explains how that OCL is executed.

The "Complete OCL":#CompleteOCL editor enables OCL to be provided as a complementing document. This section explains how that complement is installed to become part of the complemented model.

The "Interactive OCL":#InteractiveOCL console allows you to load OCL and execute OCL expression interactively.

The "Java API":#ProgrammersGuide explains how you can take control of the OCL installation and activation.

h3(#Integration-OCLinEcore). OCL execution in Ecore / EMF Delegates

The EMF delegate mechanisms and EAnnotations that enable EMF to delegate to OCL to support
* validation of invariants
* execution of operation bodies
* evaluation of property initial and derived values
are described in the "Delegates":#Delegates section of the Programmers Guide.

h3(#Integration-Messages). Custom Validation Messages

Eclipse OCL supports the product of custom messages by defining a String-valued message expression as a parenthesized clause on an invariant.

For instance in the OCLinEcoreTutorial Example

bc.. 
invariant SufficientCopies:
	library.loans->select((book = self))->size() <= copies;
invariant SizeOk('Expected 4 ' + rather than  
p. 

may be changed to

bc.. 
invariant SufficientCopies('There are '
	+ library.loans->select((book = self))->size().toString()
	+ ' loans for the ' + copies.toString() + ' copies of \'' + name + '\''):
	library.loans->select((book = self))->size() <= copies;
p. 

to replace the default diagnostic:

bc.. 
The 'SufficientCopies' constraint is violated on 'Book b2'.
p. 

by

bc.. 
There are 3 loans for the 2 copies of 'b2'.
p. 

Unfortunately, in the Indigo release, EMF does not support this customization. This must be activated explicitly using an EValidator that is aware of the ValidationDelegateExtension extended API. This is available by using the "OCLinEcoreEObjectValidator":#OCLinEcoreEObjectValidator.

h3(#Integration-CompleteOCL). CompleteOCL Validation

Integration of Complete OCL documents is harder because Complete OCL complements pre-existing models. These cannot always be aware of the existence of that complement, since the author of a model cannot know what complements may be added by its users.

The complete model formed from the primary models and the OCL complements is application-specific and so applications must gather the contributions together. Prior to the Indigo release, this restricted Complete OCL usage to Java applications that could gather the complements.

The Indigo release provides some assistance. A more general registration approach is needed.

When using the "Xtext OCL Console":#InteractiveOCL there is a *Load Resource* icon on the tool bar that allows additional Complete OCL resources to be loaded to complement the primary models determined by EObject selections.

The "CompleteOCLEObjectValidator":#CompleteOCLEObjectValidator may be used to install a Complete OCL document.

h3. OCLinEcore for Xtext Validation

If you want to use OCLinEcore as a validation language for Xtext you must:

Use a manually maintained Ecore model to define your parsed grammar model, otherwise your embedded OCL will be lost each time you regenerate the editor. For non-trivial models, switching from auto-generated to manual manitenance is a good idea, since you may need to control changes carefully to maintain upward compatibility for existing models.

Modify the Validator class generated by genmodel to extend OCLinEcoreEObjectValidator rather than EObjectValidator. See "OCLinEcoreEObjectValidator":#OCLinEcoreEObjectValidator for details.

h3. Complete OCL for Xtext Validation

If you want to use Complete OCL as a validation language for Xtext you may use the "CompleteOCLEObjectValidator":#CompleteOCLEObjectValidator to register the Complete OCL for EMF Validation. This may readily be achieved by reusing the empty example JavaValidator created by Xtext to install the Complete OCL. If your Xtext language is _States_, and your Complete OCL is _model/States.ocl_ in _StatesProject_ you should change your StatesJavaValidator to:

bc.. 
public class StatesJavaValidator extends AbstractStatesJavaValidator
{
    @Override
    public void register(EValidatorRegistrar registrar) {
        super.register(registrar);
        StatesPackage ePackage = StatesPackage.eINSTANCE;
        URI oclURI = URI.createPlatformResourceURI(
            "/StatesProject/model/States.ocl", true);
        registrar.register(ePackage,
            new CompleteOCLEObjectValidator(ePackage, oclURI));
    }
}
p. 

