Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » EMF » [CDO] Detecting whether a legacy object is being populated from revision data
[CDO] Detecting whether a legacy object is being populated from revision data [message #963174] Mon, 29 October 2012 16:13 Go to next message
Christian W. Damus is currently offline Christian W. Damus
Messages: 802
Registered: July 2009
Senior Member
Hi!


The Background
------------------------------------------------------------

The Eclipse UML2 project provides an implementation of UML's
subset/superset property constraints. These constraints automatically
update a superset property when something is added to a subset and
update a subset property when something is removed from the superset.
Cool stuff.

This facility is used by UML2's implementation of the UML metamodel,
itself, but can also be used by any other code generated from a UML
model.

A crucial point is that these constraints are *not* enforced while an
object is being constructed by loading from persistent storage, because
the persistent state must be applied *as is* to each object being
loaded. The UML2 run-time heretofore has detected this condition by
querying whether the resource containing the object is in the process
of loading (Resource.Internal::isLoading method).

This doesn't apply to CDO, in which objects don't have to be in
resources but can still be loaded from persistent storage. So, in the
absence of any changes, the CDOLegacyWrapper causes subset/superset
constraints to fire when loading legacy UML or other objects from
revision data.

I have hacked together changes in UML2 that would allow me to
substitute a CDO-aware strategy for determining whether an object is
being loaded, but now I need to reliably determine whether a legacy
object is in the process of being populated from its revision data.


The Question
------------------------------------------------------------

Does CDO provide an API that I can use to detect that a legacy object
is being populated from its revision data? Or should I look into
contributing something new?


Thanks,

Christian
Re: [CDO] Detecting whether a legacy object is being populated from revision data [message #963200 is a reply to message #963174] Mon, 29 October 2012 16:34 Go to previous messageGo to next message
Eike Stepper is currently offline Eike Stepper
Messages: 5540
Registered: July 2009
Senior Member
Am 29.10.2012 17:13, schrieb Christian W. Damus:
> Hi!
>
>
> The Background
> ------------------------------------------------------------
>
> The Eclipse UML2 project provides an implementation of UML's subset/superset property constraints. These constraints
> automatically update a superset property when something is added to a subset and update a subset property when
> something is removed from the superset. Cool stuff.
Not sure :P

When I read your eplanatory comments on the https://bugs.eclipse.org/392956 I already thought "why don't they just
persist the smaller subsets and derive the bigger ones transiently, similar to feature maps?"

> This facility is used by UML2's implementation of the UML metamodel, itself, but can also be used by any other code
> generated from a UML model.
>
> A crucial point is that these constraints are *not* enforced while an object is being constructed by loading from
> persistent storage, because the persistent state must be applied *as is* to each object being loaded. The UML2
> run-time heretofore has detected this condition by querying whether the resource containing the object is in the
> process of loading (Resource.Internal::isLoading method).
>
> This doesn't apply to CDO, in which objects don't have to be in resources but can still be loaded from persistent
> storage.
Just to be exact, logically CDOObjects (whether native or not) have to be contained by resoures. The resources just
don't have to be loaded physically all the time.

> So, in the absence of any changes, the CDOLegacyWrapper causes subset/superset constraints to fire when loading legacy
> UML or other objects from revision data.
What do you mean by "fire"?

Is it a matter of turning off and on again the eDeliver property in the new persistence filtering mechansim?

> I have hacked together changes in UML2 that would allow me to substitute a CDO-aware strategy for determining whether
> an object is being loaded,
By "being loaded" you mean CDOLegacyWrapper.revisionToInstance() being active?

> but now I need to reliably determine whether a legacy object is in the process of being populated from its revision data.
Maybe we can expose CDOLegacyWrapper.underConstruction semi-publicly (although we always strived for not exposing the
native/legacy distinction anywhere). Wanna play with it first?

> The Question
> ------------------------------------------------------------
>
> Does CDO provide an API that I can use to detect that a legacy object is being populated from its revision data?
Not yet, see above.

> Or should I look into contributing something new?
That would be a precondition for making it happen :P

Cheers
/Eike

----
http://www.esc-net.de
http://thegordian.blogspot.com
http://twitter.com/eikestepper
Re: [CDO] Detecting whether a legacy object is being populated from revision data [message #963269 is a reply to message #963200] Mon, 29 October 2012 17:41 Go to previous messageGo to next message
Christian W. Damus is currently offline Christian W. Damus
Messages: 802
Registered: July 2009
Senior Member
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta http-equiv="Content-Style-Type" content="text/css">
<title></title>
<meta name="Generator" content="Cocoa HTML Writer">
<meta name="CocoaVersion" content="1187.34">
<style type="text/css">
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; line-height: 15.0px; font: 12.0px Helvetica}
p.p2 {margin: 0.0px 0.0px 0.0px 0.0px; line-height: 15.0px; font: 12.0px Helvetica; min-height: 14.0px}
p.p3 {margin: 0.0px 0.0px 0.0px 12.0px; line-height: 14.0px; font: 12.0px Helvetica; color: #011892}
p.p4 {margin: 0.0px 0.0px 0.0px 24.0px; font: 12.0px Helvetica; color: #008e00}
p.p5 {margin: 0.0px 0.0px 0.0px 24.0px; font: 12.0px Helvetica; color: #008e00; min-height: 14.0px}
p.p6 {margin: 0.0px 0.0px 0.0px 12.0px; font: 12.0px Helvetica; color: #011892}
p.p7 {margin: 0.0px 0.0px 0.0px 12.0px; font: 12.0px Helvetica; color: #011892; min-height: 14.0px}
p.p8 {margin: 0.0px 0.0px 0.0px 0.0px; line-height: 14.0px; font: 12.0px Helvetica; min-height: 14.0px}
p.p9 {margin: 0.0px 0.0px 0.0px 0.0px; line-height: 14.0px; font: 12.0px Helvetica}
p.p10 {margin: 0.0px 0.0px 0.0px 0.0px; line-height: 14.0px; font: 12.0px Helvetica; color: #011892; min-height: 14.0px}
p.p11 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica; color: #000000; min-height: 14.0px}
</style>
</head>
<body>
<p class="p1">Hi, Eike,</p>
<p class="p2"><br></p>
<p class="p1">Thanks for the response.<span class="Apple-converted-space">  </span>See some replies in-line, below.</p>
<p class="p2"><br></p>
<p class="p1">cW</p>
<p class="p2"><br></p>
<p class="p2"><br></p>
<p class="p1">On 2012-10-29 16:34:11 +0000, Eike Stepper said:</p>
<p class="p2"><br></p>
<p class="p3">Am 29.10.2012 17:13, schrieb Christian W. Damus:</p>
<p class="p4">Hi!</p>
<p class="p5"><br></p>
<p class="p5"><br></p>
<p class="p4">The Background</p>
<p class="p4">------------------------------------------------------------</p>
<p class="p5"><br></p>
<p class="p4">The Eclipse UML2 project provides an implementation of UML's subset/superset property constraints.<span class="Apple-converted-space">  </span>These constraints automatically update a superset property when something is added to a subset and update a subset property when something is removed from the superset.<span class="Apple-converted-space">  </span>Cool stuff.</p>
<p class="p6">Not sure :P</p>
<p class="p7"><br></p>
<p class="p6">When I read your eplanatory comments on the https://bugs.eclipse.org/392956 I already thought "why don't they just persist the smaller subsets and derive the bigger ones transiently, similar to feature maps?"</p>
<p class="p8"><br></p>
<p class="p9">Because the UML specification has to do things in its own inscrutable way and it's Eclipse UML2's job to implement it.<span class="Apple-converted-space">  </span>Ours is not to question why.<span class="Apple-converted-space">  </span>:-D</p>
<p class="p8"><br></p>
<p class="p9">Actually, a lot of superset features in UML work exactly like that:<span class="Apple-converted-space">  </span>they are "derived unions" that are transient and computed dynamically from their subsets.<span class="Apple-converted-space">  </span>Other superset features are mutable (because they have elements that aren't in any subset) but are persistent.<span class="Apple-converted-space">  </span>There are only those two features that are some crazy other thing.</p>
<p class="p8"><br></p>
<p class="p10"><br></p>
<p class="p4">This facility is used by UML2's implementation of the UML metamodel, itself, but can also be used by any other code generated from a UML model.</p>
<p class="p5"><br></p>
<p class="p4">A crucial point is that these constraints are *not* enforced while an object is being constructed by loading from persistent storage, because the persistent state must be applied *as is* to each object being loaded.<span class="Apple-converted-space">  </span>The UML2 run-time heretofore has detected this condition by querying whether the resource containing the object is in the process of loading (Resource.Internal::isLoading method).</p>
<p class="p5"><br></p>
<p class="p4">This doesn't apply to CDO, in which objects don't have to be in resources but can still be loaded from persistent storage.<span class="Apple-converted-space"> </span></p>
<p class="p6">Just to be exact, logically CDOObjects (whether native or not) have to be contained by resoures. The resources just don't have to be loaded physically all the time.</p>
<p class="p8"><br></p>
<p class="p9">Ah, this is good to know.<span class="Apple-converted-space">  </span>Perhaps, then, the problem can be simplified.<span class="Apple-converted-space">  </span>Let me make a few new observations and ask some new questions:</p>
<p class="p8"><br></p>
<p class="p9">(1) I assume that any implementation of an "is loading" state for native objects would<span class="Apple-converted-space"> </span></p>
<p class="p9"><span class="Apple-converted-space">     </span>be quite different than for legacy objects, because they delegate their state to a</p>
<p class="p9"><span class="Apple-converted-space">     </span>highly dynamic store in the view.<span class="Apple-converted-space">  </span>Loading is an incremental process and, for some</p>
<p class="p9"><span class="Apple-converted-space">     </span>objects, probably never finishes.<span class="Apple-converted-space">  </span>I'm not sure that "is loading" makes sense for</p>
<p class="p9"><span class="Apple-converted-space">     </span>native objects.<span class="Apple-converted-space">  </span>In a way, native objects are potentially always partially loaded and</p>
<p class="p9"><span class="Apple-converted-space">     </span>so are always in "is loading" state</p>
<p class="p8"><br></p>
<p class="p9">(2) A CDO-native implementation of subset/superset lists would rely on the internal</p>
<p class="p9"><span class="Apple-converted-space">     </span>details of lazy collection storage etc. and would be a much more complex problem</p>
<p class="p9"><span class="Apple-converted-space">     </span>than handling the legacy implementation.<span class="Apple-converted-space">  </span>There is no question (currently) of</p>
<p class="p9"><span class="Apple-converted-space">     </span>attempting to implement CDO-native subset/superset lists.</p>
<p class="p8"><br></p>
<p class="p9">(3) The reason why I have this problem with UML's subsets and supersets is because</p>
<p class="p9"><span class="Apple-converted-space">      </span>legacy objects are loaded and populated *before* they are attached to the resource.</p>
<p class="p9"><span class="Apple-converted-space">      </span>The norm in XML resources is to attach an object first to the resource (or its container)</p>
<p class="p9"><span class="Apple-converted-space">      </span>and then populate it.</p>
<p class="p8"><br></p>
<p class="p9">So, I might not have any issue at all if legacy objects were first attached to their resource (or container, recursively) before being populated from their revision data.<span class="Apple-converted-space">  </span>But, is that realistic?<span class="Apple-converted-space">  </span>What would break if CDOResources suddenly started behaving in this other way?</p>
<p class="p8"><br></p>
<p class="p8"><br></p>
<p class="p4">So, in the absence of any changes, the CDOLegacyWrapper causes subset/superset constraints to fire when loading legacy UML or other objects from revision data.</p>
<p class="p6">What do you mean by "fire"?</p>
<p class="p8"><br></p>
<p class="p9">The EList implementation that stores a subset or superset feature automatically updates all of its related superset and subset features when objects are added to it or removed from it.<span class="Apple-converted-space">  </span>This doesn't rely on notifications or anything else in the EMF run-time; it's an internal hand-shaking protocol.</p>
<p class="p8"><br></p>
<p class="p8"><br></p>
<p class="p6">Is it a matter of turning off and on again the eDeliver property in the new persistence filtering<span class="Apple-converted-space"> </span></p>
<p class="p6">mechansim?</p>
<p class="p8"><br></p>
<p class="p9">No, it's not based on notifications and anyways, it's orthogonal to the whole problem of partial or conditional persistence.<span class="Apple-converted-space">  </span>This problem is inherent to all superset/subset features, not just the crazy special cases that UML 2.4.1 gave us.</p>
<p class="p8"><br></p>
<p class="p10"><br></p>
<p class="p4">I have hacked together changes in UML2 that would allow me to substitute a CDO-aware strategy for determining whether an object is being loaded,<span class="Apple-converted-space"> </span></p>
<p class="p6">By "being loaded" you mean CDOLegacyWrapper.revisionToInstance() being active?</p>
<p class="p8"><br></p>
<p class="p9">Basically, yes.<span class="Apple-converted-space">  </span>Populating the instance from its revision data modifies the subset/superset ELists, which triggers the internal updates that I need to suppress.</p>
<p class="p8"><br></p>
<p class="p10"><br></p>
<p class="p4">but now I need to reliably determine whether a legacy object is in the process of being populated from its revision data.</p>
<p class="p6">Maybe we can expose CDOLegacyWrapper.underConstruction semi-publicly (although we always strived for not exposing the native/legacy distinction anywhere). Wanna play with it first?</p>
<p class="p8"><br></p>
<p class="p9">I am totally happy to play with it.<span class="Apple-converted-space">  </span>I have already observed the underConstruction flag, and thought a nice diamond-shaped yellow icon with the silhouette of a man stepping on a spade would suit it well.</p>
<p class="p8"><br></p>
<p class="p9">The question is which kind of API is better?</p>
<p class="p8"><br></p>
<p class="p9"><span class="Apple-converted-space">  </span>- a new ephemeral CDOState enumeration literal (e.g., "LOADING")</p>
<p class="p9"><span class="Apple-converted-space">  </span>- a new InternalCDOObject.isLoading() query method</p>
<p class="p9"><span class="Apple-converted-space">  </span>- a new CDOUtil.isLegacyObjectLoading(EObject) utility method</p>
<p class="p8"><br></p>
<p class="p9">As I said above, I'm not even sure that an "is loading" state makes sense for native objects, so that would rule out the first two API options.</p>
<p class="p8"><br></p>
<p class="p8"><br></p>
<p class="p4">The Question</p>
<p class="p4">------------------------------------------------------------</p>
<p class="p5"><br></p>
<p class="p4">Does CDO provide an API that I can use to detect that a legacy object is being populated from its revision data?<span class="Apple-converted-space"> </span></p>
<p class="p6">Not yet, see above.</p>
<p class="p7"><br></p>
<p class="p4">Or should I look into contributing something new?</p>
<p class="p6">That would be a precondition for making it happen :P</p>
<p class="p8"><br></p>
<p class="p9">Heh heh ... I'm trying my best to be self-sufficient.<span class="Apple-converted-space">  </span>:-)<span class="Apple-converted-space">  </span>I also want to make sure that I only contribute useful stuff that CDO finds palatable, which is why I need some guidance.<span class="Apple-converted-space">  </span>I very much appreciate your help with that, so far.</p>
<p class="p8"><br></p>
<p class="p8"><br></p>
<p class="p7"><br></p>
<p class="p6">Cheers</p>
<p class="p6">/Eike</p>
<p class="p7"><br></p>
<p class="p6">----</p>
<p class="p6">http://www.esc-net.de</p>
<p class="p6">http://thegordian.blogspot.com</p>
<p class="p6">http://twitter.com/eikestepper</p>
<p class="p11"><br></p>
</body>
</html>
Re: [CDO] Detecting whether a legacy object is being populated from revision data [message #963315 is a reply to message #963269] Mon, 29 October 2012 18:26 Go to previous messageGo to next message
Christian W. Damus is currently offline Christian W. Damus
Messages: 802
Registered: July 2009
Senior Member
Well, a very simple solution works perfectly for me.

Attached is a Git e-mail patch that adds a "cdoInternalIsPopulating()"
method to the CDOObjectWrapperBase. The CDOLegacyWrapper implements
this in terms of the "underConstruction" flag. The public API is
CDOUtil::isLoading(EObject), which looks for a wrapper and asks it.

I don't think concurency handling is of concern, because the only
object that can plausibly know about a wrapper before it has finished
populating (excepting the CDO infrastructure, of course) is the object,
itself. So, this method is only intended to be used by (and only
really useful to) the internal implementation of an object. That is
exactly the case in my UML scenario.

If this looks anything like something that the CDO project would except
as a contribution, I can raise an enhancement request and start
iterating the patch, there.

Thanks!

Christian
Re: [CDO] Detecting whether a legacy object is being populated from revision data [message #963331 is a reply to message #963269] Mon, 29 October 2012 18:38 Go to previous messageGo to next message
Eike Stepper is currently offline Eike Stepper
Messages: 5540
Registered: July 2009
Senior Member
Am 29.10.2012 18:41, schrieb Christian W. Damus:
>
> Hi, Eike,
>
>
> Thanks for the response.See some replies in-line, below.
>
>
> cW
>
>
>
> On 2012-10-29 16:34:11 +0000, Eike Stepper said:
>
>
> Am 29.10.2012 17:13, schrieb Christian W. Damus:
>
> Hi!
>
>
>
> The Background
>
> ------------------------------------------------------------
>
>
> The Eclipse UML2 project provides an implementation of UML's subset/superset property constraints.These constraints
> automatically update a superset property when something is added to a subset and update a subset property when
> something is removed from the superset.Cool stuff.
>
> Not sure :P
>
>
> When I read your eplanatory comments on the https://bugs.eclipse.org/392956 I already thought "why don't they just
> persist the smaller subsets and derive the bigger ones transiently, similar to feature maps?"
>
>
> Because the UML specification has to do things in its own inscrutable way and it's Eclipse UML2's job to implement
> it.Ours is not to question why.:-D
>
I get your point ;-)

>
> Actually, a lot of superset features in UML work exactly like that:they are "derived unions" that are transient and
> computed dynamically from their subsets.Other superset features are mutable (because they have elements that aren't in
> any subset) but are persistent.There are only those two features that are some crazy other thing.
>
It's always the minority causing the biggest trouble ;-)

>
> This facility is used by UML2's implementation of the UML metamodel, itself, but can also be used by any other code
> generated from a UML model.
>
>
> A crucial point is that these constraints are *not* enforced while an object is being constructed by loading from
> persistent storage, because the persistent state must be applied *as is* to each object being loaded.The UML2 run-time
> heretofore has detected this condition by querying whether the resource containing the object is in the process of
> loading (Resource.Internal::isLoading method).
>
>
> This doesn't apply to CDO, in which objects don't have to be in resources but can still be loaded from persistent storage.
>
> Just to be exact, logically CDOObjects (whether native or not) have to be contained by resoures. The resources just
> don't have to be loaded physically all the time.
>
>
> Ah, this is good to know.Perhaps, then, the problem can be simplified.Let me make a few new observations and ask some
> new questions:
>
Sure...

> (1) I assume that any implementation of an "is loading" state for native objects would
>
> be quite different than for legacy objects, because they delegate their state to a
>
> highly dynamic store in the view.Loading is an incremental process and, for some
>
> objects, probably never finishes.I'm not sure that "is loading" makes sense for
>
> native objects.In a way, native objects are potentially always partially loaded and
>
> so are always in "is loading" state
>
Hmm, they all go through CDOStateMachine.LoadTransition.execute().

> (2) A CDO-native implementation of subset/superset lists would rely on the internal
>
> details of lazy collection storage etc. and would be a much more complex problem
>
> than handling the legacy implementation.There is no question (currently) of
>
> attempting to implement CDO-native subset/superset lists.
>
I'd just wish we wouldn't need (compatible) changes on the general API (such as CDOClassInfo) if it's not a generally
useful thing. I'd rather do these things internally then and add an x-friend org.eclipse.uml2 or so. Still thinking...

> (3) The reason why I have this problem with UML's subsets and supersets is because
>
> legacy objects are loaded and populated *before* they are attached to the resource.
>
Martin used to be the legacy expert. Where exactly does this happen?

> The norm in XML resources is to attach an object first to the resource (or its container)
>
> and then populate it.
>
>
> So, I might not have any issue at all if legacy objects were first attached to their resource (or container,
> recursively) before being populated from their revision data.But, is that realistic?What would break if CDOResources
> suddenly started behaving in this other way?
>
Hard to say. I remember the legacy mechanism being quite complex, but I didn't develop it.

>
>
> So, in the absence of any changes, the CDOLegacyWrapper causes subset/superset constraints
>
You mean the newly proposed "persistence filters"?

> to fire when loading legacy UML or other objects from revision data.
>
> What do you mean by "fire"?
>
>
> The EList implementation that stores a subset or superset feature automatically updates all of its related superset
> and subset features when objects are added to it or removed from it.This doesn't rely on notifications or anything
> else in the EMF run-time; it's an internal hand-shaking protocol.
>
Between what exact entities?

>
>
> Is it a matter of turning off and on again the eDeliver property in the new persistence filtering
>
> mechansim?
>
>
> No, it's not based on notifications and anyways, it's orthogonal to the whole problem of partial or conditional
> persistence.This problem is inherent to all superset/subset features, not just the crazy special cases that UML 2.4.1
> gave us.
>
I wonder if it would be a good idea that you try to demo the whole beast to me via TeamViewer :P

>
>
> I have hacked together changes in UML2 that would allow me to substitute a CDO-aware strategy for determining whether
> an object is being loaded,
>
> By "being loaded" you mean CDOLegacyWrapper.revisionToInstance() being active?
>
>
> Basically, yes.Populating the instance from its revision data modifies the subset/superset ELists, which triggers the
> internal updates that I need to suppress.
>
Theoretically we could add an SPI interface:

public interface InternalCDOLegacyWrapper extends InternalCDOObject
{
public boolean isUnderConstruction();
}

Would that help?

> but now I need to reliably determine whether a legacy object is in the process of being populated from its revision data.
>
> Maybe we can expose CDOLegacyWrapper.underConstruction semi-publicly (although we always strived for not exposing the
> native/legacy distinction anywhere). Wanna play with it first?
>
>
> I am totally happy to play with it.I have already observed the underConstruction flag, and thought a nice
> diamond-shaped yellow icon with the silhouette of a man stepping on a spade would suit it well.
>
Must be too late here, but I don't get it :P

Do you mean "make it protected"? I think that wouldn't help you. The SPI interface above probably would, With it you
could downcast the return value of CDOUtil.getCDOObject(EObject).

> The question is which kind of API is better?
>
>
> - a new ephemeral CDOState enumeration literal (e.g., "LOADING")
>
Definitely not without parity among native and legacy objects.

> - a new InternalCDOObject.isLoading() query method
>
I have the impression it's not so much the "loading" of arbitrary CDOObjects but the "under construction" of
CDOLegacyWrappers.

> - a new CDOUtil.isLegacyObjectLoading(EObject) utility method
>
I'd prefer to keep this in the SPI space, see above.

>
> As I said above, I'm not even sure that an "is loading" state makes sense for native objects, so that would rule out
> the first two API options.
>
;-)

>
>
> The Question
>
> ------------------------------------------------------------
>
>
> Does CDO provide an API that I can use to detect that a legacy object is being populated from its revision data?
>
> Not yet, see above.
>
>
> Or should I look into contributing something new?
>
> That would be a precondition for making it happen :P
>
>
> Heh heh ... I'm trying my best to be self-sufficient.:-)I also want to make sure that I only contribute useful stuff
> that CDO finds palatable, which is why I need some guidance.I very much appreciate your help with that, so far.
>
Yes, your cooperation is always very fruitful ;-)

Cheers
/Eike

----
http://www.esc-net.de
http://thegordian.blogspot.com
http://twitter.com/eikestepper
Re: [CDO] Detecting whether a legacy object is being populated from revision data [message #963336 is a reply to message #963315] Mon, 29 October 2012 18:42 Go to previous messageGo to next message
Eike Stepper is currently offline Eike Stepper
Messages: 5540
Registered: July 2009
Senior Member
Am 29.10.2012 19:26, schrieb Christian W. Damus:
> Well, a very simple solution works perfectly for me.
>
> Attached is a Git e-mail patch that adds a "cdoInternalIsPopulating()" method to the CDOObjectWrapperBase. The
> CDOLegacyWrapper implements this in terms of the "underConstruction" flag. The public API is
> CDOUtil::isLoading(EObject), which looks for a wrapper and asks it.
>
> I don't think concurency handling is of concern, because the only object that can plausibly know about a wrapper
> before it has finished populating (excepting the CDO infrastructure, of course) is the object, itself. So, this
> method is only intended to be used by (and only really useful to) the internal implementation of an object. That is
> exactly the case in my UML scenario.
>
> If this looks anything like something that the CDO project would except as a contribution, I can raise an enhancement
> request and start iterating the patch, there.
I prefer the InternalCDOLegacyWrapper interface that I proposed in my other reply.

And I wonder if we should hide the entire persistence filtering mechanism from the public API until it becomes valid for
native objects, too...

Cheers
/Eike

----
http://www.esc-net.de
http://thegordian.blogspot.com
http://twitter.com/eikestepper
Re: [CDO] Detecting whether a legacy object is being populated from revision data [message #963397 is a reply to message #963331] Mon, 29 October 2012 19:50 Go to previous messageGo to next message
Christian W. Damus is currently offline Christian W. Damus
Messages: 802
Registered: July 2009
Senior Member
On 2012-10-29 18:38:18 +0000, Eike Stepper said:

-------- 8< --------

>> Ah, this is good to know.Perhaps, then, the problem can be
>> simplified.Let me make a few new observations and ask some new
>> questions:
>>
> Sure...
>
>> (1) I assume that any implementation of an "is loading" state for
>> native objects would
>>
>> be quite different than for legacy objects, because they delegate their
>> state to a
>>
>> highly dynamic store in the view.Loading is an incremental process and,
>> for some
>>
>> objects, probably never finishes.I'm not sure that "is loading" makes sense for
>>
>> native objects.In a way, native objects are potentially always
>> partially loaded and
>>
>> so are always in "is loading" state
>>
> Hmm, they all go through CDOStateMachine.LoadTransition.execute().

The state machine is something that I have yet to explore. But the
basic point is that there are times when a feature setting is being
initialized, so changes made to it are for the purpose of "loading" the
setting, and there are other times when the feature setting is stable
and is exposed to the application and changes made to it are for the
purpose of "editing" it.

Subset/superset constraints need to be enabled only for "editing"
changes made by an application, not for "loading" changes that
initialize an object's settings from persistent storage.

>> (2) A CDO-native implementation of subset/superset lists would rely on
>> the internal
>>
>> details of lazy collection storage etc. and would be a much more
>> complex problem
>>
>> than handling the legacy implementation.There is no question (currently) of
>>
>> attempting to implement CDO-native subset/superset lists.
>>
> I'd just wish we wouldn't need (compatible) changes on the general API
> (such as CDOClassInfo) if it's not a generally useful thing. I'd rather
> do these things internally then and add an x-friend org.eclipse.uml2 or
> so. Still thinking...

I think we're talking about two different things, now. EMF provides
InternalResource::isLoading() specifically to support the kind of
object initialization problem that this thread is about. UML2 uses
this API in subset/superset constraints, but it is also used in EMF's
own Change model and possibly by other models. It's a first-class EMF
API that currently doesn't work for CDO resources.

The partial/conditional persistence filter thing is different. It's
certainly a possibility to keep it as an internal API for now, for
friends, to "incubate" it. Technically speaking, it's not a behaviour
that only UML models can implement, but it's weird enough in the EMF
context that I tend to agree with not exposing it as API.


>> (3) The reason why I have this problem with UML's subsets and supersets
>> is because
>>
>> legacy objects are loaded and populated *before* they are attached to
>> the resource.
>>
> Martin used to be the legacy expert. Where exactly does this happen?

Where does what happen? Attachment to the resource? I see that the
CDOLegacyWrapper's revisionToInstance() implements the following
sequence:

1. Connect to the container object
2. Populate all features
3. Connect to the resource

The last step is implemented in the revisionToInstanceResource()
method. I'll try changing revisionToInstance() to call that, first, to
see whether that is a sufficient change for my needs. After all, if we
connect to the container before populating other features, it can be
argued that we should also connect to the resource (for the case where
the container is a resource, not another object) before populating
features.

But, this is perhaps a drastic change in behaviour.


>> The norm in XML resources is to attach an object first to the resource
>> (or its container)
>>
>> and then populate it.
>>
>>
>> So, I might not have any issue at all if legacy objects were first
>> attached to their resource (or container, recursively) before being
>> populated from their revision data.But, is that realistic?What would
>> break if CDOResources suddenly started behaving in this other way?
>>
> Hard to say. I remember the legacy mechanism being quite complex, but I
> didn't develop it.

I think I can easily change the order in which objects are attached,
but I certainly don't know the down-stream impact any better than you
do! ;-)


>>
>> So, in the absence of any changes, the CDOLegacyWrapper causes
>> subset/superset constraints
>>
> You mean the newly proposed "persistence filters"?

No, that is a completely different problem. Quite orthogonal to the
"is loading" question.


>
>> to fire when loading legacy UML or other objects from revision data.
>>
>> What do you mean by "fire"?
>>
>>
>> The EList implementation that stores a subset or superset feature
>> automatically updates all of its related superset and subset features
>> when objects are added to it or removed from it.This doesn't rely on
>> notifications or anything else in the EMF run-time; it's an internal
>> hand-shaking protocol.
>>
> Between what exact entities?

Between the ELists that are settings of an object's features.

For example, in UML an Association has a "memberEnd" feature that is a
collection of Property elements. This is a superset of another feature
"ownedEnd", which has Property elements that are owned (contained) by
the Association. The "memberEnd" superset additionally can have
Property elements that are not owned by the Association, but by (for
example) Class elements that the Association connects.

So, we can add/remove elements to both the superset feature and the
subset feature. Being a subset, all Property elements in the
"ownedEnd" list *must* appear in the "memberEnd" list that is a
superset of it. Therefore, the "ownedEnd" subset's add() method
automatically adds a Property to the "memberEnd" list also, if that new
Property is not already in "memberEnd". Conversely, a Property that is
not in the "memberEnd" superset *must not* appear in the "ownedEnd"
list that is a subset of it. So, the "memberEnd" superset's remove()
method automatically removes a Property from the "ownedEnd" subset when
removing from the superset.

This is the kind of constraint enforcement that we are dealing with,
entirely between the feature settings of a single EObject.


>> Is it a matter of turning off and on again the eDeliver property in the
>> new persistence filtering
>>
>> mechansim?
>>
>>
>> No, it's not based on notifications and anyways, it's orthogonal to the
>> whole problem of partial or conditional persistence.This problem is
>> inherent to all superset/subset features, not just the crazy special
>> cases that UML 2.4.1 gave us.
>>
> I wonder if it would be a good idea that you try to demo the whole
> beast to me via TeamViewer :P

I could try, but it's not much of a demo. There's not really anything
to "see" except the debugger's Variables view. :-(


>> I have hacked together changes in UML2 that would allow me to
>> substitute a CDO-aware strategy for determining whether an object is
>> being loaded,
>>
>> By "being loaded" you mean CDOLegacyWrapper.revisionToInstance() being active?
>>
>>
>> Basically, yes.Populating the instance from its revision data modifies
>> the subset/superset ELists, which triggers the internal updates that I
>> need to suppress.
>>
> Theoretically we could add an SPI interface:
>
> public interface InternalCDOLegacyWrapper extends InternalCDOObject
> {
> public boolean isUnderConstruction();
> }
>
> Would that help?

Yes, that would help. It might be safer than changing the relative
timing of attachment to the resource, though I will try that, too.


>
>> but now I need to reliably determine whether a legacy object is in the
>> process of being populated from its revision data.
>>
>> Maybe we can expose CDOLegacyWrapper.underConstruction semi-publicly
>> (although we always strived for not exposing the native/legacy
>> distinction anywhere). Wanna play with it first?
>>
>>
>> I am totally happy to play with it.I have already observed the
>> underConstruction flag, and thought a nice diamond-shaped yellow icon
>> with the silhouette of a man stepping on a spade would suit it well.
>>
> Must be too late here, but I don't get it :P

Sorry, I was just painting a word-picture of the "under construction"
images that web pages used in the 1990's to indicate that content would
be coming soon. :-D Some of them were even GIFs that animated the
little construction worker digging.


> Do you mean "make it protected"? I think that wouldn't help you. The
> SPI interface above probably would, With it you could downcast the
> return value of CDOUtil.getCDOObject(EObject).
>
>> The question is which kind of API is better?
>>
>>
>> - a new ephemeral CDOState enumeration literal (e.g., "LOADING")
>>
> Definitely not without parity among native and legacy objects.
>
>> - a new InternalCDOObject.isLoading() query method
>>
> I have the impression it's not so much the "loading" of arbitrary
> CDOObjects but the "under construction" of CDOLegacyWrappers.
>
>> - a new CDOUtil.isLegacyObjectLoading(EObject) utility method
>>
> I'd prefer to keep this in the SPI space, see above.
>
>>
>> As I said above, I'm not even sure that an "is loading" state makes
>> sense for native objects, so that would rule out the first two API
>> options.
>>
> ;-)
>
>>
>>
>> The Question
>>
>> ------------------------------------------------------------
>>
>>
>> Does CDO provide an API that I can use to detect that a legacy object
>> is being populated from its revision data?
>>
>> Not yet, see above.
>>
>>
>> Or should I look into contributing something new?
>>
>> That would be a precondition for making it happen :P
>>
>>
>> Heh heh ... I'm trying my best to be self-sufficient.:-)I also want to
>> make sure that I only contribute useful stuff that CDO finds palatable,
>> which is why I need some guidance.I very much appreciate your help with
>> that, so far.
>>
> Yes, your cooperation is always very fruitful ;-)
>
> Cheers
> /Eike
>
> ----
> http://www.esc-net.de
> http://thegordian.blogspot.com
> http://twitter.com/eikestepper
Re: [CDO] Detecting whether a legacy object is being populated from revision data [message #963403 is a reply to message #963336] Mon, 29 October 2012 19:52 Go to previous messageGo to next message
Christian W. Damus is currently offline Christian W. Damus
Messages: 802
Registered: July 2009
Senior Member
On 2012-10-29 18:42:55 +0000, Eike Stepper said:

> Am 29.10.2012 19:26, schrieb Christian W. Damus:
>> Well, a very simple solution works perfectly for me.
>>
>> Attached is a Git e-mail patch that adds a "cdoInternalIsPopulating()"
>> method to the CDOObjectWrapperBase. The CDOLegacyWrapper implements
>> this in terms of the "underConstruction" flag. The public API is
>> CDOUtil::isLoading(EObject), which looks for a wrapper and asks it.
>>
>> I don't think concurency handling is of concern, because the only
>> object that can plausibly know about a wrapper before it has finished
>> populating (excepting the CDO infrastructure, of course) is the object,
>> itself. So, this method is only intended to be used by (and only
>> really useful to) the internal implementation of an object. That is
>> exactly the case in my UML scenario.
>>
>> If this looks anything like something that the CDO project would except
>> as a contribution, I can raise an enhancement request and start
>> iterating the patch, there.
> I prefer the InternalCDOLegacyWrapper interface that I proposed in my
> other reply.

Agreed. I prefer it, too.


> And I wonder if we should hide the entire persistence filtering
> mechanism from the public API until it becomes valid for native
> objects, too...

Always remembering that it's a solution to a completely different
problem, I would agree with that, too, just because it is such a
"weird" thing to do with models.

Note, however, that my latest revision of the patch on that bug works
for native objects too (following your suggestion) and I even included
a test to prove it. :-)

(not meaning this as an argument against hiding the API)

>
> Cheers
> /Eike
>
> ----
> http://www.esc-net.de
> http://thegordian.blogspot.com
> http://twitter.com/eikestepper
Re: [CDO] Detecting whether a legacy object is being populated from revision data [message #963412 is a reply to message #963397] Mon, 29 October 2012 20:05 Go to previous messageGo to next message
Christian W. Damus is currently offline Christian W. Damus
Messages: 802
Registered: July 2009
Senior Member
I tried changing the CDOLegacyWrapper::revisionToInstance() method to
connect the object to its resource (if any) before populating its
features.

With that change, UML2's subset/superset features see the containing
resource and can ask it whether it is currently loading, using the
Resource.Internal::isLoading() method.

Unfortunately, a CDOResource always says it isn't loading. The
CDOResource::loading field is never set.
Re: [CDO] Detecting whether a legacy object is being populated from revision data [message #963419 is a reply to message #963331] Mon, 29 October 2012 20:08 Go to previous messageGo to next message
Christian W. Damus is currently offline Christian W. Damus
Messages: 802
Registered: July 2009
Senior Member
On 2012-10-29 18:38:18 +0000, Eike Stepper said:

> I'd just wish we wouldn't need (compatible) changes on the general API
> (such as CDOClassInfo) if it's not a generally useful thing. I'd rather
> do these things internally then and add an x-friend org.eclipse.uml2 or
> so. Still thinking...

I've completed missed the fact that the persistence filter needn't be
API at all, anyways. It can absolutely be hidden internally. All that
a model such as UML2 has to do is set the annotation on its
EStructuralFeature. There's no need for clients ever to interact with
the filters.
Re: [CDO] Detecting whether a legacy object is being populated from revision data [message #963429 is a reply to message #963336] Mon, 29 October 2012 20:20 Go to previous messageGo to next message
Christian W. Damus is currently offline Christian W. Damus
Messages: 802
Registered: July 2009
Senior Member
On 2012-10-29 18:42:55 +0000, Eike Stepper said:

> I prefer the InternalCDOLegacyWrapper interface that I proposed in my
> other reply.

Yes, it's a simpler solution (attached) and works just as well in my tests.
Re: [CDO] Detecting whether a legacy object is being populated from revision data [message #963860 is a reply to message #963412] Tue, 30 October 2012 04:32 Go to previous messageGo to next message
Eike Stepper is currently offline Eike Stepper
Messages: 5540
Registered: July 2009
Senior Member
Am 29.10.2012 21:05, schrieb Christian W. Damus:
> I tried changing the CDOLegacyWrapper::revisionToInstance() method to connect the object to its resource (if any)
> before populating its features.
>
> With that change, UML2's subset/superset features see the containing resource and can ask it whether it is currently
> loading, using the Resource.Internal::isLoading() method.
>
> Unfortunately, a CDOResource always says it isn't loading. The CDOResource::loading field is never set.
I thought about that one when I read your other post. Maybe we can introduce a new internal counter field in
CDOResourceImpl and update it whenever CDOLegacyWrapper::underConstruction is changed. CDOResource::loading would be
adjusted on 0 <-> 1 transitions.

Cheers
/Eike

----
http://www.esc-net.de
http://thegordian.blogspot.com
http://twitter.com/eikestepper
Re: [CDO] Detecting whether a legacy object is being populated from revision data [message #963861 is a reply to message #963419] Tue, 30 October 2012 04:34 Go to previous messageGo to next message
Eike Stepper is currently offline Eike Stepper
Messages: 5540
Registered: July 2009
Senior Member
Am 29.10.2012 21:08, schrieb Christian W. Damus:
> On 2012-10-29 18:38:18 +0000, Eike Stepper said:
>
>> I'd just wish we wouldn't need (compatible) changes on the general API (such as CDOClassInfo) if it's not a generally
>> useful thing. I'd rather do these things internally then and add an x-friend org.eclipse.uml2 or so. Still thinking...
>
> I've completed missed the fact that the persistence filter needn't be API at all, anyways. It can absolutely be
> hidden internally. All that a model such as UML2 has to do is set the annotation on its EStructuralFeature. There's
> no need for clients ever to interact with the filters.
Excellent. There's no InternalCDOClassInfo, yet. But it should be easy to add in order to avoid downcasts to the Impl class.

Cheers
/Eike

----
http://www.esc-net.de
http://thegordian.blogspot.com
http://twitter.com/eikestepper
Re: [CDO] Detecting whether a legacy object is being populated from revision data [message #963866 is a reply to message #963403] Tue, 30 October 2012 04:39 Go to previous messageGo to next message
Eike Stepper is currently offline Eike Stepper
Messages: 5540
Registered: July 2009
Senior Member
Am 29.10.2012 20:52, schrieb Christian W. Damus:
> On 2012-10-29 18:42:55 +0000, Eike Stepper said:
>
>> Am 29.10.2012 19:26, schrieb Christian W. Damus:
>>> Well, a very simple solution works perfectly for me.
>>>
>>> Attached is a Git e-mail patch that adds a "cdoInternalIsPopulating()" method to the CDOObjectWrapperBase. The
>>> CDOLegacyWrapper implements this in terms of the "underConstruction" flag. The public API is
>>> CDOUtil::isLoading(EObject), which looks for a wrapper and asks it.
>>>
>>> I don't think concurency handling is of concern, because the only object that can plausibly know about a wrapper
>>> before it has finished populating (excepting the CDO infrastructure, of course) is the object, itself. So, this
>>> method is only intended to be used by (and only really useful to) the internal implementation of an object. That is
>>> exactly the case in my UML scenario.
>>>
>>> If this looks anything like something that the CDO project would except as a contribution, I can raise an
>>> enhancement request and start iterating the patch, there.
>> I prefer the InternalCDOLegacyWrapper interface that I proposed in my other reply.
>
> Agreed. I prefer it, too.
Good ;-)

>
>> And I wonder if we should hide the entire persistence filtering mechanism from the public API until it becomes valid
>> for native objects, too...
>
> Always remembering that it's a solution to a completely different problem, I would agree with that, too, just because
> it is such a "weird" thing to do with models.
>
> Note, however, that my latest revision of the patch on that bug works for native objects too (following your
> suggestion) and I even included a test to prove it. :-)
>
> (not meaning this as an argument against hiding the API)
I haven't looked at the tests, yet, because I trust you. My concern regarding public API was mostly driven by the fact
that the original approach did not support native objects. If there's the least bit of a chance that it can be a
generally useful functionality for all kinds of objects we can certainly make it API. It's not that much and it's in a
class (CDOClassInfo) that most users haven't seen anyway.

Cheers
/Eike

----
http://www.esc-net.de
http://thegordian.blogspot.com
http://twitter.com/eikestepper
Re: [CDO] Detecting whether a legacy object is being populated from revision data [message #964370 is a reply to message #963861] Tue, 30 October 2012 13:14 Go to previous messageGo to next message
Christian W. Damus is currently offline Christian W. Damus
Messages: 802
Registered: July 2009
Senior Member
On 2012-10-30 04:34:16 +0000, Eike Stepper said:

> Am 29.10.2012 21:08, schrieb Christian W. Damus:
>> On 2012-10-29 18:38:18 +0000, Eike Stepper said:
>>
>>> I'd just wish we wouldn't need (compatible) changes on the general API
>>> (such as CDOClassInfo) if it's not a generally useful thing. I'd rather
>>> do these things internally then and add an x-friend org.eclipse.uml2 or
>>> so. Still thinking...
>>
>> I've completed missed the fact that the persistence filter needn't be
>> API at all, anyways. It can absolutely be hidden internally. All that
>> a model such as UML2 has to do is set the annotation on its
>> EStructuralFeature. There's no need for clients ever to interact with
>> the filters.
> Excellent. There's no InternalCDOClassInfo, yet. But it should be easy
> to add in order to avoid downcasts to the Impl class.

Funny, that's exactly what my latest revision of the patch does. ;-)

cW
Re: [CDO] Detecting whether a legacy object is being populated from revision data [message #964377 is a reply to message #963860] Tue, 30 October 2012 13:21 Go to previous messageGo to next message
Christian W. Damus is currently offline Christian W. Damus
Messages: 802
Registered: July 2009
Senior Member
On 2012-10-30 04:32:17 +0000, Eike Stepper said:

> Am 29.10.2012 21:05, schrieb Christian W. Damus:
>> I tried changing the CDOLegacyWrapper::revisionToInstance() method to
>> connect the object to its resource (if any) before populating its
>> features.
>>
>> With that change, UML2's subset/superset features see the containing
>> resource and can ask it whether it is currently loading, using the
>> Resource.Internal::isLoading() method.
>>
>> Unfortunately, a CDOResource always says it isn't loading. The
>> CDOResource::loading field is never set.
> I thought about that one when I read your other post. Maybe we can
> introduce a new internal counter field in CDOResourceImpl and update
> it whenever CDOLegacyWrapper::underConstruction is changed.
> CDOResource::loading would be adjusted on 0 <-> 1 transitions.

Yes, that would be cool. But, in order for that to be useful, it
requires attaching the object to its resource first, before populating
features. I do think that would be most consistent with attaching to
the container before populating features (which is the current
behaviour), but worry about the impact that might have on existing
applications.

But, so much of the benefit of CDO is in capabilities that it provides
at the object level (loading, locking, versioning, etc.) that the rest
of EMF ordinarily can only implement at the resource level, that I feel
it makes sense to provide "is loading" state at the object level, too.
:-)

On the other hand, with the EMF isLoading() API working in CDOResources
as it does in XMLResources, UML wouldn't have to change anything. As
it is, I have to make changes in the UML2 run-time and in the code
generation templates to support object-level "is loading" in CDO.


>
> Cheers
> /Eike
>
> ----
> http://www.esc-net.de
> http://thegordian.blogspot.com
> http://twitter.com/eikestepper
Re: [CDO] Detecting whether a legacy object is being populated from revision data [message #964387 is a reply to message #963866] Tue, 30 October 2012 13:26 Go to previous messageGo to next message
Christian W. Damus is currently offline Christian W. Damus
Messages: 802
Registered: July 2009
Senior Member
On 2012-10-30 04:39:15 +0000, Eike Stepper said:

-------- 8< --------

>>> And I wonder if we should hide the entire persistence filtering
>>> mechanism from the public API until it becomes valid for native
>>> objects, too...
>>
>> Always remembering that it's a solution to a completely different
>> problem, I would agree with that, too, just because it is such a
>> "weird" thing to do with models.
>>
>> Note, however, that my latest revision of the patch on that bug works
>> for native objects too (following your suggestion) and I even included
>> a test to prove it. :-)
>>
>> (not meaning this as an argument against hiding the API)
> I haven't looked at the tests, yet, because I trust you. My concern
> regarding public API was mostly driven by the fact that the original
> approach did not support native objects. If there's the least bit of a
> chance that it can be a generally useful functionality for all kinds of
> objects we can certainly make it API. It's not that much and it's in a
> class (CDOClassInfo) that most users haven't seen anyway.

Heh heh ... don't trust me, yet. I think I've figured out how the test
framework works, but you might have something to say about that. :-)

I think this particular case is a modeling anti-pattern that shouldn't
be encouraged, in general. I would hope that UML 2.5 fixes this quirk
whenever it lands. That might even be a reason to support it only in
the legacy adapters, where we already accept some performance overhead,
because it's a special case brought to us by UML which is a legacy
model.

cW
Re: [CDO] Detecting whether a legacy object is being populated from revision data [message #964559 is a reply to message #963174] Tue, 30 October 2012 16:11 Go to previous message
Christian W. Damus is currently offline Christian W. Damus
Messages: 802
Registered: July 2009
Senior Member
Hi, Eike,

I've raised https://bugs.eclipse.org/bugs/show_bug.cgi?id=393164 to
continue the discussion of the "is loading" problem.

As I mentioned in that bug, the more I think about it, the more I am
convinced that supporting the Resource.Internal::isLoading() API for
legacy models in the CDOResource is the correct way to go.

Any "legacy" model was, by definition, designed to work in EMF's XML
resources. Those resources do attach objects before populating them
and support the isLoading() internal protocol. So, it can be expected
that legacy models can only work better in a CDOResource that provides
a similar behaviour.

Thanks,

Christian
Previous Topic:How to get the org.eclipse.uml2.uml.Type?
Next Topic:[CDO] Offline Branching
Goto Forum:
  


Current Time: Thu Oct 23 19:56:19 GMT 2014

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

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