Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » EMF » [CDO] CDO/GMF compatibility
[CDO] CDO/GMF compatibility [message #1006420] Thu, 31 January 2013 10:26 Go to next message
Eclipse UserFriend
Hi Eike,

A few months ago, I have asked a question about a GMF notation metamodel
customization http://www.eclipse.org/forums/index.php/t/358618/ .

To summarize, this customization concerns the ViewImpl.getElement()
whose behavior is to return the element of the parent View if its
element field is null :

/**
* <!-- begin-user-doc --> <!-- end-user-doc -->
*
* @generated NOT
*/
public EObject getElement() {
if (!isSetElement()) {
EObject container = eContainer();
if (container instanceof View) {
View view = (View) container;
element = view.getElement();
}
}
if (element != null && element.eIsProxy()) {
EObject oldElement = element;
element = eResolveProxy((InternalEObject) element);
if (element != oldElement) {
if (eNotificationRequired())
eNotify(new ENotificationImpl(this, Notification.RESOLVE,
NotationPackage.VIEW__ELEMENT, oldElement, element));
}
}
return element;
}


And this customization can cause issue with CDO in legacy (also in
native), indeed when attaching a ViewImpl object to a CDOTransaction,
CDO creates a CDORevision with current values of this object by calling
object.eGet(feature). And in the case of a ViewImpl whose element field
is null, a call to object.eGet(elementFeature) will return the element
value of a parent View, because of call to ViewImpl.getElement() and the
ViewImpl.isSetElement() method return true. Which can be problematic on
undo, for which CDO will reaffect values of CDORevision to ViewImpl.

A possible work-around in legacy for our use case is to change
ViewImpl.eGet() to not call ViewImpl.getElement() directly but call the
following release :

public EObject getGenElement() {
if (element != null && element.eIsProxy()) {
EObject oldElement = element;
if (!isSetElement()) {
oldElement = null;
}
element = eResolveProxy((InternalEObject) element);
if (element != oldElement) {
if (eNotificationRequired())
eNotify(new ENotificationImpl(this, Notification.RESOLVE,
NotationPackage.VIEW__ELEMENT, oldElement, element));
}
}
return element;
}

Like that the CDORevision created have correct values and changes can be
undo without issues. Someone have tried the GMF/CDO integration have
already encountered this issue and what do you think about my work-around?

Best Regards.
Re: [CDO] CDO/GMF compatibility [message #1006500 is a reply to message #1006420] Thu, 31 January 2013 14:03 Go to previous message
Christian W. Damus is currently offline Christian W. DamusFriend
Messages: 847
Registered: July 2009
Senior Member
Hi, Esteban,

Yes, I can well understand this this would create problems. The issue
is that GMF assigns the 'element' field. It's OK to derive a default
for an unset reference, but then it shouldn't be set by the derivation.
Or, the reference could be generated as "unsettable", which is a state
independent of the field. But, even so, one wouldn't want to set the
field because the container view might change, and then the cached
derived value would be wrong.

This is a bug in GMF, and not just because it bothers CDO. So, barring
a fix in GMF, you do need to work around it in your custom notation
model implementation.

If GMF were updated (or if your implementation overrides
View::getElement() method) thus:

/**
* <!-- begin-user-doc --> <!-- end-user-doc -->
*
* @generated NOT
*/
public EObject getElement() {
EObject result = basicGetElement();

if (!isSetElement()) {
EObject container = eContainer();
if (container instanceof View) {
View view = (View) container;
result = view.getElement();
}
}

return result;
}

(although I would actually suggest renaming the generated method to
getElementGen and wrapping it)

Then, I would think that GMF behaves as it needs to and CDO also. CDO
wouldn't need an override of eGet(). It seems to me that the attempt
to resolve a proxy is redundant because calling getElement() on the
parent view would already return the resolved object. Because this
object is a computed default value, the notification isn't needed
because no different value could have previously been observed, so no
listener can care that it was a proxy.

Does that make sense?

HTH,

Christian


On 2013-01-31 10:26:13 +0000, Esteban DUGUEPEROUX said:

> Hi Eike,
>
> A few months ago, I have asked a question about a GMF notation
> metamodel customization
> http://www.eclipse.org/forums/index.php/t/358618/ .
>
> To summarize, this customization concerns the ViewImpl.getElement()
> whose behavior is to return the element of the parent View if its
> element field is null :
>
> /**
> * <!-- begin-user-doc --> <!-- end-user-doc -->
> *
> * @generated NOT
> */
> public EObject getElement() {
> if (!isSetElement()) {
> EObject container = eContainer();
> if (container instanceof View) {
> View view = (View) container;
> element = view.getElement();
> }
> }
> if (element != null && element.eIsProxy()) {
> EObject oldElement = element;
> element = eResolveProxy((InternalEObject) element);
> if (element != oldElement) {
> if (eNotificationRequired())
> eNotify(new ENotificationImpl(this, Notification.RESOLVE,
> NotationPackage.VIEW__ELEMENT, oldElement, element));
> }
> }
> return element;
> }
>
>
> And this customization can cause issue with CDO in legacy (also in
> native), indeed when attaching a ViewImpl object to a CDOTransaction,
> CDO creates a CDORevision with current values of this object by calling
> object.eGet(feature). And in the case of a ViewImpl whose element field
> is null, a call to object.eGet(elementFeature) will return the element
> value of a parent View, because of call to ViewImpl.getElement() and
> the ViewImpl.isSetElement() method return true. Which can be
> problematic on undo, for which CDO will reaffect values of CDORevision
> to ViewImpl.
>
> A possible work-around in legacy for our use case is to change
> ViewImpl.eGet() to not call ViewImpl.getElement() directly but call the
> following release :
>
> public EObject getGenElement() {
> if (element != null && element.eIsProxy()) {
> EObject oldElement = element;
> if (!isSetElement()) {
> oldElement = null;
> }
> element = eResolveProxy((InternalEObject) element);
> if (element != oldElement) {
> if (eNotificationRequired())
> eNotify(new ENotificationImpl(this, Notification.RESOLVE,
> NotationPackage.VIEW__ELEMENT, oldElement, element));
> }
> }
> return element;
> }
>
> Like that the CDORevision created have correct values and changes can
> be undo without issues. Someone have tried the GMF/CDO integration have
> already encountered this issue and what do you think about my
> work-around?
>
> Best Regards.
Previous Topic:[CDO] Dealing with extended meta model
Next Topic:JMerge error when merging annotations on EnumLiteral
Goto Forum:
  


Current Time: Mon Dec 22 14:57:58 GMT 2014

Powered by FUDForum. Page generated in 0.01641 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software