Home » Modeling » EMF "Technology" (Ecore Tools, EMFatic, etc) » [Temporality] Temporality design
|
Re: [Temporality] Temporality design [message #105015 is a reply to message #105013] |
Fri, 21 December 2007 17:48 |
Eclipse User |
|
|
|
Originally posted by: stepper.sympedia.de
JC,
From your proposal I got the impression that you originally planned to
let the model developer add an EClass "Temporal" to the set of super
types in the Ecore model instead of setting the genmodel property "Root
Extends Class" = "o.e...Temporal". If I got that wrong I withdraw my
technical comment ;-)
Please see the other thread for comments on using a common infra
structure for EStore integration.
Regards,
Eike Stepper
----
http://wiki.eclipse.org/CDO
http://wiki.eclipse.org/Net4j
jc schrieb:
> Eike wrote:
>
> Technical comment:
> By forcing model developers to subclass a framework type (Temporality) your
> framework becomes invasive to the model. This might not be desirable for all
> models/model developers. With my CDO framework I started the model
> integration the same way (model invasive) and all users came quickly back
> with the question if there was a way to be more transparent. If you are
> interested in the solution I found for this problem we can discuss that
> (preferringly on the newsgroup). May be we are able to factor out a common
> framework to integrate orthogonal functions ionto EMF models.
>
> Conceptual comment/question:
> How do you plan to handle object graphs (as opposed to single instances and
> their attributes)? I guess your Temporality class will offer API to query
> object state of other versions of that object. Does this API return this
> object state as instances of EObject? If so, what will access to the
> reference features deliver? In other words, will it be possible to navigate
> a whole object graph like it had been at any time since creation of that
> graph? Or will it only be possible to query old attribute values?
>
> Eike,
>
> I would like to discuss your solution to removing the invasive (Temporal
> base class). I used this approach to leverage EMFs persistence. Since the
> base class is modeled all of the versions get persisted for free.
>
> So the whole design rests on a modeled Temporal base class and an
> intercepting time aware EStore.
>
> The time (version) aware EStore retrieves the attribute or reference value
> according to the time obtained from the TimeProvider. So when you crawl a
> graph are referenced EObjects the references are the ones for a given time.
> That is you crawl the graph as it looked at a given time.
>
> Thanks
> jc
>
>
>
|
|
| |
Re: [Temporality] Temporality design [message #105018 is a reply to message #105017] |
Fri, 21 December 2007 19:30 |
Eclipse User |
|
|
|
Originally posted by: stepper.sympedia.de
This is a multi-part message in MIME format.
--------------030006070108020504040407
Content-Type: text/plain; charset=ISO-8859-15; format=flowed
Content-Transfer-Encoding: 7bit
jc schrieb:
> You understood correctly. My design requires a Car model to have as a super
> type Temporal. This indicates to the feature that you want Car to be
> temporal and also provides a way to attach modeled version objects to the
> Car. That is the Temporal has a bi-directional reference with a
> VersionHolder EClass.
>
> The other thing the Temporality design requires is a hook in all
> setter/getter which is done in an EStore.
>
> Thoughts?
>
For the EStore integration you need to change the base class of all
modeled root classes to EStoreEObjectImpl (via "Root Extends Class"
genmodel property). Why don't you provide an own subclass of
EStoreEObjectImpl that implements the new API which you can provide via
via "Root Extends Interface" genmodel property? That is want I meant
(and what CDO does do). This way you keep the model free of framework
interfaces.
Regards,
Eike Stepper
----
http://wiki.eclipse.org/CDO
http://wiki.eclipse.org/Net4j
> "Eike Stepper" <stepper@sympedia.de> wrote in message
> news:fkgua1$hj7$1@build.eclipse.org...
>
>> JC,
>>
>> From your proposal I got the impression that you originally planned to let
>> the model developer add an EClass "Temporal" to the set of super types in
>> the Ecore model instead of setting the genmodel property "Root Extends
>> Class" = "o.e...Temporal". If I got that wrong I withdraw my technical
>> comment ;-)
>>
>> Please see the other thread for comments on using a common infra structure
>> for EStore integration.
>>
>> Regards,
>> Eike Stepper
>> ----
>> http://wiki.eclipse.org/CDO
>> http://wiki.eclipse.org/Net4j
>>
>>
>>
>> jc schrieb:
>>
>>> Eike wrote:
>>>
>>> Technical comment:
>>> By forcing model developers to subclass a framework type (Temporality)
>>> your framework becomes invasive to the model. This might not be desirable
>>> for all models/model developers. With my CDO framework I started the
>>> model integration the same way (model invasive) and all users came
>>> quickly back with the question if there was a way to be more transparent.
>>> If you are interested in the solution I found for this problem we can
>>> discuss that (preferringly on the newsgroup). May be we are able to
>>> factor out a common framework to integrate orthogonal functions ionto EMF
>>> models.
>>>
>>> Conceptual comment/question:
>>> How do you plan to handle object graphs (as opposed to single instances
>>> and their attributes)? I guess your Temporality class will offer API to
>>> query object state of other versions of that object. Does this API return
>>> this object state as instances of EObject? If so, what will access to the
>>> reference features deliver? In other words, will it be possible to
>>> navigate a whole object graph like it had been at any time since creation
>>> of that graph? Or will it only be possible to query old attribute values?
>>>
>>> Eike,
>>>
>>> I would like to discuss your solution to removing the invasive (Temporal
>>> base class). I used this approach to leverage EMFs persistence. Since the
>>> base class is modeled all of the versions get persisted for free.
>>>
>>> So the whole design rests on a modeled Temporal base class and an
>>> intercepting time aware EStore.
>>>
>>> The time (version) aware EStore retrieves the attribute or reference
>>> value according to the time obtained from the TimeProvider. So when you
>>> crawl a graph are referenced EObjects the references are the ones for a
>>> given time. That is you crawl the graph as it looked at a given time.
>>>
>>> Thanks
>>> jc
>>>
>>>
>>>
>>>
>
>
>
--------------030006070108020504040407
Content-Type: text/html; charset=ISO-8859-15
Content-Transfer-Encoding: 7bit
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html;charset=ISO-8859-15"
http-equiv="Content-Type">
</head>
<body bgcolor="#ffffff" text="#000000">
jc schrieb:
<blockquote cite="mid:fkh00h$hr4$1@build.eclipse.org" type="cite">
<pre wrap="">You understood correctly. My design requires a Car model to have as a super
type Temporal. This indicates to the feature that you want Car to be
temporal and also provides a way to attach modeled version objects to the
Car. That is the Temporal has a bi-directional reference with a
VersionHolder EClass.
The other thing the Temporality design requires is a hook in all
setter/getter which is done in an EStore.
Thoughts?
</pre>
</blockquote>
For the EStore integration you need to change the base class of all
modeled root classes to EStoreEObjectImpl (via "Root Extends Class"
genmodel property). Why don't you provide an own subclass of
EStoreEObjectImpl that implements the new API which you can provide via
via "Root Extends Interface" genmodel property? That is want I meant
(and what CDO does do). This way you keep the model free of framework
interfaces.<br>
<br>
Regards,<br>
Eike Stepper<br>
----<br>
<a class="moz-txt-link-freetext" href="http://wiki.eclipse.org/CDO">http://wiki.eclipse.org/CDO</a><br>
<a class="moz-txt-link-freetext" href="http://wiki.eclipse.org/Net4j">http://wiki.eclipse.org/Net4j</a><br>
<br>
<br>
<blockquote cite="mid:fkh00h$hr4$1@build.eclipse.org" type="cite">
<pre wrap="">"Eike Stepper" <a class="moz-txt-link-rfc2396E" href="mailto:stepper@sympedia.de"><stepper@sympedia.de></a> wrote in message
<a class="moz-txt-link-freetext" href="news:fkgua1$hj7$1@build.eclipse.org">news:fkgua1$hj7$1@build.eclipse.org</a>...
</pre>
<blockquote type="cite">
<pre wrap="">JC,
From your proposal I got the impression that you originally planned to let
the model developer add an EClass "Temporal" to the set of super types in
the Ecore model instead of setting the genmodel property "Root Extends
Class" = "o.e...Temporal". If I got that wrong I withdraw my technical
comment ;-)
Please see the other thread for comments on using a common infra structure
for EStore integration.
Regards,
Eike Stepper
----
<a class="moz-txt-link-freetext" href="http://wiki.eclipse.org/CDO">http://wiki.eclipse.org/CDO</a>
<a class="moz-txt-link-freetext" href="http://wiki.eclipse.org/Net4j">http://wiki.eclipse.org/Net4j</a>
jc schrieb:
</pre>
<blockquote type="cite">
<pre wrap="">Eike wrote:
Technical comment:
By forcing model developers to subclass a framework type (Temporality)
your framework becomes invasive to the model. This might not be desirable
for all models/model developers. With my CDO framework I started the
model integration the same way (model invasive) and all users came
quickly back with the question if there was a way to be more transparent.
If you are interested in the solution I found for this problem we can
discuss that (preferringly on the newsgroup). May be we are able to
factor out a common framework to integrate orthogonal functions ionto EMF
models.
Conceptual comment/question:
How do you plan to handle object graphs (as opposed to single instances
and their attributes)? I guess your Temporality class will offer API to
query object state of other versions of that object. Does this API return
this object state as instances of EObject? If so, what will access to the
reference features deliver? In other words, will it be possible to
navigate a whole object graph like it had been at any time since creation
of that graph? Or will it only be possible to query old attribute values?
Eike,
I would like to discuss your solution to removing the invasive (Temporal
base class). I used this approach to leverage EMFs persistence. Since the
base class is modeled all of the versions get persisted for free.
So the whole design rests on a modeled Temporal base class and an
intercepting time aware EStore.
The time (version) aware EStore retrieves the attribute or reference
value according to the time obtained from the TimeProvider. So when you
crawl a graph are referenced EObjects the references are the ones for a
given time. That is you crawl the graph as it looked at a given time.
Thanks
jc
</pre>
</blockquote>
</blockquote>
<pre wrap=""><!---->
</pre>
</blockquote>
</body>
</html>
--------------030006070108020504040407--
|
|
| |
Re: [Temporality] Temporality design [message #105027 is a reply to message #105026] |
Sun, 23 December 2007 10:00 |
Eclipse User |
|
|
|
Originally posted by: stepper.sympedia.de
Jean-Claude schrieb:
> I'm a bit new to EMF so please bear with me if I say things that are
> not quite accurate.
>
> I realize users might not like to have to add a super type from the
> framework to every one of the types you want persisted in CDO or for
> every type you want Temporal etc.
>
> I understand how using a "Root Extends Class" in the genmodel is
> easier to specify for a user then having to do that. Also I understand
> how using such a EObject base class provides a way to "attach" CDO's
> API to every EObject.
>
> However I find using the "Root Extends Class" approach blocks other
> features from augmenting the EObject API. Two features depending on
> this technique will not work together. Is this correct?
Yes, that's why I suggested that we take a step back and see if we can
come up with a proposal of a common base class that can be used with
multiple technical features (one at a time). This base class would be a
subclass of EStoreEObjectImpl. Although it would probably not permit to
install multiple features at runtime it would free the developer from
selecting one feature (thereby excluding the others) at generation time.
I'm not sure if it will be possible at all but an attempt to consolidate
our store integrations could yield interesting results.
> I would rather use a modeled super type (with "method body"
> annotations) and rely on the code generator to "attach" my API to
> every EObject by injecting the method and method bodies into every
> generated EObject.
>
> It is true that I still need a "Root Extends Class" to plug my EStore
> hook and that again two features depending on this technique will not
> work together. But I believe this is a limitation of the EMF framework
> that should be address so that many features can play nice together.
"Root Extends Class" is a very powerful and very general mechanism. I
guess not all "RootExtenders" are delegating to an EStore and not all
RootExtenders that do delegate to an EStore will be able to use a common
root class. I believe it's the existance of certain requirements that
could open the door for such consolidation, requirements like the often
cited "pre-event hooks in getters and setters".
May be it's best that we wait until you come up with working code for
your problem and then look if we can factor out such a common base
class. On the other hand it could be useful for you to see how the
CDOStore (implements EStore) is working and what was necessary in the
CDOObjectImpl (extends EStoreEObjectImpl) to make it work with that store:
-
http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.emf/org .eclipse.emf.cdo/plugins/org.eclipse.emf.cdo/src/org/eclipse /emf/internal/cdo/CDOStore.java?root=Modeling_Project&vi ew=markup
-
http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.emf/org .eclipse.emf.cdo/plugins/org.eclipse.emf.cdo/src/org/eclipse /emf/internal/cdo/CDOObjectImpl.java?root=Modeling_Project&a mp;view=markup
> [Bug 197487] Provide stateless EstoreEList and EStoreFeatureMap base
> classes.
>
> What was the main concern of the users with having to add a super type
> from the framework? Was it the inconvenience of having to go through
> every type and add the super type?
Partly, although I had a migrator tool that performed this task
automatically. I think it's more a conceptual issue with the *core*
model being abused for model-unrelated things/features. In anology (I
hope) you seldom hear users complaining about the inconvenience of
maintaining a separate genmodel. They know that the (E) core model
should be as close to their business domain as possible and free of
technical features.
> I really appreciate your comments Eike. As I said I'm new to EMF so I
> need these feedback to help me nail down the Temporality feature
> correctly.
Great. To be honest I'm really not sure if we'll manage to identify
concrete potential for "store integration consolidation" but I think
that the discussion is interesting for both of us.
> BTW: How do other features plug themselves into EMF? Do they mostly
> use the EMF adapters/observers?
I can only guess but I think the better features are doing whatever is
feasible and appropriate for them to fulfill their requirements. Smart
answer, eh? ;-)
Regards,
Eike Stepper
----
http://wiki.eclipse.org/CDO
http://wiki.eclipse.org/Net4j
|
|
|
Re: [Temporality] Temporality design [message #105087 is a reply to message #105027] |
Sun, 23 December 2007 12:17 |
Eclipse User |
|
|
|
Originally posted by: merks.ca.ibm.com
Guys,
It's nice to see the newsgroup being used for open design discussions!
My 2 cents below.
Eike Stepper wrote:
> Jean-Claude schrieb:
>> I'm a bit new to EMF so please bear with me if I say things that are
>> not quite accurate.
>>
>> I realize users might not like to have to add a super type from the
>> framework to every one of the types you want persisted in CDO or for
>> every type you want Temporal etc.
>>
>> I understand how using a "Root Extends Class" in the genmodel is
>> easier to specify for a user then having to do that. Also I
>> understand how using such a EObject base class provides a way to
>> "attach" CDO's API to every EObject.
>>
>> However I find using the "Root Extends Class" approach blocks other
>> features from augmenting the EObject API. Two features depending on
>> this technique will not work together. Is this correct?
> Yes, that's why I suggested that we take a step back and see if we can
> come up with a proposal of a common base class that can be used with
> multiple technical features (one at a time). This base class would be
> a subclass of EStoreEObjectImpl. Although it would probably not permit
> to install multiple features at runtime it would free the developer
> from selecting one feature (thereby excluding the others) at
> generation time. I'm not sure if it will be possible at all but an
> attempt to consolidate our store integrations could yield interesting
> results.
With regard to root extends interface and root extends class. These are
quite useful for a number of reasons but one thing they are not good for
is if these things really want to introduce modeled
EStructuralFeatures. Such things must be part of the known EClass
hierarchy. One aspect of how these can be used that I'm sure is totally
not obvious but is very powerful is root implements interface, which for
SDO you can see is set to InternalEDataObject. If you look in the
SDO.ecore model for what's in the hierarchy of this you'll see it
specifies all kinds of EOperations with actual method body annotations.
As a result, if you are extending a non data object XyzImpl (one that
doesn't extend the EDataObjectImpl root extends class), the methods
bodies form the root implements interface will be generated into the
generated derived class. In this way, additional API implementations
can be mixed into an established hierarchy without requiring the use of
a specific base class.
>
>> I would rather use a modeled super type (with "method body"
>> annotations) and rely on the code generator to "attach" my API to
>> every EObject by injecting the method and method bodies into every
>> generated EObject.
>>
>> It is true that I still need a "Root Extends Class" to plug my EStore
>> hook and that again two features depending on this technique will not
>> work together. But I believe this is a limitation of the EMF
>> framework that should be address so that many features can play nice
>> together.
> "Root Extends Class" is a very powerful and very general mechanism. I
> guess not all "RootExtenders" are delegating to an EStore and not all
> RootExtenders that do delegate to an EStore will be able to use a
> common root class. I believe it's the existance of certain
> requirements that could open the door for such consolidation,
> requirements like the often cited "pre-event hooks in getters and
> setters".
>
> May be it's best that we wait until you come up with working code for
> your problem and then look if we can factor out such a common base
> class. On the other hand it could be useful for you to see how the
> CDOStore (implements EStore) is working and what was necessary in the
> CDOObjectImpl (extends EStoreEObjectImpl) to make it work with that
> store:
Often the idea is to have both a base class and a root implements
interface with method bodies that can be used to mix in what's in the
base class. Of course right now we only have the ability to mix in
method bodies, and not stateful fields, but if use cases require them, I
could imagine adding some type of support for them (perhaps by having
something similar to <%a.b.C%> which does an import but instead would be
used to inject field declarations in the containing class.
>
> -
> http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.emf/org .eclipse.emf.cdo/plugins/org.eclipse.emf.cdo/src/org/eclipse /emf/internal/cdo/CDOStore.java?root=Modeling_Project&vi ew=markup
>
>
> -
> http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.emf/org .eclipse.emf.cdo/plugins/org.eclipse.emf.cdo/src/org/eclipse /emf/internal/cdo/CDOObjectImpl.java?root=Modeling_Project&a mp;view=markup
>
>
>> [Bug 197487] Provide stateless EstoreEList and EStoreFeatureMap base
>> classes.
>>
>> What was the main concern of the users with having to add a super
>> type from the framework? Was it the inconvenience of having to go
>> through every type and add the super type?
> Partly, although I had a migrator tool that performed this task
> automatically. I think it's more a conceptual issue with the *core*
> model being abused for model-unrelated things/features. In anology (I
> hope) you seldom hear users complaining about the inconvenience of
> maintaining a separate genmodel. They know that the (E) core model
> should be as close to their business domain as possible and free of
> technical features.
>
>> I really appreciate your comments Eike. As I said I'm new to EMF so I
>> need these feedback to help me nail down the Temporality feature
>> correctly.
> Great. To be honest I'm really not sure if we'll manage to identify
> concrete potential for "store integration consolidation" but I think
> that the discussion is interesting for both of us.
And for me too.
>
>> BTW: How do other features plug themselves into EMF? Do they mostly
>> use the EMF adapters/observers?
> I can only guess but I think the better features are doing whatever is
> feasible and appropriate for them to fulfill their requirements. Smart
> answer, eh? ;-)
Generally the lest obtrusive something is in terms of impact on
generated code the more likely it can be reused broadly. Certainly
read hooks are a common source of "incompatibilities" because the basic
generation pattern simply has no read hooks and adding anything to a
method that simply returns a variable has a dramatic impact on
performance; you just can't beat "X foo() { return x; }" in terms of
performance and even the most minor addition, particularly a call to any
other method, can have an order of magnitude impact...
>
> Regards,
> Eike Stepper
> ----
> http://wiki.eclipse.org/CDO
> http://wiki.eclipse.org/Net4j
|
|
|
Re: [Temporality] Temporality design [message #105197 is a reply to message #105087] |
Tue, 25 December 2007 17:11 |
Jean-Claude Cote Messages: 56 Registered: July 2009 |
Member |
|
|
Ed Merks wrote:
> Guys,
> It's nice to see the newsgroup being used for open design discussions!
> My 2 cents below.
> Eike Stepper wrote:
>> Jean-Claude schrieb:
>>> I'm a bit new to EMF so please bear with me if I say things that are
>>> not quite accurate.
>>>
>>> I realize users might not like to have to add a super type from the
>>> framework to every one of the types you want persisted in CDO or for
>>> every type you want Temporal etc.
>>>
>>> I understand how using a "Root Extends Class" in the genmodel is
>>> easier to specify for a user then having to do that. Also I
>>> understand how using such a EObject base class provides a way to
>>> "attach" CDO's API to every EObject.
>>>
>>> However I find using the "Root Extends Class" approach blocks other
>>> features from augmenting the EObject API. Two features depending on
>>> this technique will not work together. Is this correct?
>> Yes, that's why I suggested that we take a step back and see if we can
>> come up with a proposal of a common base class that can be used with
>> multiple technical features (one at a time). This base class would be
>> a subclass of EStoreEObjectImpl. Although it would probably not permit
>> to install multiple features at runtime it would free the developer
>> from selecting one feature (thereby excluding the others) at
>> generation time. I'm not sure if it will be possible at all but an
>> attempt to consolidate our store integrations could yield interesting
>> results.
> With regard to root extends interface and root extends class. These are
> quite useful for a number of reasons but one thing they are not good for
> is if these things really want to introduce modeled
> EStructuralFeatures. Such things must be part of the known EClass
> hierarchy. One aspect of how these can be used that I'm sure is totally
> not obvious but is very powerful is root implements interface, which for
> SDO you can see is set to InternalEDataObject. If you look in the
> SDO.ecore model for what's in the hierarchy of this you'll see it
> specifies all kinds of EOperations with actual method body annotations.
> As a result, if you are extending a non data object XyzImpl (one that
> doesn't extend the EDataObjectImpl root extends class), the methods
> bodies form the root implements interface will be generated into the
> generated derived class. In this way, additional API implementations
> can be mixed into an established hierarchy without requiring the use of
> a specific base class.
I did not know of this feature of the GenModel. I like the idea very much.
It's a nice way to mix-in implementation into generated code without
having to declare it explicitly in your model. However after playing with
it a bit it appears to me that it only will inject methods into modeled
types that have super types from other .ecore files.
public class ClassWithMethodsToInjectImpl extends EObjectImpl implements
ClassWithMethodsToInject {
...
public void operation1() {
/* body goes here */
}
public class ReceivingClassImpl extends EObjectImpl implements
ReceivingClass {
public class SubClassOfReceivingClassImpl extends ReceivingClassImpl
implements SubClassOfReceivingClass {
public class SubOfExternalImpl extends AnyTypeImpl implements
SubOfExternal, ClassWithMethodsToInject {
...
public void operation1() {
/* body goes here */
}
>>
>>> I would rather use a modeled super type (with "method body"
>>> annotations) and rely on the code generator to "attach" my API to
>>> every EObject by injecting the method and method bodies into every
>>> generated EObject.
>>>
>>> It is true that I still need a "Root Extends Class" to plug my EStore
>>> hook and that again two features depending on this technique will not
>>> work together. But I believe this is a limitation of the EMF
>>> framework that should be address so that many features can play nice
>>> together.
>> "Root Extends Class" is a very powerful and very general mechanism. I
>> guess not all "RootExtenders" are delegating to an EStore and not all
>> RootExtenders that do delegate to an EStore will be able to use a
>> common root class. I believe it's the existance of certain
>> requirements that could open the door for such consolidation,
>> requirements like the often cited "pre-event hooks in getters and
>> setters".
>>
>> May be it's best that we wait until you come up with working code for
>> your problem and then look if we can factor out such a common base
>> class. On the other hand it could be useful for you to see how the
>> CDOStore (implements EStore) is working and what was necessary in the
>> CDOObjectImpl (extends EStoreEObjectImpl) to make it work with that
>> store:
I have the basic functionality already working. I just need to put in in
the CVS repository. I'm reading up on the whole process of setting up
these projects for the build host etc. Once I have this uploaded I think
it will be easier for us to discuss these details.
> Often the idea is to have both a base class and a root implements
> interface with method bodies that can be used to mix in what's in the
> base class. Of course right now we only have the ability to mix in
> method bodies, and not stateful fields, but if use cases require them, I
> could imagine adding some type of support for them (perhaps by having
> something similar to <%a.b.C%> which does an import but instead would be
> used to inject field declarations in the containing class.
>>
>> -
>>
http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.emf/org .eclipse.emf.cdo/plugins/org.eclipse.emf.cdo/src/org/eclipse /emf/internal/cdo/CDOStore.java?root=Modeling_Project&vi ew=markup
>>
>>
>> -
>>
http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.emf/org .eclipse.emf.cdo/plugins/org.eclipse.emf.cdo/src/org/eclipse /emf/internal/cdo/CDOObjectImpl.java?root=Modeling_Project&a mp;view=markup
>>
>>
>>> [Bug 197487] Provide stateless EstoreEList and EStoreFeatureMap base
>>> classes.
>>>
>>> What was the main concern of the users with having to add a super
>>> type from the framework? Was it the inconvenience of having to go
>>> through every type and add the super type?
>> Partly, although I had a migrator tool that performed this task
>> automatically. I think it's more a conceptual issue with the *core*
>> model being abused for model-unrelated things/features. In anology (I
>> hope) you seldom hear users complaining about the inconvenience of
>> maintaining a separate genmodel. They know that the (E) core model
>> should be as close to their business domain as possible and free of
>> technical features.
>>
>>> I really appreciate your comments Eike. As I said I'm new to EMF so I
>>> need these feedback to help me nail down the Temporality feature
>>> correctly.
>> Great. To be honest I'm really not sure if we'll manage to identify
>> concrete potential for "store integration consolidation" but I think
>> that the discussion is interesting for both of us.
> And for me too.
>>
>>> BTW: How do other features plug themselves into EMF? Do they mostly
>>> use the EMF adapters/observers?
>> I can only guess but I think the better features are doing whatever is
>> feasible and appropriate for them to fulfill their requirements. Smart
>> answer, eh? ;-)
> Generally the lest obtrusive something is in terms of impact on
> generated code the more likely it can be reused broadly. Certainly
> read hooks are a common source of "incompatibilities" because the basic
> generation pattern simply has no read hooks and adding anything to a
> method that simply returns a variable has a dramatic impact on
> performance; you just can't beat "X foo() { return x; }" in terms of
> performance and even the most minor addition, particularly a call to any
> other method, can have an order of magnitude impact...
>>
>> Regards,
>> Eike Stepper
>> ----
>> http://wiki.eclipse.org/CDO
>> http://wiki.eclipse.org/Net4j
|
|
|
Re: [Temporality] Temporality design [message #105238 is a reply to message #105197] |
Wed, 26 December 2007 12:01 |
Eclipse User |
|
|
|
Originally posted by: merks.ca.ibm.com
Jean-Claude,
Keep in mind that when a Root Implements Interface or a Root Extends
Interface is specified, the generator assumes that the Root Extends
Class implements the full API for both (I think it checks that it's
different from EObjectImpl as well). So typically you'd have a model in
which you extend EObject explicitly so as to mix in the additional API
(like EDataObjectImpl in SDO) and then other models would use that
(EDataObjectImpl) as the Root Extends Class; this avoids generating lots
of methods in lots of models by having a single root that already
implements them. Of course once a base class has implemented this API,
there's no need to mix it in again in derived classes of that base
class; perhaps that's what you are observing with your comment about
extending a class from a different model? (The generator checks if the
base model specifies a different Root Implements interface which tells
it whether it needs to mix that in.)
Jean-Claude wrote:
> Ed Merks wrote:
>
>> Guys,
>
>> It's nice to see the newsgroup being used for open design
>> discussions! My 2 cents below.
>
>> Eike Stepper wrote:
>>> Jean-Claude schrieb:
>>>> I'm a bit new to EMF so please bear with me if I say things that
>>>> are not quite accurate.
>>>>
>>>> I realize users might not like to have to add a super type from the
>>>> framework to every one of the types you want persisted in CDO or
>>>> for every type you want Temporal etc.
>>>>
>>>> I understand how using a "Root Extends Class" in the genmodel is
>>>> easier to specify for a user then having to do that. Also I
>>>> understand how using such a EObject base class provides a way to
>>>> "attach" CDO's API to every EObject.
>>>>
>>>> However I find using the "Root Extends Class" approach blocks other
>>>> features from augmenting the EObject API. Two features depending on
>>>> this technique will not work together. Is this correct?
>>> Yes, that's why I suggested that we take a step back and see if we
>>> can come up with a proposal of a common base class that can be used
>>> with multiple technical features (one at a time). This base class
>>> would be a subclass of EStoreEObjectImpl. Although it would probably
>>> not permit to install multiple features at runtime it would free the
>>> developer from selecting one feature (thereby excluding the others)
>>> at generation time. I'm not sure if it will be possible at all but
>>> an attempt to consolidate our store integrations could yield
>>> interesting results.
>> With regard to root extends interface and root extends class. These
>> are quite useful for a number of reasons but one thing they are not
>> good for is if these things really want to introduce modeled
>> EStructuralFeatures. Such things must be part of the known EClass
>> hierarchy. One aspect of how these can be used that I'm sure is
>> totally not obvious but is very powerful is root implements
>> interface, which for SDO you can see is set to InternalEDataObject.
>> If you look in the SDO.ecore model for what's in the hierarchy of
>> this you'll see it specifies all kinds of EOperations with actual
>> method body annotations. As a result, if you are extending a non
>> data object XyzImpl (one that doesn't extend the EDataObjectImpl root
>> extends class), the methods bodies form the root implements interface
>> will be generated into the generated derived class. In this way,
>> additional API implementations can be mixed into an established
>> hierarchy without requiring the use of a specific base class.
>
> I did not know of this feature of the GenModel. I like the idea very
> much. It's a nice way to mix-in implementation into generated code
> without having to declare it explicitly in your model. However after
> playing with it a bit it appears to me that it only will inject
> methods into modeled types that have super types from other .ecore files.
>
> public class ClassWithMethodsToInjectImpl extends EObjectImpl
> implements ClassWithMethodsToInject {
> ..
> public void operation1() {
> /* body goes here */
> }
>
> public class ReceivingClassImpl extends EObjectImpl implements
> ReceivingClass {
>
> public class SubClassOfReceivingClassImpl extends ReceivingClassImpl
> implements SubClassOfReceivingClass {
>
> public class SubOfExternalImpl extends AnyTypeImpl implements
> SubOfExternal, ClassWithMethodsToInject {
> ..
> public void operation1() {
> /* body goes here */
> }
>
>
>
>>>
>>>> I would rather use a modeled super type (with "method body"
>>>> annotations) and rely on the code generator to "attach" my API to
>>>> every EObject by injecting the method and method bodies into every
>>>> generated EObject.
>>>>
>>>> It is true that I still need a "Root Extends Class" to plug my
>>>> EStore hook and that again two features depending on this technique
>>>> will not work together. But I believe this is a limitation of the
>>>> EMF framework that should be address so that many features can play
>>>> nice together.
>>> "Root Extends Class" is a very powerful and very general mechanism.
>>> I guess not all "RootExtenders" are delegating to an EStore and not
>>> all RootExtenders that do delegate to an EStore will be able to use
>>> a common root class. I believe it's the existance of certain
>>> requirements that could open the door for such consolidation,
>>> requirements like the often cited "pre-event hooks in getters and
>>> setters".
>>>
>>> May be it's best that we wait until you come up with working code
>>> for your problem and then look if we can factor out such a common
>>> base class. On the other hand it could be useful for you to see how
>>> the CDOStore (implements EStore) is working and what was necessary
>>> in the CDOObjectImpl (extends EStoreEObjectImpl) to make it work
>>> with that store:
> I have the basic functionality already working. I just need to put in
> in the CVS repository. I'm reading up on the whole process of setting
> up these projects for the build host etc. Once I have this uploaded I
> think it will be easier for us to discuss these details.
>
>> Often the idea is to have both a base class and a root implements
>> interface with method bodies that can be used to mix in what's in the
>> base class. Of course right now we only have the ability to mix in
>> method bodies, and not stateful fields, but if use cases require
>> them, I could imagine adding some type of support for them (perhaps
>> by having something similar to <%a.b.C%> which does an import but
>> instead would be used to inject field declarations in the containing
>> class.
>>>
>>> -
> http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.emf/org .eclipse.emf.cdo/plugins/org.eclipse.emf.cdo/src/org/eclipse /emf/internal/cdo/CDOStore.java?root=Modeling_Project&vi ew=markup
>
>>>
>>>
>>> -
> http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.emf/org .eclipse.emf.cdo/plugins/org.eclipse.emf.cdo/src/org/eclipse /emf/internal/cdo/CDOObjectImpl.java?root=Modeling_Project&a mp;view=markup
>
>>>
>>>
>>>> [Bug 197487] Provide stateless EstoreEList and EStoreFeatureMap
>>>> base classes.
>>>>
>>>> What was the main concern of the users with having to add a super
>>>> type from the framework? Was it the inconvenience of having to go
>>>> through every type and add the super type?
>>> Partly, although I had a migrator tool that performed this task
>>> automatically. I think it's more a conceptual issue with the *core*
>>> model being abused for model-unrelated things/features. In anology
>>> (I hope) you seldom hear users complaining about the inconvenience
>>> of maintaining a separate genmodel. They know that the (E) core
>>> model should be as close to their business domain as possible and
>>> free of technical features.
>>>
>>>> I really appreciate your comments Eike. As I said I'm new to EMF so
>>>> I need these feedback to help me nail down the Temporality feature
>>>> correctly.
>>> Great. To be honest I'm really not sure if we'll manage to identify
>>> concrete potential for "store integration consolidation" but I think
>>> that the discussion is interesting for both of us.
>> And for me too.
>>>
>>>> BTW: How do other features plug themselves into EMF? Do they mostly
>>>> use the EMF adapters/observers?
>>> I can only guess but I think the better features are doing whatever
>>> is feasible and appropriate for them to fulfill their requirements.
>>> Smart answer, eh? ;-)
>> Generally the lest obtrusive something is in terms of impact on
>> generated code the more likely it can be reused broadly. Certainly
>> read hooks are a common source of "incompatibilities" because the
>> basic generation pattern simply has no read hooks and adding anything
>> to a method that simply returns a variable has a dramatic impact on
>> performance; you just can't beat "X foo() { return x; }" in terms of
>> performance and even the most minor addition, particularly a call to
>> any other method, can have an order of magnitude impact...
>>>
>>> Regards,
>>> Eike Stepper
>>> ----
>>> http://wiki.eclipse.org/CDO
>>> http://wiki.eclipse.org/Net4j
>
>
|
|
| |
Re: [Temporality] Temporality design [message #105265 is a reply to message #105251] |
Wed, 26 December 2007 16:33 |
Eclipse User |
|
|
|
Originally posted by: merks.ca.ibm.com
Jean-Claude,
Have a look at SDO.genmodel itself and at what happens when you invoke
Set SDO Defaults in the GenModel. The expectation is that you typically
set both the Root Extends Class (which implements the Root Implements
Interface already) and the Root Implements Interface and that the mixing
behavior is needed only if you extend a class from a model with a
different Root Extends Class...
And no, you can't specify multiple. You'll need to define one that in
turn extends all the other ones you'd like to combine.
Jean-Claude wrote:
> I see you have to explicitly extend something from another genmodel in
> order for the code generator to mix-in the operations from the "Root
> Implements Interface". I'm going to make different scenarios and post
> them here.
>
> BTW: Can I specify multiple "Root Implements Interface" ? I tried
> different seperators but none worked so far.
>
> thanks
> Jean-Claude
>
>
|
|
|
Re: [Temporality] Temporality design [message #105323 is a reply to message #105265] |
Thu, 27 December 2007 11:44 |
Eclipse User |
|
|
|
Originally posted by: stepper.sympedia.de
Ed Merks schrieb:
> Jean-Claude,
>
> Have a look at SDO.genmodel itself and at what happens when you invoke
> Set SDO Defaults in the GenModel. The expectation is that you
> typically set both the Root Extends Class (which implements the Root
> Implements Interface already) and the Root Implements Interface and
> that the mixing behavior is needed only if you extend a class from a
> model with a different Root Extends Class...
>
> And no, you can't specify multiple. You'll need to define one that in
> turn extends all the other ones you'd like to combine.
That's what I'm doing for CDO, too, in order to generate a Resource
implementation that's a CDOObject as well:
public interface EresourceObject extends CDOObject, Resource.Internal
{
}
I'm using EresourceObject as Root Extends Interface in the genmodel.
Regards,
Eike Stepper
----
http://wiki.eclipse.org/CDO
http://wiki.eclipse.org/Net4j
>
>
> Jean-Claude wrote:
>> I see you have to explicitly extend something from another genmodel
>> in order for the code generator to mix-in the operations from the
>> "Root Implements Interface". I'm going to make different scenarios
>> and post them here.
>>
>> BTW: Can I specify multiple "Root Implements Interface" ? I tried
>> different seperators but none worked so far.
>>
>> thanks
>> Jean-Claude
>>
>>
|
|
| |
Re: [Temporality] Temporality design [message #612956 is a reply to message #105013] |
Fri, 21 December 2007 17:48 |
|
JC,
From your proposal I got the impression that you originally planned to
let the model developer add an EClass "Temporal" to the set of super
types in the Ecore model instead of setting the genmodel property "Root
Extends Class" = "o.e...Temporal". If I got that wrong I withdraw my
technical comment ;-)
Please see the other thread for comments on using a common infra
structure for EStore integration.
Regards,
Eike Stepper
----
http://wiki.eclipse.org/CDO
http://wiki.eclipse.org/Net4j
jc schrieb:
> Eike wrote:
>
> Technical comment:
> By forcing model developers to subclass a framework type (Temporality) your
> framework becomes invasive to the model. This might not be desirable for all
> models/model developers. With my CDO framework I started the model
> integration the same way (model invasive) and all users came quickly back
> with the question if there was a way to be more transparent. If you are
> interested in the solution I found for this problem we can discuss that
> (preferringly on the newsgroup). May be we are able to factor out a common
> framework to integrate orthogonal functions ionto EMF models.
>
> Conceptual comment/question:
> How do you plan to handle object graphs (as opposed to single instances and
> their attributes)? I guess your Temporality class will offer API to query
> object state of other versions of that object. Does this API return this
> object state as instances of EObject? If so, what will access to the
> reference features deliver? In other words, will it be possible to navigate
> a whole object graph like it had been at any time since creation of that
> graph? Or will it only be possible to query old attribute values?
>
> Eike,
>
> I would like to discuss your solution to removing the invasive (Temporal
> base class). I used this approach to leverage EMFs persistence. Since the
> base class is modeled all of the versions get persisted for free.
>
> So the whole design rests on a modeled Temporal base class and an
> intercepting time aware EStore.
>
> The time (version) aware EStore retrieves the attribute or reference value
> according to the time obtained from the TimeProvider. So when you crawl a
> graph are referenced EObjects the references are the ones for a given time.
> That is you crawl the graph as it looked at a given time.
>
> Thanks
> jc
>
>
>
Cheers
/Eike
----
http://www.esc-net.de
http://thegordian.blogspot.com
http://twitter.com/eikestepper
|
|
| |
Re: [Temporality] Temporality design [message #612963 is a reply to message #105017] |
Fri, 21 December 2007 19:30 |
|
This is a multi-part message in MIME format.
--------------030006070108020504040407
Content-Type: text/plain; charset=ISO-8859-15; format=flowed
Content-Transfer-Encoding: 7bit
jc schrieb:
> You understood correctly. My design requires a Car model to have as a super
> type Temporal. This indicates to the feature that you want Car to be
> temporal and also provides a way to attach modeled version objects to the
> Car. That is the Temporal has a bi-directional reference with a
> VersionHolder EClass.
>
> The other thing the Temporality design requires is a hook in all
> setter/getter which is done in an EStore.
>
> Thoughts?
>
For the EStore integration you need to change the base class of all
modeled root classes to EStoreEObjectImpl (via "Root Extends Class"
genmodel property). Why don't you provide an own subclass of
EStoreEObjectImpl that implements the new API which you can provide via
via "Root Extends Interface" genmodel property? That is want I meant
(and what CDO does do). This way you keep the model free of framework
interfaces.
Regards,
Eike Stepper
----
http://wiki.eclipse.org/CDO
http://wiki.eclipse.org/Net4j
> "Eike Stepper" <stepper@sympedia.de> wrote in message
> news:fkgua1$hj7$1@build.eclipse.org...
>
>> JC,
>>
>> From your proposal I got the impression that you originally planned to let
>> the model developer add an EClass "Temporal" to the set of super types in
>> the Ecore model instead of setting the genmodel property "Root Extends
>> Class" = "o.e...Temporal". If I got that wrong I withdraw my technical
>> comment ;-)
>>
>> Please see the other thread for comments on using a common infra structure
>> for EStore integration.
>>
>> Regards,
>> Eike Stepper
>> ----
>> http://wiki.eclipse.org/CDO
>> http://wiki.eclipse.org/Net4j
>>
>>
>>
>> jc schrieb:
>>
>>> Eike wrote:
>>>
>>> Technical comment:
>>> By forcing model developers to subclass a framework type (Temporality)
>>> your framework becomes invasive to the model. This might not be desirable
>>> for all models/model developers. With my CDO framework I started the
>>> model integration the same way (model invasive) and all users came
>>> quickly back with the question if there was a way to be more transparent.
>>> If you are interested in the solution I found for this problem we can
>>> discuss that (preferringly on the newsgroup). May be we are able to
>>> factor out a common framework to integrate orthogonal functions ionto EMF
>>> models.
>>>
>>> Conceptual comment/question:
>>> How do you plan to handle object graphs (as opposed to single instances
>>> and their attributes)? I guess your Temporality class will offer API to
>>> query object state of other versions of that object. Does this API return
>>> this object state as instances of EObject? If so, what will access to the
>>> reference features deliver? In other words, will it be possible to
>>> navigate a whole object graph like it had been at any time since creation
>>> of that graph? Or will it only be possible to query old attribute values?
>>>
>>> Eike,
>>>
>>> I would like to discuss your solution to removing the invasive (Temporal
>>> base class). I used this approach to leverage EMFs persistence. Since the
>>> base class is modeled all of the versions get persisted for free.
>>>
>>> So the whole design rests on a modeled Temporal base class and an
>>> intercepting time aware EStore.
>>>
>>> The time (version) aware EStore retrieves the attribute or reference
>>> value according to the time obtained from the TimeProvider. So when you
>>> crawl a graph are referenced EObjects the references are the ones for a
>>> given time. That is you crawl the graph as it looked at a given time.
>>>
>>> Thanks
>>> jc
>>>
>>>
>>>
>>>
>
>
>
--------------030006070108020504040407
Content-Type: text/html; charset=ISO-8859-15
Content-Transfer-Encoding: 7bit
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html;charset=ISO-8859-15"
http-equiv="Content-Type">
</head>
<body bgcolor="#ffffff" text="#000000">
jc schrieb:
<blockquote cite="mid:fkh00h$hr4$1@build.eclipse.org" type="cite">
<pre wrap="">You understood correctly. My design requires a Car model to have as a super
type Temporal. This indicates to the feature that you want Car to be
temporal and also provides a way to attach modeled version objects to the
Car. That is the Temporal has a bi-directional reference with a
VersionHolder EClass.
The other thing the Temporality design requires is a hook in all
setter/getter which is done in an EStore.
Thoughts?
</pre>
</blockquote>
For the EStore integration you need to change the base class of all
modeled root classes to EStoreEObjectImpl (via "Root Extends Class"
genmodel property). Why don't you provide an own subclass of
EStoreEObjectImpl that implements the new API which you can provide via
via "Root Extends Interface" genmodel property? That is want I meant
(and what CDO does do). This way you keep the model free of framework
interfaces.<br>
<br>
Regards,<br>
Eike Stepper<br>
----<br>
<a class="moz-txt-link-freetext" href="http://wiki.eclipse.org/CDO">http://wiki.eclipse.org/CDO</a><br>
<a class="moz-txt-link-freetext" href="http://wiki.eclipse.org/Net4j">http://wiki.eclipse.org/Net4j</a><br>
<br>
<br>
<blockquote cite="mid:fkh00h$hr4$1@build.eclipse.org" type="cite">
<pre wrap="">"Eike Stepper" <a class="moz-txt-link-rfc2396E" href="mailto:stepper@sympedia.de"><stepper@sympedia.de></a> wrote in message
<a class="moz-txt-link-freetext" href="news:fkgua1$hj7$1@build.eclipse.org">news:fkgua1$hj7$1@build.eclipse.org</a>...
</pre>
<blockquote type="cite">
<pre wrap="">JC,
From your proposal I got the impression that you originally planned to let
the model developer add an EClass "Temporal" to the set of super types in
the Ecore model instead of setting the genmodel property "Root Extends
Class" = "o.e...Temporal". If I got that wrong I withdraw my technical
comment ;-)
Please see the other thread for comments on using a common infra structure
for EStore integration.
Regards,
Eike Stepper
----
<a class="moz-txt-link-freetext" href="http://wiki.eclipse.org/CDO">http://wiki.eclipse.org/CDO</a>
<a class="moz-txt-link-freetext" href="http://wiki.eclipse.org/Net4j">http://wiki.eclipse.org/Net4j</a>
jc schrieb:
</pre>
<blockquote type="cite">
<pre wrap="">Eike wrote:
Technical comment:
By forcing model developers to subclass a framework type (Temporality)
your framework becomes invasive to the model. This might not be desirable
for all models/model developers. With my CDO framework I started the
model integration the same way (model invasive) and all users came
quickly back with the question if there was a way to be more transparent.
If you are interested in the solution I found for this problem we can
discuss that (preferringly on the newsgroup). May be we are able to
factor out a common framework to integrate orthogonal functions ionto EMF
models.
Conceptual comment/question:
How do you plan to handle object graphs (as opposed to single instances
and their attributes)? I guess your Temporality class will offer API to
query object state of other versions of that object. Does this API return
this object state as instances of EObject? If so, what will access to the
reference features deliver? In other words, will it be possible to
navigate a whole object graph like it had been at any time since creation
of that graph? Or will it only be possible to query old attribute values?
Eike,
I would like to discuss your solution to removing the invasive (Temporal
base class). I used this approach to leverage EMFs persistence. Since the
base class is modeled all of the versions get persisted for free.
So the whole design rests on a modeled Temporal base class and an
intercepting time aware EStore.
The time (version) aware EStore retrieves the attribute or reference
value according to the time obtained from the TimeProvider. So when you
crawl a graph are referenced EObjects the references are the ones for a
given time. That is you crawl the graph as it looked at a given time.
Thanks
jc
</pre>
</blockquote>
</blockquote>
<pre wrap=""><!---->
</pre>
</blockquote>
</body>
</html>
--------------030006070108020504040407--
Cheers
/Eike
----
http://www.esc-net.de
http://thegordian.blogspot.com
http://twitter.com/eikestepper
|
|
| |
Re: [Temporality] Temporality design [message #612982 is a reply to message #105026] |
Sun, 23 December 2007 10:00 |
|
Jean-Claude schrieb:
> I'm a bit new to EMF so please bear with me if I say things that are
> not quite accurate.
>
> I realize users might not like to have to add a super type from the
> framework to every one of the types you want persisted in CDO or for
> every type you want Temporal etc.
>
> I understand how using a "Root Extends Class" in the genmodel is
> easier to specify for a user then having to do that. Also I understand
> how using such a EObject base class provides a way to "attach" CDO's
> API to every EObject.
>
> However I find using the "Root Extends Class" approach blocks other
> features from augmenting the EObject API. Two features depending on
> this technique will not work together. Is this correct?
Yes, that's why I suggested that we take a step back and see if we can
come up with a proposal of a common base class that can be used with
multiple technical features (one at a time). This base class would be a
subclass of EStoreEObjectImpl. Although it would probably not permit to
install multiple features at runtime it would free the developer from
selecting one feature (thereby excluding the others) at generation time.
I'm not sure if it will be possible at all but an attempt to consolidate
our store integrations could yield interesting results.
> I would rather use a modeled super type (with "method body"
> annotations) and rely on the code generator to "attach" my API to
> every EObject by injecting the method and method bodies into every
> generated EObject.
>
> It is true that I still need a "Root Extends Class" to plug my EStore
> hook and that again two features depending on this technique will not
> work together. But I believe this is a limitation of the EMF framework
> that should be address so that many features can play nice together.
"Root Extends Class" is a very powerful and very general mechanism. I
guess not all "RootExtenders" are delegating to an EStore and not all
RootExtenders that do delegate to an EStore will be able to use a common
root class. I believe it's the existance of certain requirements that
could open the door for such consolidation, requirements like the often
cited "pre-event hooks in getters and setters".
May be it's best that we wait until you come up with working code for
your problem and then look if we can factor out such a common base
class. On the other hand it could be useful for you to see how the
CDOStore (implements EStore) is working and what was necessary in the
CDOObjectImpl (extends EStoreEObjectImpl) to make it work with that store:
-
http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.emf/org .eclipse.emf.cdo/plugins/org.eclipse.emf.cdo/src/org/eclipse /emf/internal/cdo/CDOStore.java?root=Modeling_Project&vi ew=markup
-
http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.emf/org .eclipse.emf.cdo/plugins/org.eclipse.emf.cdo/src/org/eclipse /emf/internal/cdo/CDOObjectImpl.java?root=Modeling_Project&a mp;view=markup
> [Bug 197487] Provide stateless EstoreEList and EStoreFeatureMap base
> classes.
>
> What was the main concern of the users with having to add a super type
> from the framework? Was it the inconvenience of having to go through
> every type and add the super type?
Partly, although I had a migrator tool that performed this task
automatically. I think it's more a conceptual issue with the *core*
model being abused for model-unrelated things/features. In anology (I
hope) you seldom hear users complaining about the inconvenience of
maintaining a separate genmodel. They know that the (E) core model
should be as close to their business domain as possible and free of
technical features.
> I really appreciate your comments Eike. As I said I'm new to EMF so I
> need these feedback to help me nail down the Temporality feature
> correctly.
Great. To be honest I'm really not sure if we'll manage to identify
concrete potential for "store integration consolidation" but I think
that the discussion is interesting for both of us.
> BTW: How do other features plug themselves into EMF? Do they mostly
> use the EMF adapters/observers?
I can only guess but I think the better features are doing whatever is
feasible and appropriate for them to fulfill their requirements. Smart
answer, eh? ;-)
Regards,
Eike Stepper
----
http://wiki.eclipse.org/CDO
http://wiki.eclipse.org/Net4j
Cheers
/Eike
----
http://www.esc-net.de
http://thegordian.blogspot.com
http://twitter.com/eikestepper
|
|
|
Re: [Temporality] Temporality design [message #612987 is a reply to message #105027] |
Sun, 23 December 2007 12:17 |
Ed Merks Messages: 33217 Registered: July 2009 |
Senior Member |
|
|
Guys,
It's nice to see the newsgroup being used for open design discussions!
My 2 cents below.
Eike Stepper wrote:
> Jean-Claude schrieb:
>> I'm a bit new to EMF so please bear with me if I say things that are
>> not quite accurate.
>>
>> I realize users might not like to have to add a super type from the
>> framework to every one of the types you want persisted in CDO or for
>> every type you want Temporal etc.
>>
>> I understand how using a "Root Extends Class" in the genmodel is
>> easier to specify for a user then having to do that. Also I
>> understand how using such a EObject base class provides a way to
>> "attach" CDO's API to every EObject.
>>
>> However I find using the "Root Extends Class" approach blocks other
>> features from augmenting the EObject API. Two features depending on
>> this technique will not work together. Is this correct?
> Yes, that's why I suggested that we take a step back and see if we can
> come up with a proposal of a common base class that can be used with
> multiple technical features (one at a time). This base class would be
> a subclass of EStoreEObjectImpl. Although it would probably not permit
> to install multiple features at runtime it would free the developer
> from selecting one feature (thereby excluding the others) at
> generation time. I'm not sure if it will be possible at all but an
> attempt to consolidate our store integrations could yield interesting
> results.
With regard to root extends interface and root extends class. These are
quite useful for a number of reasons but one thing they are not good for
is if these things really want to introduce modeled
EStructuralFeatures. Such things must be part of the known EClass
hierarchy. One aspect of how these can be used that I'm sure is totally
not obvious but is very powerful is root implements interface, which for
SDO you can see is set to InternalEDataObject. If you look in the
SDO.ecore model for what's in the hierarchy of this you'll see it
specifies all kinds of EOperations with actual method body annotations.
As a result, if you are extending a non data object XyzImpl (one that
doesn't extend the EDataObjectImpl root extends class), the methods
bodies form the root implements interface will be generated into the
generated derived class. In this way, additional API implementations
can be mixed into an established hierarchy without requiring the use of
a specific base class.
>
>> I would rather use a modeled super type (with "method body"
>> annotations) and rely on the code generator to "attach" my API to
>> every EObject by injecting the method and method bodies into every
>> generated EObject.
>>
>> It is true that I still need a "Root Extends Class" to plug my EStore
>> hook and that again two features depending on this technique will not
>> work together. But I believe this is a limitation of the EMF
>> framework that should be address so that many features can play nice
>> together.
> "Root Extends Class" is a very powerful and very general mechanism. I
> guess not all "RootExtenders" are delegating to an EStore and not all
> RootExtenders that do delegate to an EStore will be able to use a
> common root class. I believe it's the existance of certain
> requirements that could open the door for such consolidation,
> requirements like the often cited "pre-event hooks in getters and
> setters".
>
> May be it's best that we wait until you come up with working code for
> your problem and then look if we can factor out such a common base
> class. On the other hand it could be useful for you to see how the
> CDOStore (implements EStore) is working and what was necessary in the
> CDOObjectImpl (extends EStoreEObjectImpl) to make it work with that
> store:
Often the idea is to have both a base class and a root implements
interface with method bodies that can be used to mix in what's in the
base class. Of course right now we only have the ability to mix in
method bodies, and not stateful fields, but if use cases require them, I
could imagine adding some type of support for them (perhaps by having
something similar to <%a.b.C%> which does an import but instead would be
used to inject field declarations in the containing class.
>
> -
> http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.emf/org .eclipse.emf.cdo/plugins/org.eclipse.emf.cdo/src/org/eclipse /emf/internal/cdo/CDOStore.java?root=Modeling_Project&vi ew=markup
>
>
> -
> http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.emf/org .eclipse.emf.cdo/plugins/org.eclipse.emf.cdo/src/org/eclipse /emf/internal/cdo/CDOObjectImpl.java?root=Modeling_Project&a mp;view=markup
>
>
>> [Bug 197487] Provide stateless EstoreEList and EStoreFeatureMap base
>> classes.
>>
>> What was the main concern of the users with having to add a super
>> type from the framework? Was it the inconvenience of having to go
>> through every type and add the super type?
> Partly, although I had a migrator tool that performed this task
> automatically. I think it's more a conceptual issue with the *core*
> model being abused for model-unrelated things/features. In anology (I
> hope) you seldom hear users complaining about the inconvenience of
> maintaining a separate genmodel. They know that the (E) core model
> should be as close to their business domain as possible and free of
> technical features.
>
>> I really appreciate your comments Eike. As I said I'm new to EMF so I
>> need these feedback to help me nail down the Temporality feature
>> correctly.
> Great. To be honest I'm really not sure if we'll manage to identify
> concrete potential for "store integration consolidation" but I think
> that the discussion is interesting for both of us.
And for me too.
>
>> BTW: How do other features plug themselves into EMF? Do they mostly
>> use the EMF adapters/observers?
> I can only guess but I think the better features are doing whatever is
> feasible and appropriate for them to fulfill their requirements. Smart
> answer, eh? ;-)
Generally the lest obtrusive something is in terms of impact on
generated code the more likely it can be reused broadly. Certainly
read hooks are a common source of "incompatibilities" because the basic
generation pattern simply has no read hooks and adding anything to a
method that simply returns a variable has a dramatic impact on
performance; you just can't beat "X foo() { return x; }" in terms of
performance and even the most minor addition, particularly a call to any
other method, can have an order of magnitude impact...
>
> Regards,
> Eike Stepper
> ----
> http://wiki.eclipse.org/CDO
> http://wiki.eclipse.org/Net4j
Ed Merks
Professional Support: https://www.macromodeling.com/
|
|
|
Re: [Temporality] Temporality design [message #613001 is a reply to message #105087] |
Tue, 25 December 2007 17:11 |
Jean-Claude Cote Messages: 56 Registered: July 2009 |
Member |
|
|
Ed Merks wrote:
> Guys,
> It's nice to see the newsgroup being used for open design discussions!
> My 2 cents below.
> Eike Stepper wrote:
>> Jean-Claude schrieb:
>>> I'm a bit new to EMF so please bear with me if I say things that are
>>> not quite accurate.
>>>
>>> I realize users might not like to have to add a super type from the
>>> framework to every one of the types you want persisted in CDO or for
>>> every type you want Temporal etc.
>>>
>>> I understand how using a "Root Extends Class" in the genmodel is
>>> easier to specify for a user then having to do that. Also I
>>> understand how using such a EObject base class provides a way to
>>> "attach" CDO's API to every EObject.
>>>
>>> However I find using the "Root Extends Class" approach blocks other
>>> features from augmenting the EObject API. Two features depending on
>>> this technique will not work together. Is this correct?
>> Yes, that's why I suggested that we take a step back and see if we can
>> come up with a proposal of a common base class that can be used with
>> multiple technical features (one at a time). This base class would be
>> a subclass of EStoreEObjectImpl. Although it would probably not permit
>> to install multiple features at runtime it would free the developer
>> from selecting one feature (thereby excluding the others) at
>> generation time. I'm not sure if it will be possible at all but an
>> attempt to consolidate our store integrations could yield interesting
>> results.
> With regard to root extends interface and root extends class. These are
> quite useful for a number of reasons but one thing they are not good for
> is if these things really want to introduce modeled
> EStructuralFeatures. Such things must be part of the known EClass
> hierarchy. One aspect of how these can be used that I'm sure is totally
> not obvious but is very powerful is root implements interface, which for
> SDO you can see is set to InternalEDataObject. If you look in the
> SDO.ecore model for what's in the hierarchy of this you'll see it
> specifies all kinds of EOperations with actual method body annotations.
> As a result, if you are extending a non data object XyzImpl (one that
> doesn't extend the EDataObjectImpl root extends class), the methods
> bodies form the root implements interface will be generated into the
> generated derived class. In this way, additional API implementations
> can be mixed into an established hierarchy without requiring the use of
> a specific base class.
I did not know of this feature of the GenModel. I like the idea very much.
It's a nice way to mix-in implementation into generated code without
having to declare it explicitly in your model. However after playing with
it a bit it appears to me that it only will inject methods into modeled
types that have super types from other .ecore files.
public class ClassWithMethodsToInjectImpl extends EObjectImpl implements
ClassWithMethodsToInject {
...
public void operation1() {
/* body goes here */
}
public class ReceivingClassImpl extends EObjectImpl implements
ReceivingClass {
public class SubClassOfReceivingClassImpl extends ReceivingClassImpl
implements SubClassOfReceivingClass {
public class SubOfExternalImpl extends AnyTypeImpl implements
SubOfExternal, ClassWithMethodsToInject {
...
public void operation1() {
/* body goes here */
}
>>
>>> I would rather use a modeled super type (with "method body"
>>> annotations) and rely on the code generator to "attach" my API to
>>> every EObject by injecting the method and method bodies into every
>>> generated EObject.
>>>
>>> It is true that I still need a "Root Extends Class" to plug my EStore
>>> hook and that again two features depending on this technique will not
>>> work together. But I believe this is a limitation of the EMF
>>> framework that should be address so that many features can play nice
>>> together.
>> "Root Extends Class" is a very powerful and very general mechanism. I
>> guess not all "RootExtenders" are delegating to an EStore and not all
>> RootExtenders that do delegate to an EStore will be able to use a
>> common root class. I believe it's the existance of certain
>> requirements that could open the door for such consolidation,
>> requirements like the often cited "pre-event hooks in getters and
>> setters".
>>
>> May be it's best that we wait until you come up with working code for
>> your problem and then look if we can factor out such a common base
>> class. On the other hand it could be useful for you to see how the
>> CDOStore (implements EStore) is working and what was necessary in the
>> CDOObjectImpl (extends EStoreEObjectImpl) to make it work with that
>> store:
I have the basic functionality already working. I just need to put in in
the CVS repository. I'm reading up on the whole process of setting up
these projects for the build host etc. Once I have this uploaded I think
it will be easier for us to discuss these details.
> Often the idea is to have both a base class and a root implements
> interface with method bodies that can be used to mix in what's in the
> base class. Of course right now we only have the ability to mix in
> method bodies, and not stateful fields, but if use cases require them, I
> could imagine adding some type of support for them (perhaps by having
> something similar to <%a.b.C%> which does an import but instead would be
> used to inject field declarations in the containing class.
>>
>> -
>>
http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.emf/org .eclipse.emf.cdo/plugins/org.eclipse.emf.cdo/src/org/eclipse /emf/internal/cdo/CDOStore.java?root=Modeling_Project&vi ew=markup
>>
>>
>> -
>>
http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.emf/org .eclipse.emf.cdo/plugins/org.eclipse.emf.cdo/src/org/eclipse /emf/internal/cdo/CDOObjectImpl.java?root=Modeling_Project&a mp;view=markup
>>
>>
>>> [Bug 197487] Provide stateless EstoreEList and EStoreFeatureMap base
>>> classes.
>>>
>>> What was the main concern of the users with having to add a super
>>> type from the framework? Was it the inconvenience of having to go
>>> through every type and add the super type?
>> Partly, although I had a migrator tool that performed this task
>> automatically. I think it's more a conceptual issue with the *core*
>> model being abused for model-unrelated things/features. In anology (I
>> hope) you seldom hear users complaining about the inconvenience of
>> maintaining a separate genmodel. They know that the (E) core model
>> should be as close to their business domain as possible and free of
>> technical features.
>>
>>> I really appreciate your comments Eike. As I said I'm new to EMF so I
>>> need these feedback to help me nail down the Temporality feature
>>> correctly.
>> Great. To be honest I'm really not sure if we'll manage to identify
>> concrete potential for "store integration consolidation" but I think
>> that the discussion is interesting for both of us.
> And for me too.
>>
>>> BTW: How do other features plug themselves into EMF? Do they mostly
>>> use the EMF adapters/observers?
>> I can only guess but I think the better features are doing whatever is
>> feasible and appropriate for them to fulfill their requirements. Smart
>> answer, eh? ;-)
> Generally the lest obtrusive something is in terms of impact on
> generated code the more likely it can be reused broadly. Certainly
> read hooks are a common source of "incompatibilities" because the basic
> generation pattern simply has no read hooks and adding anything to a
> method that simply returns a variable has a dramatic impact on
> performance; you just can't beat "X foo() { return x; }" in terms of
> performance and even the most minor addition, particularly a call to any
> other method, can have an order of magnitude impact...
>>
>> Regards,
>> Eike Stepper
>> ----
>> http://wiki.eclipse.org/CDO
>> http://wiki.eclipse.org/Net4j
|
|
|
Re: [Temporality] Temporality design [message #613007 is a reply to message #105197] |
Wed, 26 December 2007 12:01 |
Ed Merks Messages: 33217 Registered: July 2009 |
Senior Member |
|
|
Jean-Claude,
Keep in mind that when a Root Implements Interface or a Root Extends
Interface is specified, the generator assumes that the Root Extends
Class implements the full API for both (I think it checks that it's
different from EObjectImpl as well). So typically you'd have a model in
which you extend EObject explicitly so as to mix in the additional API
(like EDataObjectImpl in SDO) and then other models would use that
(EDataObjectImpl) as the Root Extends Class; this avoids generating lots
of methods in lots of models by having a single root that already
implements them. Of course once a base class has implemented this API,
there's no need to mix it in again in derived classes of that base
class; perhaps that's what you are observing with your comment about
extending a class from a different model? (The generator checks if the
base model specifies a different Root Implements interface which tells
it whether it needs to mix that in.)
Jean-Claude wrote:
> Ed Merks wrote:
>
>> Guys,
>
>> It's nice to see the newsgroup being used for open design
>> discussions! My 2 cents below.
>
>> Eike Stepper wrote:
>>> Jean-Claude schrieb:
>>>> I'm a bit new to EMF so please bear with me if I say things that
>>>> are not quite accurate.
>>>>
>>>> I realize users might not like to have to add a super type from the
>>>> framework to every one of the types you want persisted in CDO or
>>>> for every type you want Temporal etc.
>>>>
>>>> I understand how using a "Root Extends Class" in the genmodel is
>>>> easier to specify for a user then having to do that. Also I
>>>> understand how using such a EObject base class provides a way to
>>>> "attach" CDO's API to every EObject.
>>>>
>>>> However I find using the "Root Extends Class" approach blocks other
>>>> features from augmenting the EObject API. Two features depending on
>>>> this technique will not work together. Is this correct?
>>> Yes, that's why I suggested that we take a step back and see if we
>>> can come up with a proposal of a common base class that can be used
>>> with multiple technical features (one at a time). This base class
>>> would be a subclass of EStoreEObjectImpl. Although it would probably
>>> not permit to install multiple features at runtime it would free the
>>> developer from selecting one feature (thereby excluding the others)
>>> at generation time. I'm not sure if it will be possible at all but
>>> an attempt to consolidate our store integrations could yield
>>> interesting results.
>> With regard to root extends interface and root extends class. These
>> are quite useful for a number of reasons but one thing they are not
>> good for is if these things really want to introduce modeled
>> EStructuralFeatures. Such things must be part of the known EClass
>> hierarchy. One aspect of how these can be used that I'm sure is
>> totally not obvious but is very powerful is root implements
>> interface, which for SDO you can see is set to InternalEDataObject.
>> If you look in the SDO.ecore model for what's in the hierarchy of
>> this you'll see it specifies all kinds of EOperations with actual
>> method body annotations. As a result, if you are extending a non
>> data object XyzImpl (one that doesn't extend the EDataObjectImpl root
>> extends class), the methods bodies form the root implements interface
>> will be generated into the generated derived class. In this way,
>> additional API implementations can be mixed into an established
>> hierarchy without requiring the use of a specific base class.
>
> I did not know of this feature of the GenModel. I like the idea very
> much. It's a nice way to mix-in implementation into generated code
> without having to declare it explicitly in your model. However after
> playing with it a bit it appears to me that it only will inject
> methods into modeled types that have super types from other .ecore files.
>
> public class ClassWithMethodsToInjectImpl extends EObjectImpl
> implements ClassWithMethodsToInject {
> ..
> public void operation1() {
> /* body goes here */
> }
>
> public class ReceivingClassImpl extends EObjectImpl implements
> ReceivingClass {
>
> public class SubClassOfReceivingClassImpl extends ReceivingClassImpl
> implements SubClassOfReceivingClass {
>
> public class SubOfExternalImpl extends AnyTypeImpl implements
> SubOfExternal, ClassWithMethodsToInject {
> ..
> public void operation1() {
> /* body goes here */
> }
>
>
>
>>>
>>>> I would rather use a modeled super type (with "method body"
>>>> annotations) and rely on the code generator to "attach" my API to
>>>> every EObject by injecting the method and method bodies into every
>>>> generated EObject.
>>>>
>>>> It is true that I still need a "Root Extends Class" to plug my
>>>> EStore hook and that again two features depending on this technique
>>>> will not work together. But I believe this is a limitation of the
>>>> EMF framework that should be address so that many features can play
>>>> nice together.
>>> "Root Extends Class" is a very powerful and very general mechanism.
>>> I guess not all "RootExtenders" are delegating to an EStore and not
>>> all RootExtenders that do delegate to an EStore will be able to use
>>> a common root class. I believe it's the existance of certain
>>> requirements that could open the door for such consolidation,
>>> requirements like the often cited "pre-event hooks in getters and
>>> setters".
>>>
>>> May be it's best that we wait until you come up with working code
>>> for your problem and then look if we can factor out such a common
>>> base class. On the other hand it could be useful for you to see how
>>> the CDOStore (implements EStore) is working and what was necessary
>>> in the CDOObjectImpl (extends EStoreEObjectImpl) to make it work
>>> with that store:
> I have the basic functionality already working. I just need to put in
> in the CVS repository. I'm reading up on the whole process of setting
> up these projects for the build host etc. Once I have this uploaded I
> think it will be easier for us to discuss these details.
>
>> Often the idea is to have both a base class and a root implements
>> interface with method bodies that can be used to mix in what's in the
>> base class. Of course right now we only have the ability to mix in
>> method bodies, and not stateful fields, but if use cases require
>> them, I could imagine adding some type of support for them (perhaps
>> by having something similar to <%a.b.C%> which does an import but
>> instead would be used to inject field declarations in the containing
>> class.
>>>
>>> -
> http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.emf/org .eclipse.emf.cdo/plugins/org.eclipse.emf.cdo/src/org/eclipse /emf/internal/cdo/CDOStore.java?root=Modeling_Project&vi ew=markup
>
>>>
>>>
>>> -
> http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.emf/org .eclipse.emf.cdo/plugins/org.eclipse.emf.cdo/src/org/eclipse /emf/internal/cdo/CDOObjectImpl.java?root=Modeling_Project&a mp;view=markup
>
>>>
>>>
>>>> [Bug 197487] Provide stateless EstoreEList and EStoreFeatureMap
>>>> base classes.
>>>>
>>>> What was the main concern of the users with having to add a super
>>>> type from the framework? Was it the inconvenience of having to go
>>>> through every type and add the super type?
>>> Partly, although I had a migrator tool that performed this task
>>> automatically. I think it's more a conceptual issue with the *core*
>>> model being abused for model-unrelated things/features. In anology
>>> (I hope) you seldom hear users complaining about the inconvenience
>>> of maintaining a separate genmodel. They know that the (E) core
>>> model should be as close to their business domain as possible and
>>> free of technical features.
>>>
>>>> I really appreciate your comments Eike. As I said I'm new to EMF so
>>>> I need these feedback to help me nail down the Temporality feature
>>>> correctly.
>>> Great. To be honest I'm really not sure if we'll manage to identify
>>> concrete potential for "store integration consolidation" but I think
>>> that the discussion is interesting for both of us.
>> And for me too.
>>>
>>>> BTW: How do other features plug themselves into EMF? Do they mostly
>>>> use the EMF adapters/observers?
>>> I can only guess but I think the better features are doing whatever
>>> is feasible and appropriate for them to fulfill their requirements.
>>> Smart answer, eh? ;-)
>> Generally the lest obtrusive something is in terms of impact on
>> generated code the more likely it can be reused broadly. Certainly
>> read hooks are a common source of "incompatibilities" because the
>> basic generation pattern simply has no read hooks and adding anything
>> to a method that simply returns a variable has a dramatic impact on
>> performance; you just can't beat "X foo() { return x; }" in terms of
>> performance and even the most minor addition, particularly a call to
>> any other method, can have an order of magnitude impact...
>>>
>>> Regards,
>>> Eike Stepper
>>> ----
>>> http://wiki.eclipse.org/CDO
>>> http://wiki.eclipse.org/Net4j
>
>
Ed Merks
Professional Support: https://www.macromodeling.com/
|
|
| |
Re: [Temporality] Temporality design [message #613010 is a reply to message #105251] |
Wed, 26 December 2007 16:33 |
Ed Merks Messages: 33217 Registered: July 2009 |
Senior Member |
|
|
Jean-Claude,
Have a look at SDO.genmodel itself and at what happens when you invoke
Set SDO Defaults in the GenModel. The expectation is that you typically
set both the Root Extends Class (which implements the Root Implements
Interface already) and the Root Implements Interface and that the mixing
behavior is needed only if you extend a class from a model with a
different Root Extends Class...
And no, you can't specify multiple. You'll need to define one that in
turn extends all the other ones you'd like to combine.
Jean-Claude wrote:
> I see you have to explicitly extend something from another genmodel in
> order for the code generator to mix-in the operations from the "Root
> Implements Interface". I'm going to make different scenarios and post
> them here.
>
> BTW: Can I specify multiple "Root Implements Interface" ? I tried
> different seperators but none worked so far.
>
> thanks
> Jean-Claude
>
>
Ed Merks
Professional Support: https://www.macromodeling.com/
|
|
|
Re: [Temporality] Temporality design [message #613023 is a reply to message #105265] |
Thu, 27 December 2007 11:44 |
|
Ed Merks schrieb:
> Jean-Claude,
>
> Have a look at SDO.genmodel itself and at what happens when you invoke
> Set SDO Defaults in the GenModel. The expectation is that you
> typically set both the Root Extends Class (which implements the Root
> Implements Interface already) and the Root Implements Interface and
> that the mixing behavior is needed only if you extend a class from a
> model with a different Root Extends Class...
>
> And no, you can't specify multiple. You'll need to define one that in
> turn extends all the other ones you'd like to combine.
That's what I'm doing for CDO, too, in order to generate a Resource
implementation that's a CDOObject as well:
public interface EresourceObject extends CDOObject, Resource.Internal
{
}
I'm using EresourceObject as Root Extends Interface in the genmodel.
Regards,
Eike Stepper
----
http://wiki.eclipse.org/CDO
http://wiki.eclipse.org/Net4j
>
>
> Jean-Claude wrote:
>> I see you have to explicitly extend something from another genmodel
>> in order for the code generator to mix-in the operations from the
>> "Root Implements Interface". I'm going to make different scenarios
>> and post them here.
>>
>> BTW: Can I specify multiple "Root Implements Interface" ? I tried
>> different seperators but none worked so far.
>>
>> thanks
>> Jean-Claude
>>
>>
Cheers
/Eike
----
http://www.esc-net.de
http://thegordian.blogspot.com
http://twitter.com/eikestepper
|
|
| |
Goto Forum:
Current Time: Tue Sep 24 04:06:43 GMT 2024
Powered by FUDForum. Page generated in 0.05434 seconds
|