EMF does not only provide modeling and code generation facilities, but as well powerful runtime support for manipulating model instances. Runtime support builds upon the reflective nature of EMF models and on generated metadata facilities such as model specific factory (EFactory) and metadata holder (EPackage) implementations. When starting to work with EMF and not knowing about this support, one will treat model instance as any other object structure and use home made patterns to access and manipulate your models.
Within a software project not all team members share the same knowledge and understanding of EMF. Team members concerned with architecture and design might have deeper insight into EMF compared to other developers merrily being “forced” to work with EMF models. To some extend this is fine, designing models and handling the generation process is not a task every team member has to accomplish. However, when programming against EMF models there are a number of use model Even you actively try to limit these differences, at any point of a project team members may come and go. Clearly, new team members
This and later posts shall introduce a minimum set of very useful framework features and starting points client programmers should know about. The following issues are covered:
- Use EcoreUtil as your starting pointNavigate through your model instance
- Identify usage of model elements
- Extend behaviour of model elements
- Testing equality of object structures
- Copy model elements
Use EcoreUtil as a starting point
The class EcoreUtil in the package org.eclipse.emf.common.util is probably the best starting point to learn about EMF’s runtime support for model instances. Just skimming and reading through the implementation code will reveal EMF useful utilities as well as interesting EMF internals to developers. EcoreUtil provides static methods and nested inner classes which exploit the reflective nature of EMF models to generically work with model elements. Let’s assume we want to remove a model element from its contained object structure. Without any EMF insight the straight forward approach would be to retrieve the parent and directly unset the model element or in the case of a multiplicity many features remove the model element from the list of model elements. The following snippet displays EcoreUtil’s implementation of the remove method, which reflectively retrieves the elements container and feature, and removes the element.
/**
* Removes the object from its {@link EObject#eResource containing} resource
* and/or its {@link EObject#eContainer containing} object.
* @param eObject the object to remove.
*/
public static void remove(EObject eObject) {
InternalEObject internalEObject = (InternalEObject)eObject;
EObject container = internalEObject.eInternalContainer();
if (container != null) {
EReference feature = eObject.eContainmentFeature();
if (FeatureMapUtil.isMany(container, feature)) {
((EList<?>)container.eGet(feature)).remove(eObject);
}
else {
container.eUnset(feature);
}
}
Resource resource = internalEObject.eDirectResource();
if (resource != null) {
resource.getContents().remove(eObject);
}
}
No comments:
Post a Comment