blob: f19fa7d095dfabcb613e8c808284703be1e331f8 [file] [log] [blame] [view]
# Example queries on XMI models
These are some sample queries that can be done on any set of indexed XMI-based UML models, assuming that `Class::name` has been added as an indexed attribute and `Class::ownedOperationCount` has been defined as a derived attribute (as showed in [[Basic concepts and usage]]). All the queries are written in the [Epsilon Object Language](http://www.eclipse.org/epsilon/doc/eol/).
In order to index XMI-based UML models, you only need to enable the `UMLMetaModelResourceFactory` and `UMLModelResourceFactory` plugins when you create a new Hawk instance, and ensure your files have the `.uml` extension. If you are using any predefined UML data types, you may also want to add a `PredefinedUMLLibraries` location inside "Indexed Locations": that will integrate those predefined objects into the Hawk graph, allowing you to reference them on queries.
The rest of this article will run on [this toy XMI-based UML file](https://raw.githubusercontent.com/mondo-project/mondo-hawk/gh-pages/examples/models/zoo/zoo.xmi), which was exported from [this Modelio 3.2.1 project](https://github.com/mondo-project/mondo-hawk/raw/gh-pages/examples/models/zoo/Zoo.modelio.zip):
![Example UML model](img/zoo-classes.png)
To avoid ambiguity in type names, the default namespaces list in the query dialog should include the UML metamodel URI (`http://www.eclipse.org/uml2/5.0.0/UML` for the above `UML.ecore` file).
## All instances of a type
return Class.all.size;
Returns the total number of classes within the specified scope. If you leave "Context Files" empty, it'll count all the classes in all the projects. If you put "*OSS.modelio.zip" in "Context Files", it'll count only the classes within the OSS project. This is faster than going through the model because we can go to the Class node and then simply count all the incoming edges with label "ofType".
![Query result](img/query01_all-instances.png)
## Reference slots in a type
return Model.types.select(t|t.name='Class').references;
Gives you all the reference slots in the UML "Class" type. This is an example of the queries that can be performed at the "meta" level: more details are available in [[Meta level queries in Hawk]]. The query dialog with the result would look like this:
![Query result](img/query02_refslots.png)
## Reference traversal
return Class.all
.select(c|c.qualifiedName='zoo::Zebra')
.superClass.flatten.name;
Gives you the names of all the superclasses of class `Zebra` within model `zoo`.
![Query result](img/query03_reftraversal.png)
## Reverse reference traversal
return Class.all
.select(c|c.qualifiedName='zoo::Animal')
.revRefNav_superClass.flatten.name;
Gives the names of all the *sub*classes of `Animal` (follows "superClass" in reverse). The UML metamodel doesn't have "subclass" links, but we can use Hawk's automatic support for reverse traversal of references. In general, if `x.e` is a reference, we can follow it in reverse with `x.revRefNav_e`. We can also access containers using `x.eContainer`.
![Query result](img/query04_reversetraversal.png)
## Range queries with indexed or derived integer attributes
return Class.all.select(c|c.ownedOperationCount > 0).name;
Finds the names of the classes with at least one operation of their own.
![Query result](img/query05_rangequeries.png)
## Advanced example: loops, variables and custom operations
var counts = Sequence {};
var i = 0;
var n = count(0);
while (n > 0) {
counts.add(Sequence {">" + i, n});
i = i + 1;
n = count(i);
}
return counts;
operation count(n) {
return Class.all.select(c|c.ownedOperationCount > n).size;
}
![Query result](img/query06_advanced.png)
This query produces a sequence of `>x, y` pairs which indicate that `y` classes have more than `x` operations of their own.