Exercise 4 (Optional). Validation Framework - Implementing A Named Constraint
What This Exercise Is About
Having learned how to use EMF's Validation Framework to validate model instance data, you will now add a named constraint to the XML Schema from which the model code was generated, and implement the validation code required to activate the constraint in your PurchaseOrder model editor.

What You Should Be Able To Do
At the end of the
lab, you should be able to:
- Modify an XML Schema model to add an arbitrary, named constraint, using an <xsd:annotation/>
- Generate model code which implements that constraint
- Write code to implement the specific behaviour of that constraint
- Test validation by inputting valid and invalid data into a purchase order, then running the Validate action
Required Materials
- Eclipse 3.2
- Eclipse Modeling Framework (EMF) 2.2
General Advice / Warnings
- You can run validation on any object node (Item, USAddress), not just the root node (Document Root). If you want to validate the entire instance, you should select the topmost object (Document Root) from which to validate downward
- If you plan to use XML Schema to import a model, make sure you're using the IBM JDK or else have implemented the Sun JDK Crimson DOM bug workaround (http://eclipse.org/emf/downloads-xerces.php)
- Make sure that if you're manually editing a XML Schema file to add constraints, <xsd:annotation/> must always be at the start of <xsd:complexType/>
- For more on XML Schema:
Exercise Instructions
This exercise is
carried out entirely using the Eclipse Software Development Kit (SDK)
version 3.2 with the Eclipse Modeling Framework (EMF) 2.2 installed
into it. The exercise instructions refer to this product as either
Eclipse or as "the workbench."
In your workspace, there should be a EMF_Workshop/Exercise4_Validation folder
containing a new version of PurchaseOrder.xsd, which has been revised to include a named constraint.
Directions
Step A: Setup
- If you did not complete Exercise 1, please return to that exercise and complete it before proceeding.
- Switch to the
Plug-in Development perspective, if not already there.
- Select Window
-> Open Perspective -> Other... -> Plug-in Development.
Step B: Add Named Constraint to Schema
- Review the changes made to PurchaseOrder.xsd, compared to the version in the Exercise 1 source folder. If you open both the Exercise 1 and 4 source folders, you can select both versions of the file, then right-click and select Compare With -> Each Other. The following annotation was added.
<xsd:annotation>
<xsd:appinfo source="http://www.eclipse.org/emf/2002/Ecore"
ecore:key="constraints">VolumeDiscount</xsd:appinfo>
</xsd:annotation>
- Copy the Exercise 4 version of PurchaseOrder.xsd on top of the Exercise 1 version, replacing it. If you want to maintain two different files (for comparison), rename the Exercise 1 version first, then copy the Exercise 4 version into that folder.
- Open the file com.example.po/src/com.example.po.util/POValidator.java. This file contains methods used to validate your model. Using the Outline view, find the method validatePurchaseOrder(). Notice that it contains only one line, delegating this method to validate_EveryDefaultConstraint():
public boolean validatePurchaseOrder(PurchaseOrder purchaseOrder,
DiagnosticChain diagnostics, Map context)
{
return validate_EveryDefaultConstraint(purchaseOrder, diagnostics,
context);
}
- Right-click the file com.example.po/model/PurchaseOrder.genmodel, and select Reload... in order to push changes to your schema into your generator model.
- Select XML Schema. Hit Next, then Next, then Finish.
- Open PurchaseOrder.genmodel (if not already open). Right-click the main node PurchaseOrder, then select Generate Model Code to regenerate your code from the new generator model.
- Switch back to POValidator.java. Notice now that the validatePurchaseOrder() method contains several more validation steps, and that there is also a new method, validatePurchaseOrder_VolumeDiscount(). This is the method we now must implement.
Step C: Implement Validation Code
- If you switch to the Tasks view (Window -> Show View -> Tasks), you will see a new TODO.

- If you double-click the TODO, it will open the associated file (if not already open) and jump to the line containing the TODO comment.
- At this point, if you were to open your PurchaseOrder model editor (in your second workbench), you would not see anything different, since the constraint has not been implemented, and thus always returns true (valid).
- If pressed for time, you can copy code from the JPages folder under the Exercise 4 source folder. Otherwise, the steps to code are listed below.
- Ensure that you remove the @generated annotation or mark it @generated NOT, in order to prevent losing your changes should you regenerate.
- Iterate through the purchase order's items to compute the total value of the order.
float totalValue = 0;
for (Iterator iter = purchaseOrder.getItems().iterator(); iter.hasNext(); )
{
Item item = (Item)iter.next();
totalValue += item.getPrice() * item.getQuantity();
}
- If the total value of the order is $500.00 or more, add a diagnostic with severity level Diagnostic.INFO. The method should always return true.
if (totalValue >= 500 && diagnostics != null)
{
diagnostics.add
(new BasicDiagnostic
(Diagnostic.INFO,
DIAGNOSTIC_SOURCE,
0,
"This order qualifies for a 5% discount because its total value, $"
+ totalValue + ", is at least $500.",
new Object[] { purchaseOrder }));
}
return true;
Step D: Test Named Constraint
- Launch your second workbench again, using the same launch configuration from Exercise 1. There are many ways to do this.
- Select from the Run menu Run History -> Eclipse Application.
- Click the Run button in the coolbar (a green circle with a white triangle in it, or a "play" button) and select Run History -> Eclipse Application.
- Hit SHIFT-ALT-X (eXecute). Wait one second for the context menu to open, then then hit E (Eclipse Application).
- From your first workbench, copy the file Exercises/data/po-valid.xml into the po project of your second workbench. Rename the file to po-valid.po.
- Open the file po-valid.po. Select the Document Root node, then select PO Editor -> Validate. You will now get an information alert, since the value of the purchase order is at least $500. As in Exercise 1, this information will also appear in the Problems view.

- Optionally, you may want to explore the other constraints in PurchaseOrder.xsd. If so, copy the other purchase order instance documents (*.po) in the EMF_Workshop/Solution4_Optional/data folder of your first workbench to your second workbench. Open each one in turn, validate it, and observe the errors that appear.
Summary
You have learned how to implement an arbitrary, named constraint in an XML Schema document, then generate the code to validate that constraint, and finally, to write the code to implement the details of the validation.
Sample Output
