Start the Entity Editor
That's all that is necessary to create an entity language, including support for data types and nested packages. The complete grammar now looks like this:
grammar org.example.domainmodel.Domainmodel
with org.eclipse.xtext.common.Terminals
generate domainmodel "http://www.example.org/domainmodel/Domainmodel"
Domainmodel:
(elements += AbstractElement)*
;
PackageDeclaration:
'package' name = QualifiedName '{'
(elements += AbstractElement)*
'}'
;
AbstractElement:
PackageDeclaration | Type | Import
;
QualifiedName:
ID ('.' ID)*
;
Import:
'import' importedNamespace = QualifiedNameWithWildcard
;
QualifiedNameWithWildcard:
QualifiedName '.*'?
;
Type:
DataType | Entity
;
DataType:
'datatype' name=ID
;
Entity:
'entity' name = ID ('extends' superType = [Entity | QualifiedName])?
'{'
(features += Feature)*
'}'
;
Feature:
(many ?= 'many')? name = ID ':' type = [Type | QualifiedName]
;
Now What?
The next step is to fire up the generator, which will process the grammar definition and derive some infrastructure and configuration information from it. Locate the GenerateDomainmodel.mwe2 next to the grammar file and choose:
Run As -> MWE2 Workflow
from the context menu. After the generator was executed successfully, you can test drive the editor in a new Eclipse application. Therefore, select :
Run As -> Eclipse Application
on the project org.example.domainmodel to launch a new Eclipse process. You are already in the home stretch: Create a new Project using a sample file with the right extension, e.g., Sample.dmodel; and then you can try the editor (Figure 2).
Custom Checks
One main advantages of external DSLs (that is, DSLs that are a separate part of a package) is the ability to specify the semantics and the validation rules. Because you have full control over the language, you can define constraints that are specific to your project and environment. To illustrate how this can be done with Xtext, let's add a check to ensure that multi-value features only refer to entities.
The generator that processed the grammar definition already created stubs for commonly used customization points among them the hook for static analysis. The class DomainmodelJavaValidator should be enhanced with constraints specific for the language. It provides a convenient API to write checks. Each method written in that class that is annotated with @Check is invoked by the framework in the validation phase. The methods specify the type of the validated model element by means of their first argument. When you identify a problem, error(..), warning(..) or info(..) can be used to report it as shown in this code.
package org.example.domainmodel.validation;
import org.eclipse.xtext.validation.Check;
import org.example.domainmodel.domainmodel.DomainmodelPackage;
import org.example.domainmodel.domainmodel.Entity;
import org.example.domainmodel.domainmodel.Feature;
public class DomainmodelJavaValidator
extends AbstractDomainmodelJavaValidator {
@Check
public void checkFeature(Feature f) {
if (f.isMany() && !(f.getType() instanceof Entity)) {
error("Multi value features have to point to entities",
DomainmodelPackage.Literals.FEATURE__MANY);
}
}
}
The validation hook is certainly not the only customization point provided by Xtext. Fine-grained customization with other customization techniques is demonstrated by the documentation on the Xtext website.[5]
In the next installment, I'll show how to take this language definition and put it to use.
References
Sebastian Zarnekow is core committer to the Xtext project.


