Ecore Metamodeling

Advanced Metamodel Features

Learn how to use enumerations, inheritance, and abstract classes to create sophisticated metamodels.

In this tutorial, you’ll extend the Company metamodel with advanced Ecore features including EEnum for typed constants, class inheritance hierarchies, and abstract base classes.

35 mins Estimated Time

Section 1

Understanding EEnum

EEnum defines enumeration types—fixed sets of named values. Use enumerations to model properties that can only take specific predefined values, such as employment status or project priority.

Enumerations provide type safety and make your models more expressive by replacing generic strings or integers with meaningful, constrained values.

EEnum for Typed Constants

Step 1

Start with the bidirectional Company metamodel from Tutorial 03.

We’ll add an EEnum to represent employment status for Person instances.

Company.ecore
1<?xml version="1.0" encoding="UTF-8"?>
2<ecore:EPackage xmi:version="2.0"
3 xmlns:xmi="http://www.omg.org/XMI"
4 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5 xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore"
6 name="company"
7 nsURI="http://www.example.org/company"
8 nsPrefix="company">
9
10 <eClassifiers xsi:type="ecore:EClass" name="Person">
11 <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
12 <eStructuralFeatures xsi:type="ecore:EAttribute" name="email" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
13 <eStructuralFeatures xsi:type="ecore:EReference" name="employer" eType="#//Company" eOpposite="#//Company/employees"/>
14 </eClassifiers>
15
16 <eClassifiers xsi:type="ecore:EClass" name="Company">
17 <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
18 <eStructuralFeatures xsi:type="ecore:EReference" name="employees" upperBound="-1" eType="#//Person" containment="true" eOpposite="#//Person/employer"/>
19 </eClassifiers>
20
21</ecore:EPackage>

Step 2

Add an EEnum for employment status.

The EEnum defines three literal values: FULL_TIME, PART_TIME, and CONTRACTOR. Each literal has a name and a numeric value attribute.

Company.ecore
1<?xml version="1.0" encoding="UTF-8"?>
2<ecore:EPackage xmi:version="2.0"
3 xmlns:xmi="http://www.omg.org/XMI"
4 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5 xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore"
6 name="company"
7 nsURI="http://www.example.org/company"
8 nsPrefix="company">
9
10 <eClassifiers xsi:type="ecore:EEnum" name="EmploymentStatus">
11 <eLiterals name="FULL_TIME" value="0"/>
12 <eLiterals name="PART_TIME" value="1"/>
13 <eLiterals name="CONTRACTOR" value="2"/>
14 </eClassifiers>
15
16 <eClassifiers xsi:type="ecore:EClass" name="Person">
17 <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
18 <eStructuralFeatures xsi:type="ecore:EAttribute" name="email" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
19 <eStructuralFeatures xsi:type="ecore:EReference" name="employer" eType="#//Company" eOpposite="#//Company/employees"/>
20 </eClassifiers>
21
22 <eClassifiers xsi:type="ecore:EClass" name="Company">
23 <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
24 <eStructuralFeatures xsi:type="ecore:EReference" name="employees" upperBound="-1" eType="#//Person" containment="true" eOpposite="#//Person/employer"/>
25 </eClassifiers>
26
27</ecore:EPackage>

Step 3

Add an attribute to Person using the enum type.

The status attribute references the EmploymentStatus enum using eType="#//EmploymentStatus". Now Person instances can only have one of the three defined status values.

Company.ecore
1<?xml version="1.0" encoding="UTF-8"?>
2<ecore:EPackage xmi:version="2.0"
3 xmlns:xmi="http://www.omg.org/XMI"
4 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5 xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore"
6 name="company"
7 nsURI="http://www.example.org/company"
8 nsPrefix="company">
9
10 <eClassifiers xsi:type="ecore:EEnum" name="EmploymentStatus">
11 <eLiterals name="FULL_TIME" value="0"/>
12 <eLiterals name="PART_TIME" value="1"/>
13 <eLiterals name="CONTRACTOR" value="2"/>
14 </eClassifiers>
15
16 <eClassifiers xsi:type="ecore:EClass" name="Person">
17 <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
18 <eStructuralFeatures xsi:type="ecore:EAttribute" name="email" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
19 <eStructuralFeatures xsi:type="ecore:EAttribute" name="status" eType="#//EmploymentStatus"/>
20 <eStructuralFeatures xsi:type="ecore:EReference" name="employer" eType="#//Company" eOpposite="#//Company/employees"/>
21 </eClassifiers>
22
23 <eClassifiers xsi:type="ecore:EClass" name="Company">
24 <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
25 <eStructuralFeatures xsi:type="ecore:EReference" name="employees" upperBound="-1" eType="#//Person" containment="true" eOpposite="#//Person/employer"/>
26 </eClassifiers>
27
28</ecore:EPackage>

Section 2

Class Inheritance

Class inheritance lets you create hierarchies where subclasses inherit attributes and references from parent classes. Use eSuperTypes to establish inheritance relationships.

Inheritance promotes reuse and models “is-a” relationships. For example, Employee and Manager are both types of Person, inheriting common properties whilst adding their own specialisations.

Step 1

Create a class hierarchy with inheritance.

Employee and Manager both extend Person through the eSuperTypes attribute. They inherit name and email from Person whilst adding their own attributes (employeeId for Employee, department for Manager).

Company.ecore
1<?xml version="1.0" encoding="UTF-8"?>
2<ecore:EPackage xmi:version="2.0"
3 xmlns:xmi="http://www.omg.org/XMI"
4 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5 xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore"
6 name="company"
7 nsURI="http://www.example.org/company"
8 nsPrefix="company">
9
10 <eClassifiers xsi:type="ecore:EEnum" name="EmploymentStatus">
11 <eLiterals name="FULL_TIME" value="0"/>
12 <eLiterals name="PART_TIME" value="1"/>
13 <eLiterals name="CONTRACTOR" value="2"/>
14 </eClassifiers>
15
16 <eClassifiers xsi:type="ecore:EClass" name="Person">
17 <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
18 <eStructuralFeatures xsi:type="ecore:EAttribute" name="email" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
19 <eStructuralFeatures xsi:type="ecore:EAttribute" name="status" eType="#//EmploymentStatus"/>
20 <eStructuralFeatures xsi:type="ecore:EReference" name="employer" eType="#//Company" eOpposite="#//Company/employees"/>
21 </eClassifiers>
22
23 <eClassifiers xsi:type="ecore:EClass" name="Employee" eSuperTypes="#//Person">
24 <eStructuralFeatures xsi:type="ecore:EAttribute" name="employeeId" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
25 </eClassifiers>
26
27 <eClassifiers xsi:type="ecore:EClass" name="Manager" eSuperTypes="#//Person">
28 <eStructuralFeatures xsi:type="ecore:EAttribute" name="department" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
29 </eClassifiers>
30
31 <eClassifiers xsi:type="ecore:EClass" name="Company">
32 <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
33 <eStructuralFeatures xsi:type="ecore:EReference" name="employees" upperBound="-1" eType="#//Person" containment="true" eOpposite="#//Person/employer"/>
34 </eClassifiers>
35
36</ecore:EPackage>

Step 2

Use the inspect command to view the inheritance structure.

The --show-supertypes flag displays the inheritance relationships, showing which classes extend others and what members they inherit.

Terminal
1swift-ecore inspect Company.ecore --detail full --show-supertypes

Section 3

Abstract Classes

Abstract classes cannot be instantiated directly—they serve as base types that other classes extend. Mark a class as abstract when it represents a concept that only makes sense through its concrete subclasses.

Abstract classes let you define common structure and behaviour whilst ensuring only complete, concrete implementations can be created.

Step 1

Mark Person as abstract since only Employee or Manager instances should exist.

Adding abstract="true" to Person prevents direct instantiation. You can only create Employee or Manager instances, which inherit Person’s structure.

Company.ecore
1<?xml version="1.0" encoding="UTF-8"?>
2<ecore:EPackage xmi:version="2.0"
3 xmlns:xmi="http://www.omg.org/XMI"
4 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5 xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore"
6 name="company"
7 nsURI="http://www.example.org/company"
8 nsPrefix="company">
9
10 <eClassifiers xsi:type="ecore:EEnum" name="EmploymentStatus">
11 <eLiterals name="FULL_TIME" value="0"/>
12 <eLiterals name="PART_TIME" value="1"/>
13 <eLiterals name="CONTRACTOR" value="2"/>
14 </eClassifiers>
15
16 <eClassifiers xsi:type="ecore:EClass" name="Person" abstract="true">
17 <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
18 <eStructuralFeatures xsi:type="ecore:EAttribute" name="email" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
19 <eStructuralFeatures xsi:type="ecore:EAttribute" name="status" eType="#//EmploymentStatus"/>
20 <eStructuralFeatures xsi:type="ecore:EReference" name="employer" eType="#//Company" eOpposite="#//Company/employees"/>
21 </eClassifiers>
22
23 <eClassifiers xsi:type="ecore:EClass" name="Employee" eSuperTypes="#//Person">
24 <eStructuralFeatures xsi:type="ecore:EAttribute" name="employeeId" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
25 </eClassifiers>
26
27 <eClassifiers xsi:type="ecore:EClass" name="Manager" eSuperTypes="#//Person">
28 <eStructuralFeatures xsi:type="ecore:EAttribute" name="department" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
29 </eClassifiers>
30
31 <eClassifiers xsi:type="ecore:EClass" name="Company">
32 <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
33 <eStructuralFeatures xsi:type="ecore:EReference" name="employees" upperBound="-1" eType="#//Person" containment="true" eOpposite="#//Person/employer"/>
34 </eClassifiers>
35
36</ecore:EPackage>

Step 2

Create a model instance using concrete classes.

The XMI contains company:Employee and company:Manager elements, not company:Person. Abstract classes only exist at the metamodel level to define shared structure.

company-model.xmi
1<?xml version="1.0" encoding="UTF-8"?>
2<xmi:XMI xmi:version="2.0"
3 xmlns:xmi="http://www.omg.org/XMI"
4 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5 xmlns:company="http://www.example.org/company">
6
7 <company:Company xmi:id="company1" name="Tech Innovations Ltd">
8 <employees xsi:type="company:Employee" xmi:id="emp1" name="Alice Johnson" email="alice@techinnovations.com" status="FULL_TIME" employeeId="E001"/>
9 <employees xsi:type="company:Employee" xmi:id="emp2" name="Bob Smith" email="bob@techinnovations.com" status="PART_TIME" employeeId="E002"/>
10 <employees xsi:type="company:Manager" xmi:id="mgr1" name="Carol Williams" email="carol@techinnovations.com" status="FULL_TIME" department="Engineering"/>
11 </company:Company>
12
13</xmi:XMI>

Step 3

Validate the metamodel to ensure abstract classes are correctly defined.

The validation confirms that abstract classes have at least one concrete subclass and verifies the inheritance structure is sound.

Terminal
1swift-ecore validate Company.ecore --check-abstract-classes

Check Your Understanding

Question 1 of 4

What is the purpose of an EEnum?

Question 2 of 4

How do you establish inheritance between classes in Ecore?

Question 3 of 4

What does marking a class as abstract mean?

Question 4 of 4

When should you use an EEnum instead of a String attribute?

JSON and XMI Formats

Learn how to convert models between JSON and XMI formats, and validate round-trip conversions.