June 2, 2010

Creating a index of EObjects by their type with EMFPath

On common need you may have when working with EMF, it to build an index of elements by their type. In this post index will be an instance of the Multimap class of Google Collections (basically, it is an abstraction of Map<K, Collection<V>>).

Let's say we have an EMF Resource named eResource.

First, we get the whole contents in an Iterable and we give it to the index() method of the Multimaps class and the EObjects.eClass Function as the indexing function.

Iterable<EObject> descendants = descendant.of(eResource);
Multimap<EClass, EObject> descendantsByEClass = Multimaps.index(descendants, EObjects.eClass);

This is a strict index that does not index elements regarding their EClass supertypes' hierarchy. For instance if have an EClass referenced by a variable named b_EClass, descendantsByEClass.get(b_EClass) will return all elements having b_EClass as their EClass, but it will not return elements having a subclass of b_EClass as their own EClass:

EClass a, b; // b inherits from a
descendantsByEClass
.get(b); // will return elements of type b but not a

To do so, we have to substitute the indexing function EObjects.eClass by a composite one. This composite Function get the EClass of the current EObject and return this EClass and all its supertypes. To put all indexes into the Multimap, we have to change to call of Multimaps.index to Multimaps2.index to create an index of all elements by kind:

Iterable<EObject> descendants = descendant.of(eResource);
Multimap<EClass, EObject> descendantsByKind = Multimaps2.index(descendants, Functions.compose(EClasses.eAllSuperTypesAndSelf, EObjects.eClass));

Now, descendantsByEClass.get() will return elements of type b and its supertypes.

EClass a, b; // b inherits from a
descendantsByEClass
.get(b); // will return elements of type b and a

An equivalent without EMFPath nor Google Collections would be:

TreeIterator<EObject> it = eResource.getAllContents();
Map<EClass, List<EObject>> index = new HashMap<EClass, List<EObject>>();
while(it.hasNext()) {
EObject current = it.next();
EClass eClass = current.eClass();
addValueToMap
(index, eClass, current);
for (EClass supertype : eClass.getEAllSuperTypes()) {
addValueToMap
(index, supertype, current);
}
}

public static void addValueToMap(Map<EClass, List<EObject>> index, EClass k, EObject v) {
List<EObject> values = index.get(k);
if (values == null) {
values
= new ArrayList<EObject>();
index
.put(k, values);
}
values
.add(v);
}

No comment ;)

May 26, 2010

EMFPath is available on Eclipse Labs

The EMFPath project is now available on EclipseLabs.

EMFPath is a Java framework based on Google Collections for browsing / editing EMF models. It has a concise and DSL-like API and has been designed with performance in mind.
There are no binary build yet, the API is still in Beta stage and then subject to change. It also lacks some documentations like a "Quick start", but everything is released so you can use it today.

You are welcome to provide feedback / comments / reviews / contributions ;)

May 15, 2010

Eclipse Labs is now open

Eclipse and Google announced Eclipse Labs. It has been a long awaited initiative from the community. This is an opportunity for anyone creating an Eclipse-based software to be exposed as a part of the Eclipse Ecosystem. The hosting system is based on Google Code project hosting. It is even possible to migrate projects already hosted at Google. All details can be found in the FAQ.

April 19, 2010

What Model Driven (Engineering / Architecture / Development) is not ?

Model Driven (Engineering / Architecture / Development) is not about generating Java class skeletons from an UML class diagram. If you still think like that, I suggest you to read the Ed Merk's slides about the "The Unbearable Stupidity of Modeling". This title is a beautiful self-mockery from the man of modeling at Eclipse but above all, it's a very good listening of different criticisms from the community and gathers a set of objective answers.

Hope this will convinced you that modeling is not just UML to Java...