Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » Modeling (top-level project) » EMF Derived Attribute Notifier
EMF Derived Attribute Notifier [message #613814] Wed, 07 January 2009 07:28
No real name is currently offline No real name
Messages: 4
Registered: July 2009
Junior Member
If you have a derived attribute in EMF and change one of the attributes
that the derived value depends on, then no notification will be sent for
the derived attribute - so it will not change in any editor etc. You have
to write these yourself.

Here's a class I wrote that I've found useful and perhaps it may be useful
to others (all comments etc. gratefully received). You can specify your
derived attribute, and also which other attributes it depends on.
Listeners are then added as appropriate and when any of your dependant
attributes change, you'll fire an event for your derived attribute.

E.g. You have a Class Library and a set of Books in it. Each Book has a
pageCount attribute. The Library has a derived attribute totalPageCount
that adds up all the pages of all the books. Then you can just write...

* @generated NOT
protected LibraryImpl() {
DerivedAttributeAdapter daa = new DerivedAttributeAdapter(this,

A local dependency is another attribute in the same class. A navigated
dependency is to an attribute in a class that you have an association
with. You can add many local dependencies, but only one remote one (though
it can be a one to many association).

Here it is...


import java.util.ArrayList;
import java.util.List;

import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.impl.AdapterImpl;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.impl.ENotificationImpl;
import org.eclipse.emf.ecore.impl.EObjectImpl;

public class DerivedAttributeAdapter extends AdapterImpl {
private final EObjectImpl source;
private final int derivedFeature;

private List<Integer> localFeatures = new ArrayList<Integer>();

// TODO this lot could be put into a subclass and put in a list to allow
// multiple navigated dependencies
private int dependantFeature = Notification.NO_FEATURE_ID;
private Class<?> dependantClass = null;
private int navigationFeature = Notification.NO_FEATURE_ID;

private AdapterImpl dependantAdapter = new AdapterImpl() {

public void notifyChanged(Notification msg) {

if (msg.getFeatureID(dependantClass) == dependantFeature &&
msg.getEventType() == Notification.SET) {

* Convenience constructor for a local and navigated dependency
public DerivedAttributeAdapter(EObjectImpl source, int derivedFeature,
int navigationFeature, int dependantFeature, int localFeature) {
this(source, derivedFeature);
addNavigatedDependency(navigationFeature, dependantFeature);

* Convenience constructor for a navigated dependency
public DerivedAttributeAdapter(EObjectImpl source, int derivedFeature,
int navigationFeature, int dependantFeature) {
this(source, derivedFeature);
addNavigatedDependency(navigationFeature, dependantFeature);

* Convenience constructor for a local dependency
public DerivedAttributeAdapter(EObjectImpl source, int derivedFeature,
int localFeature) {
this(source, derivedFeature);

public DerivedAttributeAdapter(EObjectImpl source, int derivedFeature) {
this.source = source;
this.derivedFeature = derivedFeature;

public void addNavigatedDependency(int navigationFeature, int
dependantFeature) {
this.dependantFeature = dependantFeature;
this.navigationFeature = navigationFeature;
this.dependantClass =
source.eClass().getEStructuralFeature(navigationFeature).get EType().getInstanceClass();

public void addLocalDependency(int localFeature) {

public void notifyChanged(Notification notification) {
if (notification.getFeatureID(source.getClass()) == navigationFeature) {
switch (notification.getEventType()) {
case Notification.ADD:
EObject added = (EObject) notification.getNewValue();
case Notification.SET:
EObject newValue = (EObject) notification.getNewValue();
EObject oldValue = (EObject) notification.getOldValue();
if (oldValue != null) oldValue.eAdapters().remove(dependantAdapter);
if (newValue != null) newValue.eAdapters().add(dependantAdapter);
case Notification.REMOVE:
EObject removed = (EObject) notification.getOldValue();
return; // No notification
} else if
(localFeatures.contains(notification.getFeatureID(source.get Class()))) {
if (notification.getEventType() == Notification.SET) {

private void notifyDerivedAttributeChange() {
if (source.eNotificationRequired()) {
source.eNotify(new ENotificationImpl(source, Notification.SET,
derivedFeature, null, source.eGet(
derivedFeature, true, true)));

Previous Topic:New version (Rhea) of the OpenEmbeDD MDE platform
Next Topic:help with existing meta data repository mapping
Goto Forum:

Current Time: Wed Jul 23 14:17:43 EDT 2014

Powered by FUDForum. Page generated in 0.01530 seconds