Metamodel pattern matching example: Ecore Queries


Have you ever tried to query a meta-model, i.e. a model consisting of EClasses, EAttributes, and EReferences, against a meta-model pattern? For an example, look here. In this case, we want to look for a certain sub-configuration in an Ecore metamodel, where two EClasses (each having an EAttribute of type EString) are connected by a 0-* EReference.

Use-cases of this technique include meta-transformation, meta-model analysis, higher-order transformations where transformation rules are generated/parameterized by metamodel analysis etc.

We would like to sincerely thank Christian Schweda for the inspiration for this example.

Obtaining the example

Make sure you run the latest IncQuery tooling and runtime by downloading and installing from the nightly update site.

Check out the source project from GitHub:

Running the example

  1. Import the ecorequery project into your workspace.
  2. There is a file in src/ directory: queries.eiq, right click on this, select EMF-IncQuery queries | Register patterns in Query Explorer.
  3. There is a useful, pre-prepared .ecore file in the models/sample directory: My.ecore. Open it, after that click on Load model in Query Explorer View (if you could not see this view then go to Window->Show View->Other->EMF-IncQuery->Query Explorer) .
  4. You should see the match of the pattern according to the specification found in in Query Explorer view.

Sample pattern

The project contains a pattern named SampleQuery. This pattern looks for matches like the picture at the bottom in Ecore  Models.

In the first section the pattern filters out two EClasses (XElement,YElement) and the XElement contains a reference to YElement.

The find EReferenceWithStarMultiplicity(Relates); helper pattern filters out references only with star multiplicity. 

The find EClassWithEStringAttribute(XElement, Label1); and the find EClassWithEStringAttribute(YElement, Label2); helper pattern filters out EClasses which contains EString.

The neg find IsInECore(XElement); and the neg find IsInECore(YElement); excludes matching to elements located in Ecore.ecore.