Friday, 22 March 2013

TreeIterators - Navigate through your EMF model

When working with tree based model instances iterating through of model elements content and contained substructures is a common activity. EcoreUtil provides methods to access all objects directly contained within the specified element or indirectly contained within a subtree of model elements. EObject eAllContent method only returns an elements direct content.

<T> TreeIterator<T> getAllContents(EObject eObject, boolean resolve)
<T> TreeIterator<T> getAllContents(Resource resource, boolean resolve)
<T> TreeIterator<T> getAllContents(ResourceSet resourceSet, boolean resolve)
<T> TreeIterator<T> getAllContents(Collection<?> emfObjects, boolean resolve)


The returned TreeIterator recursivley iterates over all direct and indirect content starting from a specified root element. Since content can be contained within other Resource elements the iterator may be instructed to resolve any proxy elements found. A very similar approach are EcoreUtil’s getAllProperContent methods, which are used to retrieve content which is only contained within the same Resource element.

<T> TreeIterator<T> getAllProperContents(EObject eObject, boolean resolve)
<T> TreeIterator<T> getAllProperContents(Resource resource, boolean resolve)
<T> TreeIterator<T> getAllProperContents(ResourceSet resourceSet, boolean resolve)
<T>TreeIterator<T> getAllProperContents(Collection<?> emfObjects, boolean resolve)


Both options to retrieve content yield a TreeIterator implemented by ContentTreeIterator. ContentTreeIterator iterates through all child elements retrieved by either EObjects econtents feature, a Resource elements getContents method or a ResourceSets getResources implementation. ContentTreeIterator is a nested inner class of EcoreUtil and extends AbstractTreeIterator. These implementation details may be of no further interest to you as long as your satisfied with EMFs iterator implementations (and to my opinion you can go a long way with them). If not, make use of EMF’s base iterator implementations. For example try to extend your implementation from AbstractTreeIterator and provide your own implemenation of getChildren.

When using TreeIterators remind yourself of the iterators prune method which let you skip over all subnodes contained within the last model element retrieved.

No comments:

Post a Comment