Constraints are contributed into the EMF Validation Framework by constraint providers.
These are declared as extensions on the
org.eclipse.emf.validation.constraintProviders point. The framework
offers support for two kinds of providers: static providers, which declare all of their
constraints in the plugin.xml, and
dynamic providers, which obtain their constraints at
run-time from some source that they determine. Static providers, the subject of this topic,
are really just a built-in implementation of the dynamic provider API.
Statically Declaring Constraints
The static constraint provider declares all of its constraints in its extension in
the plugin.xml file on the
org.eclipse.emf.validation.constraintProviders
extension point. Each <constraint>
element provides all of the metadata required by the
constraint descriptor, plus a language-specific declaration
of the constraint's implementation. For
OCL constraints, this is
simply the constraint expression. For
Java constraints,
it is the class name.
<extension point="org.eclipse.emf.validation.constraintProviders">
<category name="Library Constraints" id="org.eclipse.example.library">
<constraintProvider>
<package namespaceUri="https:///org/eclipse/emf/examples/library/extlibrary.ecore/1.0.0"/>
<constraints categories="org.eclipse.example.library">
<constraint
lang="Java"
class="com.example.constraints.UniqueLibraryName"
severity="WARNING"
mode="Live"
name="Library Must have a Unique Name"
id="org.eclipse.example.library.LibraryNameIsUnique"
statusCode="1">
<description>Libraries have unique names.</description>
<message>{0} has the same name as another library.</message>
<target class="Library">
<event name="Set">
<feature name="name"/>
</event>
</target">
</constraint>
</constraints>
</constraintProvider>
</extension>
The example above declares a category with an ID and a localizable name. This category is
referenced as one of the categorizations of the group of constraints that is declared in
the <constraintProvider> element.
The constraint provider class is implicit; the provider that obtains static constraint
definitions from the plugin.xml is provided by the framework and
is the default provider. This example indicates that it provides constraints for the
EXTLibrary example model. This is a high-level enablement
condition, which allows the framework to not consult or even instantiate this provider
until it needs to validate library objects. Any number of packages can be specified.
Next is a group of <constraints> which, as mentioned already,
is associated with the category defined earlier. This example declares a single constraint
in this group. It is a Java-language constraint implemented by the class indicated, which
must be accessible on the declaring plug-in's classpath (not necessarily deployed in this
plug-in). It specifies severity (error would be the default), evaluation mode (batch is
the default), localizable name, and unique ID. The ID's uniqueness is ensured by the
framework; if it is not already prepended by the declaring plug-in's ID, then the framework
will prepend it on the plug-in's behalf. Thus, the ID could have been specified simply as
"LibraryNameIsUnique."
The status code is arbitrary, used merely to populate the IStatus
objects created by the framework on constraint violation. The localizable description
appears in the preference page, and the message appears in problems reported by the
constraint. Any number of positional arguments (in the MessageFormat
pattern) may be specified. The constraint implementation determines how they are filled.
Last, but very important, is the declaration of the EClasses
targeted by this constraint and the events that trigger it. Zero or more targets may be
specified (none implying any object of the constraint provider's packages). This example
is a live constraint, and specifies that it is triggered by
Notification.SET event types on the name
feature. A batch constraint would not specify such triggers.
Note that these events are not really sufficient to ensure that live validation always
detects when duplication of library names occurs. For example, a library that already has
a duplicate name may be attached to the model. In this case, the application may not
receive and events from the name because it doesn't start listening until the library is
attached.
Another topic discusses a mechanism that
can help with this problem.
Copyright (c) 2000, 2007 IBM Corporation and others. All Rights Reserved.