Home » Modeling » TMF (Xtext) » Processing ecore with non-containment references
Processing ecore with non-containment references [message #54590] |
Wed, 01 July 2009 21:54  |
Eclipse User |
|
|
|
I'm doing a lot of conversion on a grammer into a native ecore model.
The ideas Sven gave in
http://dev.eclipse.org/newslists/news.eclipse.modeling.tmf/m sg00403.html
worked well for a lot of issues, but here's one I haven't been able to
solve.
I have an ecore model in which it is much more natural to create it and
the grammer using non-containment references. But if I try this that
means that the non-contained EObjects are removed at some very early
stage of processing; that is, they don't show up in the linking stage
as far as I can tell. Is there any hook point to get such references
objects and add the to an appropriate container?
cheers,
Miles
|
|
| |
Re: Processing ecore with non-containment references [message #54788 is a reply to message #54761] |
Thu, 02 July 2009 14:58   |
Eclipse User |
|
|
|
Thanks Sebastian,
I'm not entirely sure that it can't be done with Linker but I haven't
been able to get to a point where I can get this state. But perhaps
I've missed something.
Imagine I want to define a rooted Graph Struture but I need to create
the nodes implicitly as part of the edges. This is part of a referenced
ecore model which is like:
Graph:
ref members [edges] (containment)
ref roots [edges] (non-containment 0..*)
Edge:
ref sources [edges] (non-containment obviously 0..*)
ref targets [edges] (non-containment obviously 0..*)
And I want to define grammer like (Ithis may not be a good grammer I
haven't tested it, but just to get the idea):
XGraph returns Graph :
roots+=[Edge];
XEdge returns Edge :
targets+=([Edge] | Edge)
Now, when the model is saved, I need to gather all of the roots and
targets and add them to members so that they are contained. Does that
make sense?
I know its possible to make the grammer work (I've already done it) by
adding a bunch of intermediate rules, but that is really not very
transparant and it hard to maintain.
thanks,
Miles
On 2009-07-02 10:47:13 -0700, Sebastian Zarnekow
<Sebastian.Zarnekow@itemis.de> said:
> Hi Miles,
>
> no there is no such hook.
> Maybe you want to describe what you originally wanted to achieve. I
> guess there is a solution, that should work with Xtext.
>
> Regards,
> Sebastian
>
> Am 02.07.2009 3:54 Uhr, schrieb Miles Parker:
>>
>> I'm doing a lot of conversion on a grammer into a native ecore model.
>> The ideas Sven gave in
>> http://dev.eclipse.org/newslists/news.eclipse.modeling.tmf/m sg00403.html
>> worked well for a lot of issues, but here's one I haven't been able to
>> solve.
>>
>> I have an ecore model in which it is much more natural to create it and
>> the grammer using non-containment references. But if I try this that
>> means that the non-contained EObjects are removed at some very early
>> stage of processing; that is, they don't show up in the linking stage as
>> far as I can tell. Is there any hook point to get such references
>> objects and add the to an appropriate container?
>>
>> cheers,
>>
>> Miles
|
|
| |
Re: Processing ecore with non-containment references [message #54842 is a reply to message #54788] |
Thu, 02 July 2009 15:13   |
Eclipse User |
|
|
|
Hi Miles,
so you only have edges but no vertices or someting alike?
Can you please post a short snippet of the concrete syntax, that you'ld
like to use? Currently I cannot imagine how it should look like.
However, your usecase seems to be a good fit for m2m transformations,
because instances of your Ecore model will likely not be created by a
concise textual notation with Xtext. Or you do all the linking yourself
and create kind of intermediate instances in the parser parsing (as you
already did). But that's m2m, too.
Regards,
Sebastian
Am 02.07.2009 20:58 Uhr, schrieb Miles Parker:
> Thanks Sebastian,
>
> I'm not entirely sure that it can't be done with Linker but I haven't
> been able to get to a point where I can get this state. But perhaps I've
> missed something.
>
> Imagine I want to define a rooted Graph Struture but I need to create
> the nodes implicitly as part of the edges. This is part of a referenced
> ecore model which is like:
>
> Graph:
> ref members [edges] (containment)
> ref roots [edges] (non-containment 0..*)
>
> Edge:
> ref sources [edges] (non-containment obviously 0..*)
> ref targets [edges] (non-containment obviously 0..*)
>
> And I want to define grammer like (Ithis may not be a good grammer I
> haven't tested it, but just to get the idea):
>
> XGraph returns Graph :
> roots+=[Edge];
>
> XEdge returns Edge :
> targets+=([Edge] | Edge)
>
>
> Now, when the model is saved, I need to gather all of the roots and
> targets and add them to members so that they are contained. Does that
> make sense?
>
> I know its possible to make the grammer work (I've already done it) by
> adding a bunch of intermediate rules, but that is really not very
> transparant and it hard to maintain.
>
> thanks,
>
> Miles
>
>
> On 2009-07-02 10:47:13 -0700, Sebastian Zarnekow
> <Sebastian.Zarnekow@itemis.de> said:
>
>> Hi Miles,
>>
>> no there is no such hook.
>> Maybe you want to describe what you originally wanted to achieve. I
>> guess there is a solution, that should work with Xtext.
>>
>> Regards,
>> Sebastian
>>
>> Am 02.07.2009 3:54 Uhr, schrieb Miles Parker:
>>>
>>> I'm doing a lot of conversion on a grammer into a native ecore model.
>>> The ideas Sven gave in
>>> http://dev.eclipse.org/newslists/news.eclipse.modeling.tmf/m sg00403.html
>>> worked well for a lot of issues, but here's one I haven't been able to
>>> solve.
>>>
>>> I have an ecore model in which it is much more natural to create it and
>>> the grammer using non-containment references. But if I try this that
>>> means that the non-contained EObjects are removed at some very early
>>> stage of processing; that is, they don't show up in the linking stage as
>>> far as I can tell. Is there any hook point to get such references
>>> objects and add the to an appropriate container?
>>>
>>> cheers,
>>>
>>> Miles
>
>
|
|
|
Re: Processing ecore with non-containment references [message #54869 is a reply to message #54842] |
Thu, 02 July 2009 15:32   |
Eclipse User |
|
|
|
On 2009-07-02 12:13:02 -0700, Sebastian Zarnekow
<Sebastian.Zarnekow@itemis.de> said:
> Hi Miles,
>
> so you only have edges but no vertices or someting alike?
> Can you please post a short snippet of the concrete syntax, that you'ld
> like to use? Currently I cannot imagine how it should look like.
Well this is an example, but yes it would have been a better example to
just use nodes instead of edges. :)
> However, your usecase seems to be a good fit for m2m transformations,
> because instances of your Ecore model will likely not be created by a
> concise textual notation with Xtext. Or you do all the linking yourself
> and create kind of intermediate instances in the parser parsing (as you
> already did). But that's m2m, too.
Yes, that's exactly what I'm doing. But the problem is that I don't
have access to the intermediate instances because they are getting
erased from the tree. I'm assuming that this is because they aren't
contained somehwere..? If I could make that work then I'd have a much
more concise xtext side representation. As you can see its already
complex enough and this is only about 20% of it!
Here is the concrete syntax:
Agent returns SAgent:
ID=IDZ
("HAS" attributes+=Attributes ("," attributes+=Attributes)*".")?
("SHOWS" styles+=Style2D ("," styles+=Style2D)*".")?
rootActivity=Behaviors;
Behaviors returns AGroup :
("DOES" members+=RootRule (";" (members+=RootRule))*".")?"!";
RootRule returns ARoot :
(Rule | Watch | Initialize | Build) "::" ("[" targets+=NonRoot (","
(targets+=NonRoot))* "]")?;
Rule returns ARule :
ID=IDZ ("IN" space=[SProjection|IDZ])?;
NonRoot returns AAct :
Select | Create | CreateProjection;
Select returns ASelect :
(selected=[ASelect|IDZ]"::")?ID=IDZ "SELECTS" agent=[SAgent|IDZ] "IN"
space=[SProjection|IDZ] "WHERE" targets+=Query ("AND" targets+=Query)*;
Queries are just further nodes in the tree. As you can probably
imagine, the way I've been doing this with containment references
requires a lot of indirection between the two models.
thanks,
Miles
>
> Regards,
> Sebastian
>
>
> Am 02.07.2009 20:58 Uhr, schrieb Miles Parker:
>> Thanks Sebastian,
>>
>> I'm not entirely sure that it can't be done with Linker but I haven't
>> been able to get to a point where I can get this state. But perhaps I've
>> missed something.
>>
>> Imagine I want to define a rooted Graph Struture but I need to create
>> the nodes implicitly as part of the edges. This is part of a referenced
>> ecore model which is like:
>>
>> Graph:
>> ref members [edges] (containment)
>> ref roots [edges] (non-containment 0..*)
>>
>> Edge:
>> ref sources [edges] (non-containment obviously 0..*)
>> ref targets [edges] (non-containment obviously 0..*)
>>
>> And I want to define grammer like (Ithis may not be a good grammer I
>> haven't tested it, but just to get the idea):
>>
>> XGraph returns Graph :
>> roots+=[Edge];
>>
>> XEdge returns Edge :
>> targets+=([Edge] | Edge)
>>
>>
>> Now, when the model is saved, I need to gather all of the roots and
>> targets and add them to members so that they are contained. Does that
>> make sense?
>>
>> I know its possible to make the grammer work (I've already done it) by
>> adding a bunch of intermediate rules, but that is really not very
>> transparant and it hard to maintain.
>>
>> thanks,
>>
>> Miles
>>
>>
>> On 2009-07-02 10:47:13 -0700, Sebastian Zarnekow
>> <Sebastian.Zarnekow@itemis.de> said:
>>
>>> Hi Miles,
>>>
>>> no there is no such hook.
>>> Maybe you want to describe what you originally wanted to achieve. I
>>> guess there is a solution, that should work with Xtext.
>>>
>>> Regards,
>>> Sebastian
>>>
>>> Am 02.07.2009 3:54 Uhr, schrieb Miles Parker:
>>>>
>>>> I'm doing a lot of conversion on a grammer into a native ecore model.
>>>> The ideas Sven gave in
>>>> http://dev.eclipse.org/newslists/news.eclipse.modeling.tmf/m sg00403.html
>>>> worked well for a lot of issues, but here's one I haven't been able to
>>>> solve.
>>>>
>>>> I have an ecore model in which it is much more natural to create it and
>>>> the grammer using non-containment references. But if I try this that
>>>> means that the non-contained EObjects are removed at some very early
>>>> stage of processing; that is, they don't show up in the linking stage as
>>>> far as I can tell. Is there any hook point to get such references
>>>> objects and add the to an appropriate container?
>>>>
>>>> cheers,
>>>>
>>>> Miles
|
|
|
Re: Processing ecore with non-containment references [message #54896 is a reply to message #54869] |
Thu, 02 July 2009 16:00   |
Eclipse User |
|
|
|
Hi Miles,
you are right, the instances that are not contained in the model, will
be erased. However I did not get the clue. How did you instantiate these
instances and how did the get lost. As far as I know, the parser will
assign a produced instance to a feature of its container in (almost) any
case. So actually I'm a little bit puzzled where your instances remain :-)
However, any instance that is produced by the parser will be eventually
created by the registered implementation of the IAstFactory-interface.
You may want to hook into it and keep track of any created instance and
use this information later on. I guess you'll have to override your
parser therefore to do some post processing. Have a look at
org.eclipse.xtext.parser.antlr.AbstractAntlrParser.parse(Str ing,
ANTLRInputStream) and the concrete implementation for your language.
org.eclipse.xtext.parser.IAstFactory.create(EClassifier) may be
interesting as well.
Hope that helps,
Sebastian
Am 02.07.2009 21:32 Uhr, schrieb Miles Parker:
> On 2009-07-02 12:13:02 -0700, Sebastian Zarnekow
> <Sebastian.Zarnekow@itemis.de> said:
>
>> Hi Miles,
>>
>> so you only have edges but no vertices or someting alike?
>> Can you please post a short snippet of the concrete syntax, that
>> you'ld like to use? Currently I cannot imagine how it should look like.
>
> Well this is an example, but yes it would have been a better example to
> just use nodes instead of edges. :)
>
>> However, your usecase seems to be a good fit for m2m transformations,
>> because instances of your Ecore model will likely not be created by a
>> concise textual notation with Xtext. Or you do all the linking
>> yourself and create kind of intermediate instances in the parser
>> parsing (as you already did). But that's m2m, too.
>
> Yes, that's exactly what I'm doing. But the problem is that I don't have
> access to the intermediate instances because they are getting erased
> from the tree. I'm assuming that this is because they aren't contained
> somehwere..? If I could make that work then I'd have a much more concise
> xtext side representation. As you can see its already complex enough and
> this is only about 20% of it!
>
> Here is the concrete syntax:
>
> Agent returns SAgent:
> ID=IDZ
> ("HAS" attributes+=Attributes ("," attributes+=Attributes)*".")?
> ("SHOWS" styles+=Style2D ("," styles+=Style2D)*".")?
> rootActivity=Behaviors;
>
>
> Behaviors returns AGroup :
> ("DOES" members+=RootRule (";" (members+=RootRule))*".")?"!";
>
>
> RootRule returns ARoot :
> (Rule | Watch | Initialize | Build) "::" ("[" targets+=NonRoot (","
> (targets+=NonRoot))* "]")?;
>
>
> Rule returns ARule :
> ID=IDZ ("IN" space=[SProjection|IDZ])?;
>
> NonRoot returns AAct :
> Select | Create | CreateProjection;
>
> Select returns ASelect :
> (selected=[ASelect|IDZ]"::")?ID=IDZ "SELECTS" agent=[SAgent|IDZ] "IN"
> space=[SProjection|IDZ] "WHERE" targets+=Query ("AND" targets+=Query)*;
>
>
>
> Queries are just further nodes in the tree. As you can probably imagine,
> the way I've been doing this with containment references requires a lot
> of indirection between the two models.
>
> thanks,
>
> Miles
>
>
>>
>> Regards,
>> Sebastian
>>
>>
>> Am 02.07.2009 20:58 Uhr, schrieb Miles Parker:
>>> Thanks Sebastian,
>>>
>>> I'm not entirely sure that it can't be done with Linker but I haven't
>>> been able to get to a point where I can get this state. But perhaps I've
>>> missed something.
>>>
>>> Imagine I want to define a rooted Graph Struture but I need to create
>>> the nodes implicitly as part of the edges. This is part of a referenced
>>> ecore model which is like:
>>>
>>> Graph:
>>> ref members [edges] (containment)
>>> ref roots [edges] (non-containment 0..*)
>>>
>>> Edge:
>>> ref sources [edges] (non-containment obviously 0..*)
>>> ref targets [edges] (non-containment obviously 0..*)
>>>
>>> And I want to define grammer like (Ithis may not be a good grammer I
>>> haven't tested it, but just to get the idea):
>>>
>>> XGraph returns Graph :
>>> roots+=[Edge];
>>>
>>> XEdge returns Edge :
>>> targets+=([Edge] | Edge)
>>>
>>>
>>> Now, when the model is saved, I need to gather all of the roots and
>>> targets and add them to members so that they are contained. Does that
>>> make sense?
>>>
>>> I know its possible to make the grammer work (I've already done it) by
>>> adding a bunch of intermediate rules, but that is really not very
>>> transparant and it hard to maintain.
>>>
>>> thanks,
>>>
>>> Miles
>>>
>>>
>>> On 2009-07-02 10:47:13 -0700, Sebastian Zarnekow
>>> <Sebastian.Zarnekow@itemis.de> said:
>>>
>>>> Hi Miles,
>>>>
>>>> no there is no such hook.
>>>> Maybe you want to describe what you originally wanted to achieve. I
>>>> guess there is a solution, that should work with Xtext.
>>>>
>>>> Regards,
>>>> Sebastian
>>>>
>>>> Am 02.07.2009 3:54 Uhr, schrieb Miles Parker:
>>>>>
>>>>> I'm doing a lot of conversion on a grammer into a native ecore model.
>>>>> The ideas Sven gave in
>>>>> http://dev.eclipse.org/newslists/news.eclipse.modeling.tmf/m sg00403.html
>>>>>
>>>>> worked well for a lot of issues, but here's one I haven't been able to
>>>>> solve.
>>>>>
>>>>> I have an ecore model in which it is much more natural to create it
>>>>> and
>>>>> the grammer using non-containment references. But if I try this that
>>>>> means that the non-contained EObjects are removed at some very early
>>>>> stage of processing; that is, they don't show up in the linking
>>>>> stage as
>>>>> far as I can tell. Is there any hook point to get such references
>>>>> objects and add the to an appropriate container?
>>>>>
>>>>> cheers,
>>>>>
>>>>> Miles
>
>
|
|
|
Re: Processing ecore with non-containment references [message #55005 is a reply to message #54896] |
Thu, 02 July 2009 18:01   |
Eclipse User |
|
|
|
On 2009-07-02 13:00:20 -0700, Sebastian Zarnekow
<Sebastian.Zarnekow@itemis.de> said:
> Hi Miles,
>
> you are right, the instances that are not contained in the model, will
> be erased. However I did not get the clue. How did you instantiate
> these instances and how did the get lost. As far as I know, the parser
> will assign a produced instance to a feature of its container in
> (almost) any case. So actually I'm a little bit puzzled where your
> instances remain :-)
Me too! They are instantitated through the reference; e.g. An ASelect
is created by Select and added to an ARule created by Rule / RootRule.
(But actually... I'm not sure how the generator deals with a case where
a (XText!) Rule returns an external object created by another (XText)
Rule. Is it ok to add (external) state in the "calling" rule as I've
done?) In any case, the parser definetly checks the syntax of the rule
but maybe that's the only thing it does, becaus the non-contained
relations don't show up in the outline view.
> However, any instance that is produced by the parser will be eventually
> created by the registered implementation of the IAstFactory-interface.
> You may want to hook into it and keep track of any created instance and
> use this information later on. I guess you'll have to override your
> parser therefore to do some post processing. Have a look at
> org.eclipse.xtext.parser.antlr.AbstractAntlrParser.parse(Str ing,
> ANTLRInputStream) and the concrete implementation for your language.
> org.eclipse.xtext.parser.IAstFactory.create(EClassifier) may be
> interesting as well.
OK, thanks for the references -- I'll take a look and play around with
it some more.
-Miles
>
> Hope that helps,
> Sebastian
>
>
> Am 02.07.2009 21:32 Uhr, schrieb Miles Parker:
>> On 2009-07-02 12:13:02 -0700, Sebastian Zarnekow
>> <Sebastian.Zarnekow@itemis.de> said:
>>
>>> Hi Miles,
>>>
>>> so you only have edges but no vertices or someting alike?
>>> Can you please post a short snippet of the concrete syntax, that
>>> you'ld like to use? Currently I cannot imagine how it should look like.
>>
>> Well this is an example, but yes it would have been a better example to
>> just use nodes instead of edges. :)
>>
>>> However, your usecase seems to be a good fit for m2m transformations,
>>> because instances of your Ecore model will likely not be created by a
>>> concise textual notation with Xtext. Or you do all the linking
>>> yourself and create kind of intermediate instances in the parser
>>> parsing (as you already did). But that's m2m, too.
>>
>> Yes, that's exactly what I'm doing. But the problem is that I don't have
>> access to the intermediate instances because they are getting erased
>> from the tree. I'm assuming that this is because they aren't contained
>> somehwere..? If I could make that work then I'd have a much more concise
>> xtext side representation. As you can see its already complex enough and
>> this is only about 20% of it!
>>
>> Here is the concrete syntax:
>>
>> Agent returns SAgent:
>> ID=IDZ
>> ("HAS" attributes+=Attributes ("," attributes+=Attributes)*".")?
>> ("SHOWS" styles+=Style2D ("," styles+=Style2D)*".")?
>> rootActivity=Behaviors;
>>
>>
>> Behaviors returns AGroup :
>> ("DOES" members+=RootRule (";" (members+=RootRule))*".")?"!";
>>
>>
>> RootRule returns ARoot :
>> (Rule | Watch | Initialize | Build) "::" ("[" targets+=NonRoot (","
>> (targets+=NonRoot))* "]")?;
>>
>>
>> Rule returns ARule :
>> ID=IDZ ("IN" space=[SProjection|IDZ])?;
>>
>> NonRoot returns AAct :
>> Select | Create | CreateProjection;
>>
>> Select returns ASelect :
>> (selected=[ASelect|IDZ]"::")?ID=IDZ "SELECTS" agent=[SAgent|IDZ] "IN"
>> space=[SProjection|IDZ] "WHERE" targets+=Query ("AND" targets+=Query)*;
>>
>>
>>
>> Queries are just further nodes in the tree. As you can probably imagine,
>> the way I've been doing this with containment references requires a lot
>> of indirection between the two models.
>>
>> thanks,
>>
>> Miles
>>
>>
>>>
>>> Regards,
>>> Sebastian
>>>
>>>
>>> Am 02.07.2009 20:58 Uhr, schrieb Miles Parker:
>>>> Thanks Sebastian,
>>>>
>>>> I'm not entirely sure that it can't be done with Linker but I haven't
>>>> been able to get to a point where I can get this state. But perhaps I've
>>>> missed something.
>>>>
>>>> Imagine I want to define a rooted Graph Struture but I need to create
>>>> the nodes implicitly as part of the edges. This is part of a referenced
>>>> ecore model which is like:
>>>>
>>>> Graph:
>>>> ref members [edges] (containment)
>>>> ref roots [edges] (non-containment 0..*)
>>>>
>>>> Edge:
>>>> ref sources [edges] (non-containment obviously 0..*)
>>>> ref targets [edges] (non-containment obviously 0..*)
>>>>
>>>> And I want to define grammer like (Ithis may not be a good grammer I
>>>> haven't tested it, but just to get the idea):
>>>>
>>>> XGraph returns Graph :
>>>> roots+=[Edge];
>>>>
>>>> XEdge returns Edge :
>>>> targets+=([Edge] | Edge)
>>>>
>>>>
>>>> Now, when the model is saved, I need to gather all of the roots and
>>>> targets and add them to members so that they are contained. Does that
>>>> make sense?
>>>>
>>>> I know its possible to make the grammer work (I've already done it) by
>>>> adding a bunch of intermediate rules, but that is really not very
>>>> transparant and it hard to maintain.
>>>>
>>>> thanks,
>>>>
>>>> Miles
>>>>
>>>>
>>>> On 2009-07-02 10:47:13 -0700, Sebastian Zarnekow
>>>> <Sebastian.Zarnekow@itemis.de> said:
>>>>
>>>>> Hi Miles,
>>>>>
>>>>> no there is no such hook.
>>>>> Maybe you want to describe what you originally wanted to achieve. I
>>>>> guess there is a solution, that should work with Xtext.
>>>>>
>>>>> Regards,
>>>>> Sebastian
>>>>>
>>>>> Am 02.07.2009 3:54 Uhr, schrieb Miles Parker:
>>>>>>
>>>>>> I'm doing a lot of conversion on a grammer into a native ecore model.
>>>>>> The ideas Sven gave in
>>>>>> http://dev.eclipse.org/newslists/news.eclipse.modeling.tmf/m sg00403.html
>>>>>>
>>>>>> worked well for a lot of issues, but here's one I haven't been able to
>>>>>> solve.
>>>>>>
>>>>>> I have an ecore model in which it is much more natural to create it
>>>>>> and
>>>>>> the grammer using non-containment references. But if I try this that
>>>>>> means that the non-contained EObjects are removed at some very early
>>>>>> stage of processing; that is, they don't show up in the linking
>>>>>> stage as
>>>>>> far as I can tell. Is there any hook point to get such references
>>>>>> objects and add the to an appropriate container?
>>>>>>
>>>>>> cheers,
>>>>>>
>>>>>> Miles
|
|
|
Re: Processing ecore with non-containment references [message #58084 is a reply to message #54896] |
Mon, 13 July 2009 20:27   |
Eclipse User |
|
|
|
Sebastian,
Based on your guidance, I was able to make a lot of progress. I
impemented a custom EcoreElementFactory, and am able to intercept the
setters and getters. But though I was able to get the containment to
work, I still seem to lose things somewhere along the way! I think I
have an idea of how that happens. The containment references use ID for
key, and that ID is getting overriden. I was able to determine the
order of eveything by instrumenting the custom gactory, and I found
that the adds are happening before the setters. So the references are
now getting added properly, but then the parser comes along and
overwrites the IDs with a (non-null) value and the reference is lost.
Really, it seems to me that in the case of keys, the setters should be
happening first in default case.
Does my explanation make sense? Any ideas about how to have sets
applied first? Is the order something that is determined purely through
grammer inference process?
Miles
On 2009-07-02 13:00:20 -0700, Sebastian Zarnekow
<Sebastian.Zarnekow@itemis.de> said:
> Hi Miles,
>
> you are right, the instances that are not contained in the model, will
> be erased. However I did not get the clue. How did you instantiate
> these instances and how did the get lost. As far as I know, the parser
> will assign a produced instance to a feature of its container in
> (almost) any case. So actually I'm a little bit puzzled where your
> instances remain :-)
>
> However, any instance that is produced by the parser will be eventually
> created by the registered implementation of the IAstFactory-interface.
> You may want to hook into it and keep track of any created instance and
> use this information later on. I guess you'll have to override your
> parser therefore to do some post processing. Have a look at
> org.eclipse.xtext.parser.antlr.AbstractAntlrParser.parse(Str ing,
> ANTLRInputStream) and the concrete implementation for your language.
> org.eclipse.xtext.parser.IAstFactory.create(EClassifier) may be
> interesting as well.
>
> Hope that helps,
> Sebastian
>
>
> Am 02.07.2009 21:32 Uhr, schrieb Miles Parker:
>> On 2009-07-02 12:13:02 -0700, Sebastian Zarnekow
>> <Sebastian.Zarnekow@itemis.de> said:
>>
>>> Hi Miles,
>>>
>>> so you only have edges but no vertices or someting alike?
>>> Can you please post a short snippet of the concrete syntax, that
>>> you'ld like to use? Currently I cannot imagine how it should look like.
>>
>> Well this is an example, but yes it would have been a better example to
>> just use nodes instead of edges. :)
>>
>>> However, your usecase seems to be a good fit for m2m transformations,
>>> because instances of your Ecore model will likely not be created by a
>>> concise textual notation with Xtext. Or you do all the linking
>>> yourself and create kind of intermediate instances in the parser
>>> parsing (as you already did). But that's m2m, too.
>>
>> Yes, that's exactly what I'm doing. But the problem is that I don't have
>> access to the intermediate instances because they are getting erased
>> from the tree. I'm assuming that this is because they aren't contained
>> somehwere..? If I could make that work then I'd have a much more concise
>> xtext side representation. As you can see its already complex enough and
>> this is only about 20% of it!
>>
>> Here is the concrete syntax:
>>
>> Agent returns SAgent:
>> ID=IDZ
>> ("HAS" attributes+=Attributes ("," attributes+=Attributes)*".")?
>> ("SHOWS" styles+=Style2D ("," styles+=Style2D)*".")?
>> rootActivity=Behaviors;
>>
>>
>> Behaviors returns AGroup :
>> ("DOES" members+=RootRule (";" (members+=RootRule))*".")?"!";
>>
>>
>> RootRule returns ARoot :
>> (Rule | Watch | Initialize | Build) "::" ("[" targets+=NonRoot (","
>> (targets+=NonRoot))* "]")?;
>>
>>
>> Rule returns ARule :
>> ID=IDZ ("IN" space=[SProjection|IDZ])?;
>>
>> NonRoot returns AAct :
>> Select | Create | CreateProjection;
>>
>> Select returns ASelect :
>> (selected=[ASelect|IDZ]"::")?ID=IDZ "SELECTS" agent=[SAgent|IDZ] "IN"
>> space=[SProjection|IDZ] "WHERE" targets+=Query ("AND" targets+=Query)*;
>>
>>
>>
>> Queries are just further nodes in the tree. As you can probably imagine,
>> the way I've been doing this with containment references requires a lot
>> of indirection between the two models.
>>
>> thanks,
>>
>> Miles
>>
>>
>>>
>>> Regards,
>>> Sebastian
>>>
>>>
>>> Am 02.07.2009 20:58 Uhr, schrieb Miles Parker:
>>>> Thanks Sebastian,
>>>>
>>>> I'm not entirely sure that it can't be done with Linker but I haven't
>>>> been able to get to a point where I can get this state. But perhaps I've
>>>> missed something.
>>>>
>>>> Imagine I want to define a rooted Graph Struture but I need to create
>>>> the nodes implicitly as part of the edges. This is part of a referenced
>>>> ecore model which is like:
>>>>
>>>> Graph:
>>>> ref members [edges] (containment)
>>>> ref roots [edges] (non-containment 0..*)
>>>>
>>>> Edge:
>>>> ref sources [edges] (non-containment obviously 0..*)
>>>> ref targets [edges] (non-containment obviously 0..*)
>>>>
>>>> And I want to define grammer like (Ithis may not be a good grammer I
>>>> haven't tested it, but just to get the idea):
>>>>
>>>> XGraph returns Graph :
>>>> roots+=[Edge];
>>>>
>>>> XEdge returns Edge :
>>>> targets+=([Edge] | Edge)
>>>>
>>>>
>>>> Now, when the model is saved, I need to gather all of the roots and
>>>> targets and add them to members so that they are contained. Does that
>>>> make sense?
>>>>
>>>> I know its possible to make the grammer work (I've already done it) by
>>>> adding a bunch of intermediate rules, but that is really not very
>>>> transparant and it hard to maintain.
>>>>
>>>> thanks,
>>>>
>>>> Miles
>>>>
>>>>
>>>> On 2009-07-02 10:47:13 -0700, Sebastian Zarnekow
>>>> <Sebastian.Zarnekow@itemis.de> said:
>>>>
>>>>> Hi Miles,
>>>>>
>>>>> no there is no such hook.
>>>>> Maybe you want to describe what you originally wanted to achieve. I
>>>>> guess there is a solution, that should work with Xtext.
>>>>>
>>>>> Regards,
>>>>> Sebastian
>>>>>
>>>>> Am 02.07.2009 3:54 Uhr, schrieb Miles Parker:
>>>>>>
>>>>>> I'm doing a lot of conversion on a grammer into a native ecore model.
>>>>>> The ideas Sven gave in
>>>>>> http://dev.eclipse.org/newslists/news.eclipse.modeling.tmf/m sg00403.html
>>>>>>
>>>>>> worked well for a lot of issues, but here's one I haven't been able to
>>>>>> solve.
>>>>>>
>>>>>> I have an ecore model in which it is much more natural to create it
>>>>>> and
>>>>>> the grammer using non-containment references. But if I try this that
>>>>>> means that the non-contained EObjects are removed at some very early
>>>>>> stage of processing; that is, they don't show up in the linking
>>>>>> stage as
>>>>>> far as I can tell. Is there any hook point to get such references
>>>>>> objects and add the to an appropriate container?
>>>>>>
>>>>>> cheers,
>>>>>>
>>>>>> Miles
|
|
|
Re: Processing ecore with non-containment references [message #58109 is a reply to message #58084] |
Mon, 13 July 2009 22:03   |
Eclipse User |
|
|
|
On 2009-07-13 17:27:43 -0700, Miles Parker <milesparker@gmail.com> said:
> Sebastian,
>
> Based on your guidance, I was able to make a lot of progress. I
> impemented a custom EcoreElementFactory, and am able to intercept the
> setters and getters.
Brain fade..I mean "sets and adds".
> But though I was able to get the containment to work, I still seem to
> lose things somewhere along the way! I think I have an idea of how that
> happens. The containment references use ID for key, and that ID is
> getting overriden. I was able to determine the order of eveything by
> instrumenting the custom gactory, and I found that the adds are
> happening before the setters. So the references are now getting added
> properly, but then the parser comes along and overwrites the IDs with a
> (non-null) value and the reference is lost. Really, it seems to me that
> in the case of keys, the setters should be happening first in default
> case.
>
> Does my explanation make sense? Any ideas about how to have sets
> applied first? Is the order something that is determined purely through
> grammer inference process?
>
> Miles
>
> On 2009-07-02 13:00:20 -0700, Sebastian Zarnekow
> <Sebastian.Zarnekow@itemis.de> said:
>
>> Hi Miles,
>>
>> you are right, the instances that are not contained in the model, will
>> be erased. However I did not get the clue. How did you instantiate
>> these instances and how did the get lost. As far as I know, the parser
>> will assign a produced instance to a feature of its container in
>> (almost) any case. So actually I'm a little bit puzzled where your
>> instances remain :-)
>>
>> However, any instance that is produced by the parser will be eventually
>> created by the registered implementation of the IAstFactory-interface.
>> You may want to hook into it and keep track of any created instance and
>> use this information later on. I guess you'll have to override your
>> parser therefore to do some post processing. Have a look at
>> org.eclipse.xtext.parser.antlr.AbstractAntlrParser.parse(Str ing,
>> ANTLRInputStream) and the concrete implementation for your language.
>> org.eclipse.xtext.parser.IAstFactory.create(EClassifier) may be
>> interesting as well.
>>
>> Hope that helps,
>> Sebastian
>>
>>
>> Am 02.07.2009 21:32 Uhr, schrieb Miles Parker:
>>> On 2009-07-02 12:13:02 -0700, Sebastian Zarnekow
>>> <Sebastian.Zarnekow@itemis.de> said:
>>>
>>>> Hi Miles,
>>>>
>>>> so you only have edges but no vertices or someting alike?
>>>> Can you please post a short snippet of the concrete syntax, that
>>>> you'ld like to use? Currently I cannot imagine how it should look like.
>>>
>>> Well this is an example, but yes it would have been a better example to
>>> just use nodes instead of edges. :)
>>>
>>>> However, your usecase seems to be a good fit for m2m transformations,
>>>> because instances of your Ecore model will likely not be created by a
>>>> concise textual notation with Xtext. Or you do all the linking
>>>> yourself and create kind of intermediate instances in the parser
>>>> parsing (as you already did). But that's m2m, too.
>>>
>>> Yes, that's exactly what I'm doing. But the problem is that I don't have
>>> access to the intermediate instances because they are getting erased
>>> from the tree. I'm assuming that this is because they aren't contained
>>> somehwere..? If I could make that work then I'd have a much more concise
>>> xtext side representation. As you can see its already complex enough and
>>> this is only about 20% of it!
>>>
>>> Here is the concrete syntax:
>>>
>>> Agent returns SAgent:
>>> ID=IDZ
>>> ("HAS" attributes+=Attributes ("," attributes+=Attributes)*".")?
>>> ("SHOWS" styles+=Style2D ("," styles+=Style2D)*".")?
>>> rootActivity=Behaviors;
>>>
>>>
>>> Behaviors returns AGroup :
>>> ("DOES" members+=RootRule (";" (members+=RootRule))*".")?"!";
>>>
>>>
>>> RootRule returns ARoot :
>>> (Rule | Watch | Initialize | Build) "::" ("[" targets+=NonRoot (","
>>> (targets+=NonRoot))* "]")?;
>>>
>>>
>>> Rule returns ARule :
>>> ID=IDZ ("IN" space=[SProjection|IDZ])?;
>>>
>>> NonRoot returns AAct :
>>> Select | Create | CreateProjection;
>>>
>>> Select returns ASelect :
>>> (selected=[ASelect|IDZ]"::")?ID=IDZ "SELECTS" agent=[SAgent|IDZ] "IN"
>>> space=[SProjection|IDZ] "WHERE" targets+=Query ("AND" targets+=Query)*;
>>>
>>>
>>>
>>> Queries are just further nodes in the tree. As you can probably imagine,
>>> the way I've been doing this with containment references requires a lot
>>> of indirection between the two models.
>>>
>>> thanks,
>>>
>>> Miles
>>>
>>>
>>>>
>>>> Regards,
>>>> Sebastian
>>>>
>>>>
>>>> Am 02.07.2009 20:58 Uhr, schrieb Miles Parker:
>>>>> Thanks Sebastian,
>>>>>
>>>>> I'm not entirely sure that it can't be done with Linker but I haven't
>>>>> been able to get to a point where I can get this state. But perhaps I've
>>>>> missed something.
>>>>>
>>>>> Imagine I want to define a rooted Graph Struture but I need to create
>>>>> the nodes implicitly as part of the edges. This is part of a referenced
>>>>> ecore model which is like:
>>>>>
>>>>> Graph:
>>>>> ref members [edges] (containment)
>>>>> ref roots [edges] (non-containment 0..*)
>>>>>
>>>>> Edge:
>>>>> ref sources [edges] (non-containment obviously 0..*)
>>>>> ref targets [edges] (non-containment obviously 0..*)
>>>>>
>>>>> And I want to define grammer like (Ithis may not be a good grammer I
>>>>> haven't tested it, but just to get the idea):
>>>>>
>>>>> XGraph returns Graph :
>>>>> roots+=[Edge];
>>>>>
>>>>> XEdge returns Edge :
>>>>> targets+=([Edge] | Edge)
>>>>>
>>>>>
>>>>> Now, when the model is saved, I need to gather all of the roots and
>>>>> targets and add them to members so that they are contained. Does that
>>>>> make sense?
>>>>>
>>>>> I know its possible to make the grammer work (I've already done it) by
>>>>> adding a bunch of intermediate rules, but that is really not very
>>>>> transparant and it hard to maintain.
>>>>>
>>>>> thanks,
>>>>>
>>>>> Miles
>>>>>
>>>>>
>>>>> On 2009-07-02 10:47:13 -0700, Sebastian Zarnekow
>>>>> <Sebastian.Zarnekow@itemis.de> said:
>>>>>
>>>>>> Hi Miles,
>>>>>>
>>>>>> no there is no such hook.
>>>>>> Maybe you want to describe what you originally wanted to achieve. I
>>>>>> guess there is a solution, that should work with Xtext.
>>>>>>
>>>>>> Regards,
>>>>>> Sebastian
>>>>>>
>>>>>> Am 02.07.2009 3:54 Uhr, schrieb Miles Parker:
>>>>>>>
>>>>>>> I'm doing a lot of conversion on a grammer into a native ecore model.
>>>>>>> The ideas Sven gave in
>>>>>>> http://dev.eclipse.org/newslists/news.eclipse.modeling.tmf/m sg00403.html
>>>>>>>
>>>>>>> worked well for a lot of issues, but here's one I haven't been able to
>>>>>>> solve.
>>>>>>>
>>>>>>> I have an ecore model in which it is much more natural to create it
>>>>>>> and
>>>>>>> the grammer using non-containment references. But if I try this that
>>>>>>> means that the non-contained EObjects are removed at some very early
>>>>>>> stage of processing; that is, they don't show up in the linking
>>>>>>> stage as
>>>>>>> far as I can tell. Is there any hook point to get such references
>>>>>>> objects and add the to an appropriate container?
>>>>>>>
>>>>>>> cheers,
>>>>>>>
>>>>>>> Miles
|
|
|
Re: Processing ecore with non-containment references [message #58462 is a reply to message #58084] |
Tue, 14 July 2009 10:26   |
Eclipse User |
|
|
|
Hi Miles,
you're right, newly created EObject are first added to their respective
container and initialized afterwards. Did you set any specific features
on the containment reference itself?
I cannot imagine that any element is removed from an EList when an ID
feature is assigned. Do you use a HashMap internally for your
ID<->EObject cache?
Regards,
Sebastian
Am 14.07.2009 2:27 Uhr, schrieb Miles Parker:
> Sebastian,
>
> Based on your guidance, I was able to make a lot of progress. I
> impemented a custom EcoreElementFactory, and am able to intercept the
> setters and getters. But though I was able to get the containment to
> work, I still seem to lose things somewhere along the way! I think I
> have an idea of how that happens. The containment references use ID for
> key, and that ID is getting overriden. I was able to determine the order
> of eveything by instrumenting the custom gactory, and I found that the
> adds are happening before the setters. So the references are now getting
> added properly, but then the parser comes along and overwrites the IDs
> with a (non-null) value and the reference is lost. Really, it seems to
> me that in the case of keys, the setters should be happening first in
> default case.
>
> Does my explanation make sense? Any ideas about how to have sets applied
> first? Is the order something that is determined purely through grammer
> inference process?
>
> Miles
>
> On 2009-07-02 13:00:20 -0700, Sebastian Zarnekow
> <Sebastian.Zarnekow@itemis.de> said:
>
>> Hi Miles,
>>
>> you are right, the instances that are not contained in the model, will
>> be erased. However I did not get the clue. How did you instantiate
>> these instances and how did the get lost. As far as I know, the parser
>> will assign a produced instance to a feature of its container in
>> (almost) any case. So actually I'm a little bit puzzled where your
>> instances remain :-)
>>
>> However, any instance that is produced by the parser will be
>> eventually created by the registered implementation of the
>> IAstFactory-interface. You may want to hook into it and keep track of
>> any created instance and use this information later on. I guess you'll
>> have to override your parser therefore to do some post processing.
>> Have a look at
>> org.eclipse.xtext.parser.antlr.AbstractAntlrParser.parse(Str ing,
>> ANTLRInputStream) and the concrete implementation for your language.
>> org.eclipse.xtext.parser.IAstFactory.create(EClassifier) may be
>> interesting as well.
>>
>> Hope that helps,
>> Sebastian
>>
>>
>> Am 02.07.2009 21:32 Uhr, schrieb Miles Parker:
>>> On 2009-07-02 12:13:02 -0700, Sebastian Zarnekow
>>> <Sebastian.Zarnekow@itemis.de> said:
>>>
>>>> Hi Miles,
>>>>
>>>> so you only have edges but no vertices or someting alike?
>>>> Can you please post a short snippet of the concrete syntax, that
>>>> you'ld like to use? Currently I cannot imagine how it should look like.
>>>
>>> Well this is an example, but yes it would have been a better example to
>>> just use nodes instead of edges. :)
>>>
>>>> However, your usecase seems to be a good fit for m2m transformations,
>>>> because instances of your Ecore model will likely not be created by a
>>>> concise textual notation with Xtext. Or you do all the linking
>>>> yourself and create kind of intermediate instances in the parser
>>>> parsing (as you already did). But that's m2m, too.
>>>
>>> Yes, that's exactly what I'm doing. But the problem is that I don't have
>>> access to the intermediate instances because they are getting erased
>>> from the tree. I'm assuming that this is because they aren't contained
>>> somehwere..? If I could make that work then I'd have a much more concise
>>> xtext side representation. As you can see its already complex enough and
>>> this is only about 20% of it!
>>>
>>> Here is the concrete syntax:
>>>
>>> Agent returns SAgent:
>>> ID=IDZ
>>> ("HAS" attributes+=Attributes ("," attributes+=Attributes)*".")?
>>> ("SHOWS" styles+=Style2D ("," styles+=Style2D)*".")?
>>> rootActivity=Behaviors;
>>>
>>>
>>> Behaviors returns AGroup :
>>> ("DOES" members+=RootRule (";" (members+=RootRule))*".")?"!";
>>>
>>>
>>> RootRule returns ARoot :
>>> (Rule | Watch | Initialize | Build) "::" ("[" targets+=NonRoot (","
>>> (targets+=NonRoot))* "]")?;
>>>
>>>
>>> Rule returns ARule :
>>> ID=IDZ ("IN" space=[SProjection|IDZ])?;
>>>
>>> NonRoot returns AAct :
>>> Select | Create | CreateProjection;
>>>
>>> Select returns ASelect :
>>> (selected=[ASelect|IDZ]"::")?ID=IDZ "SELECTS" agent=[SAgent|IDZ] "IN"
>>> space=[SProjection|IDZ] "WHERE" targets+=Query ("AND" targets+=Query)*;
>>>
>>>
>>>
>>> Queries are just further nodes in the tree. As you can probably imagine,
>>> the way I've been doing this with containment references requires a lot
>>> of indirection between the two models.
>>>
>>> thanks,
>>>
>>> Miles
>>>
>>>
>>>>
>>>> Regards,
>>>> Sebastian
>>>>
>>>>
>>>> Am 02.07.2009 20:58 Uhr, schrieb Miles Parker:
>>>>> Thanks Sebastian,
>>>>>
>>>>> I'm not entirely sure that it can't be done with Linker but I haven't
>>>>> been able to get to a point where I can get this state. But perhaps
>>>>> I've
>>>>> missed something.
>>>>>
>>>>> Imagine I want to define a rooted Graph Struture but I need to create
>>>>> the nodes implicitly as part of the edges. This is part of a
>>>>> referenced
>>>>> ecore model which is like:
>>>>>
>>>>> Graph:
>>>>> ref members [edges] (containment)
>>>>> ref roots [edges] (non-containment 0..*)
>>>>>
>>>>> Edge:
>>>>> ref sources [edges] (non-containment obviously 0..*)
>>>>> ref targets [edges] (non-containment obviously 0..*)
>>>>>
>>>>> And I want to define grammer like (Ithis may not be a good grammer I
>>>>> haven't tested it, but just to get the idea):
>>>>>
>>>>> XGraph returns Graph :
>>>>> roots+=[Edge];
>>>>>
>>>>> XEdge returns Edge :
>>>>> targets+=([Edge] | Edge)
>>>>>
>>>>>
>>>>> Now, when the model is saved, I need to gather all of the roots and
>>>>> targets and add them to members so that they are contained. Does that
>>>>> make sense?
>>>>>
>>>>> I know its possible to make the grammer work (I've already done it) by
>>>>> adding a bunch of intermediate rules, but that is really not very
>>>>> transparant and it hard to maintain.
>>>>>
>>>>> thanks,
>>>>>
>>>>> Miles
>>>>>
>>>>>
>>>>> On 2009-07-02 10:47:13 -0700, Sebastian Zarnekow
>>>>> <Sebastian.Zarnekow@itemis.de> said:
>>>>>
>>>>>> Hi Miles,
>>>>>>
>>>>>> no there is no such hook.
>>>>>> Maybe you want to describe what you originally wanted to achieve. I
>>>>>> guess there is a solution, that should work with Xtext.
>>>>>>
>>>>>> Regards,
>>>>>> Sebastian
>>>>>>
>>>>>> Am 02.07.2009 3:54 Uhr, schrieb Miles Parker:
>>>>>>>
>>>>>>> I'm doing a lot of conversion on a grammer into a native ecore
>>>>>>> model.
>>>>>>> The ideas Sven gave in
>>>>>>> http://dev.eclipse.org/newslists/news.eclipse.modeling.tmf/m sg00403.html
>>>>>>>
>>>>>>>
>>>>>>> worked well for a lot of issues, but here's one I haven't been
>>>>>>> able to
>>>>>>> solve.
>>>>>>>
>>>>>>> I have an ecore model in which it is much more natural to create it
>>>>>>> and
>>>>>>> the grammer using non-containment references. But if I try this that
>>>>>>> means that the non-contained EObjects are removed at some very early
>>>>>>> stage of processing; that is, they don't show up in the linking
>>>>>>> stage as
>>>>>>> far as I can tell. Is there any hook point to get such references
>>>>>>> objects and add the to an appropriate container?
>>>>>>>
>>>>>>> cheers,
>>>>>>>
>>>>>>> Miles
>
>
|
|
|
Re: Processing ecore with non-containment references [message #58633 is a reply to message #58462] |
Tue, 14 July 2009 18:24   |
Eclipse User |
|
|
|
On 2009-07-14 07:26:42 -0700, Sebastian Zarnekow
<Sebastian.Zarnekow@itemis.de> said:
> Hi Miles,
>
> you're right, newly created EObject are first added to their respective
> container and initialized afterwards. Did you set any specific features
> on the containment reference itself?
No, not for the non-root referenced nodes, that is. The very first node
is contained.
> I cannot imagine that any element is removed from an EList when an ID
> feature is assigned.
Hmm.. yes I think I see what you mean. I'm being a little vague here
because I haven't yet figured out the internals. I think what might be
happening is that when I next try to do the M2M, the ids aren't in
synch somehow..
> Do you use a HashMap internally for your ID<->EObject cache?
I don't actualy have the id at the time of add because they haven't
been set yet. So I can't hash for ID. Instead, since I have the
source->target references what I've been doing is the following.
1) I know that the continment refernces are added after the
non-containment (acyclic graph) refernces.
2) On an add for the root containment reference, I walk through the
tree of targets and assign the containment reference to be the same
root containment object.
So now in the outline view for the XText editor, the non directly
contained reference(s) shows up under the container node. But after
that point it doesn't.
>
> Regards,
> Sebastian
>
> Am 14.07.2009 2:27 Uhr, schrieb Miles Parker:
>> Sebastian,
>>
>> Based on your guidance, I was able to make a lot of progress. I
>> impemented a custom EcoreElementFactory, and am able to intercept the
>> setters and getters. But though I was able to get the containment to
>> work, I still seem to lose things somewhere along the way! I think I
>> have an idea of how that happens. The containment references use ID for
>> key, and that ID is getting overriden. I was able to determine the order
>> of eveything by instrumenting the custom gactory, and I found that the
>> adds are happening before the setters. So the references are now getting
>> added properly, but then the parser comes along and overwrites the IDs
>> with a (non-null) value and the reference is lost. Really, it seems to
>> me that in the case of keys, the setters should be happening first in
>> default case.
>>
>> Does my explanation make sense? Any ideas about how to have sets applied
>> first? Is the order something that is determined purely through grammer
>> inference process?
>>
>> Miles
>>
>> On 2009-07-02 13:00:20 -0700, Sebastian Zarnekow
>> <Sebastian.Zarnekow@itemis.de> said:
>>
>>> Hi Miles,
>>>
>>> you are right, the instances that are not contained in the model, will
>>> be erased. However I did not get the clue. How did you instantiate
>>> these instances and how did the get lost. As far as I know, the parser
>>> will assign a produced instance to a feature of its container in
>>> (almost) any case. So actually I'm a little bit puzzled where your
>>> instances remain :-)
>>>
>>> However, any instance that is produced by the parser will be
>>> eventually created by the registered implementation of the
>>> IAstFactory-interface. You may want to hook into it and keep track of
>>> any created instance and use this information later on. I guess you'll
>>> have to override your parser therefore to do some post processing.
>>> Have a look at
>>> org.eclipse.xtext.parser.antlr.AbstractAntlrParser.parse(Str ing,
>>> ANTLRInputStream) and the concrete implementation for your language.
>>> org.eclipse.xtext.parser.IAstFactory.create(EClassifier) may be
>>> interesting as well.
>>>
>>> Hope that helps,
>>> Sebastian
>>>
>>>
>>> Am 02.07.2009 21:32 Uhr, schrieb Miles Parker:
>>>> On 2009-07-02 12:13:02 -0700, Sebastian Zarnekow
>>>> <Sebastian.Zarnekow@itemis.de> said:
>>>>
>>>>> Hi Miles,
>>>>>
>>>>> so you only have edges but no vertices or someting alike?
>>>>> Can you please post a short snippet of the concrete syntax, that
>>>>> you'ld like to use? Currently I cannot imagine how it should look like.
>>>>
>>>> Well this is an example, but yes it would have been a better example to
>>>> just use nodes instead of edges. :)
>>>>
>>>>> However, your usecase seems to be a good fit for m2m transformations,
>>>>> because instances of your Ecore model will likely not be created by a
>>>>> concise textual notation with Xtext. Or you do all the linking
>>>>> yourself and create kind of intermediate instances in the parser
>>>>> parsing (as you already did). But that's m2m, too.
>>>>
>>>> Yes, that's exactly what I'm doing. But the problem is that I don't have
>>>> access to the intermediate instances because they are getting erased
>>>> from the tree. I'm assuming that this is because they aren't contained
>>>> somehwere..? If I could make that work then I'd have a much more concise
>>>> xtext side representation. As you can see its already complex enough and
>>>> this is only about 20% of it!
>>>>
>>>> Here is the concrete syntax:
>>>>
>>>> Agent returns SAgent:
>>>> ID=IDZ
>>>> ("HAS" attributes+=Attributes ("," attributes+=Attributes)*".")?
>>>> ("SHOWS" styles+=Style2D ("," styles+=Style2D)*".")?
>>>> rootActivity=Behaviors;
>>>>
>>>>
>>>> Behaviors returns AGroup :
>>>> ("DOES" members+=RootRule (";" (members+=RootRule))*".")?"!";
>>>>
>>>>
>>>> RootRule returns ARoot :
>>>> (Rule | Watch | Initialize | Build) "::" ("[" targets+=NonRoot (","
>>>> (targets+=NonRoot))* "]")?;
>>>>
>>>>
>>>> Rule returns ARule :
>>>> ID=IDZ ("IN" space=[SProjection|IDZ])?;
>>>>
>>>> NonRoot returns AAct :
>>>> Select | Create | CreateProjection;
>>>>
>>>> Select returns ASelect :
>>>> (selected=[ASelect|IDZ]"::")?ID=IDZ "SELECTS" agent=[SAgent|IDZ] "IN"
>>>> space=[SProjection|IDZ] "WHERE" targets+=Query ("AND" targets+=Query)*;
>>>>
>>>>
>>>>
>>>> Queries are just further nodes in the tree. As you can probably imagine,
>>>> the way I've been doing this with containment references requires a lot
>>>> of indirection between the two models.
>>>>
>>>> thanks,
>>>>
>>>> Miles
>>>>
>>>>
>>>>>
>>>>> Regards,
>>>>> Sebastian
>>>>>
>>>>>
>>>>> Am 02.07.2009 20:58 Uhr, schrieb Miles Parker:
>>>>>> Thanks Sebastian,
>>>>>>
>>>>>> I'm not entirely sure that it can't be done with Linker but I haven't
>>>>>> been able to get to a point where I can get this state. But perhaps
>>>>>> I've
>>>>>> missed something.
>>>>>>
>>>>>> Imagine I want to define a rooted Graph Struture but I need to create
>>>>>> the nodes implicitly as part of the edges. This is part of a
>>>>>> referenced
>>>>>> ecore model which is like:
>>>>>>
>>>>>> Graph:
>>>>>> ref members [edges] (containment)
>>>>>> ref roots [edges] (non-containment 0..*)
>>>>>>
>>>>>> Edge:
>>>>>> ref sources [edges] (non-containment obviously 0..*)
>>>>>> ref targets [edges] (non-containment obviously 0..*)
>>>>>>
>>>>>> And I want to define grammer like (Ithis may not be a good grammer I
>>>>>> haven't tested it, but just to get the idea):
>>>>>>
>>>>>> XGraph returns Graph :
>>>>>> roots+=[Edge];
>>>>>>
>>>>>> XEdge returns Edge :
>>>>>> targets+=([Edge] | Edge)
>>>>>>
>>>>>>
>>>>>> Now, when the model is saved, I need to gather all of the roots and
>>>>>> targets and add them to members so that they are contained. Does that
>>>>>> make sense?
>>>>>>
>>>>>> I know its possible to make the grammer work (I've already done it) by
>>>>>> adding a bunch of intermediate rules, but that is really not very
>>>>>> transparant and it hard to maintain.
>>>>>>
>>>>>> thanks,
>>>>>>
>>>>>> Miles
>>>>>>
>>>>>>
>>>>>> On 2009-07-02 10:47:13 -0700, Sebastian Zarnekow
>>>>>> <Sebastian.Zarnekow@itemis.de> said:
>>>>>>
>>>>>>> Hi Miles,
>>>>>>>
>>>>>>> no there is no such hook.
>>>>>>> Maybe you want to describe what you originally wanted to achieve. I
>>>>>>> guess there is a solution, that should work with Xtext.
>>>>>>>
>>>>>>> Regards,
>>>>>>> Sebastian
>>>>>>>
>>>>>>> Am 02.07.2009 3:54 Uhr, schrieb Miles Parker:
>>>>>>>>
>>>>>>>> I'm doing a lot of conversion on a grammer into a native ecore
>>>>>>>> model.
>>>>>>>> The ideas Sven gave in
>>>>>>>> http://dev.eclipse.org/newslists/news.eclipse.modeling.tmf/m sg00403.html
>>>>>>>>
>>>>>>>>
>>>>>>>> worked well for a lot of issues, but here's one I haven't been
>>>>>>>> able to
>>>>>>>> solve.
>>>>>>>>
>>>>>>>> I have an ecore model in which it is much more natural to create it
>>>>>>>> and
>>>>>>>> the grammer using non-containment references. But if I try this that
>>>>>>>> means that the non-contained EObjects are removed at some very early
>>>>>>>> stage of processing; that is, they don't show up in the linking
>>>>>>>> stage as
>>>>>>>> far as I can tell. Is there any hook point to get such references
>>>>>>>> objects and add the to an appropriate container?
>>>>>>>>
>>>>>>>> cheers,
>>>>>>>>
>>>>>>>> Miles
|
|
|
Re: Processing ecore with non-containment references [message #58829 is a reply to message #58633] |
Wed, 15 July 2009 04:50   |
Eclipse User |
|
|
|
Hi Miles,
I've got the impression that a m2m transformation would be easier ...
> So now in the outline view for the XText editor, the non directly
> contained reference(s) shows up under the container node. But after that
> point it doesn't.
Sorry I didn't get that one.
However, you could try to track any created instance and keep it in a
collection and do the ID<->EObject mapping when setID (or whatever) is
called. So you'll end up with a collection and a map in your custom ast
factory.
Regards,
Sebastian
Am 15.07.2009 0:24 Uhr, schrieb Miles Parker:
> On 2009-07-14 07:26:42 -0700, Sebastian Zarnekow
> <Sebastian.Zarnekow@itemis.de> said:
>
>> Hi Miles,
>>
>> you're right, newly created EObject are first added to their
>> respective container and initialized afterwards. Did you set any
>> specific features on the containment reference itself?
>
> No, not for the non-root referenced nodes, that is. The very first node
> is contained.
>
>> I cannot imagine that any element is removed from an EList when an ID
>> feature is assigned.
>
> Hmm.. yes I think I see what you mean. I'm being a little vague here
> because I haven't yet figured out the internals. I think what might be
> happening is that when I next try to do the M2M, the ids aren't in synch
> somehow..
>
>> Do you use a HashMap internally for your ID<->EObject cache?
>
> I don't actualy have the id at the time of add because they haven't been
> set yet. So I can't hash for ID. Instead, since I have the
> source->target references what I've been doing is the following.
>
> 1) I know that the continment refernces are added after the
> non-containment (acyclic graph) refernces.
> 2) On an add for the root containment reference, I walk through the tree
> of targets and assign the containment reference to be the same root
> containment object.
>
> So now in the outline view for the XText editor, the non directly
> contained reference(s) shows up under the container node. But after that
> point it doesn't.
>
>
>>
>> Regards,
>> Sebastian
>>
>> Am 14.07.2009 2:27 Uhr, schrieb Miles Parker:
>>> Sebastian,
>>>
>>> Based on your guidance, I was able to make a lot of progress. I
>>> impemented a custom EcoreElementFactory, and am able to intercept the
>>> setters and getters. But though I was able to get the containment to
>>> work, I still seem to lose things somewhere along the way! I think I
>>> have an idea of how that happens. The containment references use ID for
>>> key, and that ID is getting overriden. I was able to determine the order
>>> of eveything by instrumenting the custom gactory, and I found that the
>>> adds are happening before the setters. So the references are now getting
>>> added properly, but then the parser comes along and overwrites the IDs
>>> with a (non-null) value and the reference is lost. Really, it seems to
>>> me that in the case of keys, the setters should be happening first in
>>> default case.
>>>
>>> Does my explanation make sense? Any ideas about how to have sets applied
>>> first? Is the order something that is determined purely through grammer
>>> inference process?
>>>
>>> Miles
>>>
>>> On 2009-07-02 13:00:20 -0700, Sebastian Zarnekow
>>> <Sebastian.Zarnekow@itemis.de> said:
>>>
>>>> Hi Miles,
>>>>
>>>> you are right, the instances that are not contained in the model, will
>>>> be erased. However I did not get the clue. How did you instantiate
>>>> these instances and how did the get lost. As far as I know, the parser
>>>> will assign a produced instance to a feature of its container in
>>>> (almost) any case. So actually I'm a little bit puzzled where your
>>>> instances remain :-)
>>>>
>>>> However, any instance that is produced by the parser will be
>>>> eventually created by the registered implementation of the
>>>> IAstFactory-interface. You may want to hook into it and keep track of
>>>> any created instance and use this information later on. I guess you'll
>>>> have to override your parser therefore to do some post processing.
>>>> Have a look at
>>>> org.eclipse.xtext.parser.antlr.AbstractAntlrParser.parse(Str ing,
>>>> ANTLRInputStream) and the concrete implementation for your language.
>>>> org.eclipse.xtext.parser.IAstFactory.create(EClassifier) may be
>>>> interesting as well.
>>>>
>>>> Hope that helps,
>>>> Sebastian
>>>>
>>>>
>>>> Am 02.07.2009 21:32 Uhr, schrieb Miles Parker:
>>>>> On 2009-07-02 12:13:02 -0700, Sebastian Zarnekow
>>>>> <Sebastian.Zarnekow@itemis.de> said:
>>>>>
>>>>>> Hi Miles,
>>>>>>
>>>>>> so you only have edges but no vertices or someting alike?
>>>>>> Can you please post a short snippet of the concrete syntax, that
>>>>>> you'ld like to use? Currently I cannot imagine how it should look
>>>>>> like.
>>>>>
>>>>> Well this is an example, but yes it would have been a better
>>>>> example to
>>>>> just use nodes instead of edges. :)
>>>>>
>>>>>> However, your usecase seems to be a good fit for m2m transformations,
>>>>>> because instances of your Ecore model will likely not be created by a
>>>>>> concise textual notation with Xtext. Or you do all the linking
>>>>>> yourself and create kind of intermediate instances in the parser
>>>>>> parsing (as you already did). But that's m2m, too.
>>>>>
>>>>> Yes, that's exactly what I'm doing. But the problem is that I don't
>>>>> have
>>>>> access to the intermediate instances because they are getting erased
>>>>> from the tree. I'm assuming that this is because they aren't contained
>>>>> somehwere..? If I could make that work then I'd have a much more
>>>>> concise
>>>>> xtext side representation. As you can see its already complex
>>>>> enough and
>>>>> this is only about 20% of it!
>>>>>
>>>>> Here is the concrete syntax:
>>>>>
>>>>> Agent returns SAgent:
>>>>> ID=IDZ
>>>>> ("HAS" attributes+=Attributes ("," attributes+=Attributes)*".")?
>>>>> ("SHOWS" styles+=Style2D ("," styles+=Style2D)*".")?
>>>>> rootActivity=Behaviors;
>>>>>
>>>>>
>>>>> Behaviors returns AGroup :
>>>>> ("DOES" members+=RootRule (";" (members+=RootRule))*".")?"!";
>>>>>
>>>>>
>>>>> RootRule returns ARoot :
>>>>> (Rule | Watch | Initialize | Build) "::" ("[" targets+=NonRoot (","
>>>>> (targets+=NonRoot))* "]")?;
>>>>>
>>>>>
>>>>> Rule returns ARule :
>>>>> ID=IDZ ("IN" space=[SProjection|IDZ])?;
>>>>>
>>>>> NonRoot returns AAct :
>>>>> Select | Create | CreateProjection;
>>>>>
>>>>> Select returns ASelect :
>>>>> (selected=[ASelect|IDZ]"::")?ID=IDZ "SELECTS" agent=[SAgent|IDZ] "IN"
>>>>> space=[SProjection|IDZ] "WHERE" targets+=Query ("AND"
>>>>> targets+=Query)*;
>>>>>
>>>>>
>>>>>
>>>>> Queries are just further nodes in the tree. As you can probably
>>>>> imagine,
>>>>> the way I've been doing this with containment references requires a
>>>>> lot
>>>>> of indirection between the two models.
>>>>>
>>>>> thanks,
>>>>>
>>>>> Miles
>>>>>
>>>>>
>>>>>>
>>>>>> Regards,
>>>>>> Sebastian
>>>>>>
>>>>>>
>>>>>> Am 02.07.2009 20:58 Uhr, schrieb Miles Parker:
>>>>>>> Thanks Sebastian,
>>>>>>>
>>>>>>> I'm not entirely sure that it can't be done with Linker but I
>>>>>>> haven't
>>>>>>> been able to get to a point where I can get this state. But perhaps
>>>>>>> I've
>>>>>>> missed something.
>>>>>>>
>>>>>>> Imagine I want to define a rooted Graph Struture but I need to
>>>>>>> create
>>>>>>> the nodes implicitly as part of the edges. This is part of a
>>>>>>> referenced
>>>>>>> ecore model which is like:
>>>>>>>
>>>>>>> Graph:
>>>>>>> ref members [edges] (containment)
>>>>>>> ref roots [edges] (non-containment 0..*)
>>>>>>>
>>>>>>> Edge:
>>>>>>> ref sources [edges] (non-containment obviously 0..*)
>>>>>>> ref targets [edges] (non-containment obviously 0..*)
>>>>>>>
>>>>>>> And I want to define grammer like (Ithis may not be a good grammer I
>>>>>>> haven't tested it, but just to get the idea):
>>>>>>>
>>>>>>> XGraph returns Graph :
>>>>>>> roots+=[Edge];
>>>>>>>
>>>>>>> XEdge returns Edge :
>>>>>>> targets+=([Edge] | Edge)
>>>>>>>
>>>>>>>
>>>>>>> Now, when the model is saved, I need to gather all of the roots and
>>>>>>> targets and add them to members so that they are contained. Does
>>>>>>> that
>>>>>>> make sense?
>>>>>>>
>>>>>>> I know its possible to make the grammer work (I've already done
>>>>>>> it) by
>>>>>>> adding a bunch of intermediate rules, but that is really not very
>>>>>>> transparant and it hard to maintain.
>>>>>>>
>>>>>>> thanks,
>>>>>>>
>>>>>>> Miles
>>>>>>>
>>>>>>>
>>>>>>> On 2009-07-02 10:47:13 -0700, Sebastian Zarnekow
>>>>>>> <Sebastian.Zarnekow@itemis.de> said:
>>>>>>>
>>>>>>>> Hi Miles,
>>>>>>>>
>>>>>>>> no there is no such hook.
>>>>>>>> Maybe you want to describe what you originally wanted to achieve. I
>>>>>>>> guess there is a solution, that should work with Xtext.
>>>>>>>>
>>>>>>>> Regards,
>>>>>>>> Sebastian
>>>>>>>>
>>>>>>>> Am 02.07.2009 3:54 Uhr, schrieb Miles Parker:
>>>>>>>>>
>>>>>>>>> I'm doing a lot of conversion on a grammer into a native ecore
>>>>>>>>> model.
>>>>>>>>> The ideas Sven gave in
>>>>>>>>> http://dev.eclipse.org/newslists/news.eclipse.modeling.tmf/m sg00403.html
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> worked well for a lot of issues, but here's one I haven't been
>>>>>>>>> able to
>>>>>>>>> solve.
>>>>>>>>>
>>>>>>>>> I have an ecore model in which it is much more natural to
>>>>>>>>> create it
>>>>>>>>> and
>>>>>>>>> the grammer using non-containment references. But if I try this
>>>>>>>>> that
>>>>>>>>> means that the non-contained EObjects are removed at some very
>>>>>>>>> early
>>>>>>>>> stage of processing; that is, they don't show up in the linking
>>>>>>>>> stage as
>>>>>>>>> far as I can tell. Is there any hook point to get such references
>>>>>>>>> objects and add the to an appropriate container?
>>>>>>>>>
>>>>>>>>> cheers,
>>>>>>>>>
>>>>>>>>> Miles
>
>
|
|
|
Re: Processing ecore with non-containment references [message #63001 is a reply to message #58829] |
Fri, 24 July 2009 23:32   |
Eclipse User |
|
|
|
On 2009-07-15 01:50:29 -0700, Sebastian Zarnekow
<Sebastian.Zarnekow@itemis.de> said:
> Hi Miles,
>
> > So now in the outline view for the XText editor, the non directly
> > contained reference(s) shows up under the container node. But after that
> > point it doesn't.
>
> Sorry I didn't get that one.
OK, so I've dug deeper into the internals now, and I can be less
vague.. So let's forget what came before except as background.. ;)
I was able to get the following to work:
1. A "root" node is added through containment.
2. Nodes are added through grammer to ecore non-containment references.
3. I am then able, by overiding Default Ecore containment factory, to
have those added as contained members to the root node above.
4. Those nodes now show up in the target ecore model.
So that's all great.. Something nice (I think) in 4).. I don't even
have to do an M2M transformation. Since all of my source DSL elements
are basically just semantic glue now, I can just read the model in as
..mylanguage and write it back out as .mymodel!
Problem then was, the non-containment references get lost along the
way. "Where" was the part I was vague about before. Here is what was
happening..
1. All of the referrences are created nicely by my overridden element
factory. I have a perfect meta model.
2. Then AbstractCleaningLinker comes along and ruins things by removing
all of the non-containment references!
In following method everything is fine in beforeModelLinked but after
they're gone..
public void linkModel(EObject model, IDiagnosticConsumer
diagnosticsConsumer) {
beforeModelLinked(model, diagnosticsConsumer);
doLinkModel(model, diagnosticsConsumer);
afterModelLinked(model, diagnosticsConsumer);
}
This is the offending method:
protected void clearReference(EObject obj, EReference ref) {
if (!ref.isContainment() && !ref.isContainer() && !ref.isDerived() &&
ref.isChangeable())
obj.eUnset(ref);
}
So I override clearReference to a no-op and it works! Not bad as I've
been mucking with this off and on for the last couple of weeks. Now, my
only question...
Why is this being unset?! Is there something important that the
cleaning linker is doing that I'm no violating?
thanks for all your help,
Miles
|
|
|
Re: Processing ecore with non-containment references [message #63016 is a reply to message #63001] |
Mon, 27 July 2009 03:11   |
Eclipse User |
|
|
|
Hi Miles,
> Why is this being unset?! Is there something important that the cleaning
> linker is doing that I'm no violating?
Yes it is important to unset the cross references, but you may have
guessed that :-)
During the lifecycle of an Xtext based Editor, only one resource is
created (actually the XtextDocument contains it) and - simplified -
anytime the user edits the file, some parts of your model will be
reparsed and substituted by the newly created elements. However, the old
to-be-deleted elements are still cross refed although the are no longer
part of your model. Other elements, that should be refered to instead,
will not be taken into consideration as the reference is already set.
This will lead to missing error markers and invalid models. That's the
reason, why we introduced an AbstractCleaningLinker. So you should make
sure that your algorithm works as expected even in a highly dynamic,
interactive envirnment as the XtextEditor. Maybe it is sufficient to
override clearReference only for a subset of all possible references?
Regards,
Sebastian
--
Need professional support for Eclipse Modeling?
Go visit: http://xtext.itemis.com
Am 25.07.2009 5:32 Uhr, schrieb Miles Parker:
> On 2009-07-15 01:50:29 -0700, Sebastian Zarnekow
> <Sebastian.Zarnekow@itemis.de> said:
>
>> Hi Miles,
>>
>> > So now in the outline view for the XText editor, the non directly
>> > contained reference(s) shows up under the container node. But after
>> that
>> > point it doesn't.
>>
>> Sorry I didn't get that one.
>
> OK, so I've dug deeper into the internals now, and I can be less vague..
> So let's forget what came before except as background.. ;)
>
> I was able to get the following to work:
>
> 1. A "root" node is added through containment.
> 2. Nodes are added through grammer to ecore non-containment references.
> 3. I am then able, by overiding Default Ecore containment factory, to
> have those added as contained members to the root node above.
> 4. Those nodes now show up in the target ecore model.
>
> So that's all great.. Something nice (I think) in 4).. I don't even have
> to do an M2M transformation. Since all of my source DSL elements are
> basically just semantic glue now, I can just read the model in as
> ..mylanguage and write it back out as .mymodel!
>
> Problem then was, the non-containment references get lost along the way.
> "Where" was the part I was vague about before. Here is what was happening..
>
> 1. All of the referrences are created nicely by my overridden element
> factory. I have a perfect meta model.
> 2. Then AbstractCleaningLinker comes along and ruins things by removing
> all of the non-containment references!
>
> In following method everything is fine in beforeModelLinked but after
> they're gone..
>
> public void linkModel(EObject model, IDiagnosticConsumer
> diagnosticsConsumer) {
> beforeModelLinked(model, diagnosticsConsumer);
> doLinkModel(model, diagnosticsConsumer);
> afterModelLinked(model, diagnosticsConsumer);
> }
>
> This is the offending method:
>
> protected void clearReference(EObject obj, EReference ref) {
> if (!ref.isContainment() && !ref.isContainer() && !ref.isDerived() &&
> ref.isChangeable())
> obj.eUnset(ref);
> }
>
> So I override clearReference to a no-op and it works! Not bad as I've
> been mucking with this off and on for the last couple of weeks. Now, my
> only question...
>
> Why is this being unset?! Is there something important that the cleaning
> linker is doing that I'm no violating?
>
>
> thanks for all your help,
>
> Miles
>
>
|
|
|
Re: Processing ecore with non-containment references [message #140428 is a reply to message #63016] |
Mon, 27 July 2009 15:25   |
Eclipse User |
|
|
|
On 2009-07-27 00:11:15 -0700, Sebastian Zarnekow
<Sebastian.Zarnekow@itemis.de> said:
>
> During the lifecycle of an Xtext based Editor, only one resource is
> created (actually the XtextDocument contains it) and - simplified -
> anytime the user edits the file, some parts of your model will be
> reparsed and substituted by the newly created elements. However, the
> old to-be-deleted elements are still cross refed although the are no
> longer part of your model. Other elements, that should be refered to
> instead, will not be taken into consideration as the reference is
> already set. This will lead to missing error markers and invalid
> models. That's the reason, why we introduced an AbstractCleaningLinker.
> So you should make sure that your algorithm works as expected even in a
> highly dynamic, interactive envirnment as the XtextEditor. Maybe it is
> sufficient to override clearReference only for a subset of all possible
> references?
Yes, good idea. But I'm wondering if there is a better way as I will
still have a lot of these. Are you saying for example that perhaps a
user is editing one chunk of text while validation is occuring and that
could create a dangling reference? Would it be safe(r) if I could
somehow ensure that the IDs for the subset do not change while
validating?
More generally, how are these references put back together? Are they
simply rebuilt? In which case perhaps the element factory isn't the
base place to do this after all, or I should be caching the references,
allowing them to be deleted and then putting them back for those items
that are not removed?
Sorry for so many questions..
|
|
|
Re: Processing ecore with non-containment references [message #154957 is a reply to message #140428] |
Mon, 27 July 2009 15:44   |
Eclipse User |
|
|
|
Hi Miles,
please find my comments below.
Am 27.07.2009 21:25 Uhr, schrieb Miles Parker:
> On 2009-07-27 00:11:15 -0700, Sebastian Zarnekow
> <Sebastian.Zarnekow@itemis.de> said:
>
>>
>> During the lifecycle of an Xtext based Editor, only one resource is
>> created (actually the XtextDocument contains it) and - simplified -
>> anytime the user edits the file, some parts of your model will be
>> reparsed and substituted by the newly created elements. However, the
>> old to-be-deleted elements are still cross refed although the are no
>> longer part of your model. Other elements, that should be refered to
>> instead, will not be taken into consideration as the reference is
>> already set. This will lead to missing error markers and invalid
>> models. That's the reason, why we introduced an
>> AbstractCleaningLinker. So you should make sure that your algorithm
>> works as expected even in a highly dynamic, interactive envirnment as
>> the XtextEditor. Maybe it is sufficient to override clearReference
>> only for a subset of all possible references?
>
> Yes, good idea. But I'm wondering if there is a better way as I will
> still have a lot of these. Are you saying for example that perhaps a
> user is editing one chunk of text while validation is occuring and that
> could create a dangling reference? Would it be safe(r) if I could
> somehow ensure that the IDs for the subset do not change while validating?
>
DSL may have a somewhat arbitrary structure and semantic. Xtext tries to
do its best to handle as many use cases as possible in a very grateful
way. That means in terms of linking, that we try hard to avoid any links
that look like successful links but indeed are false ones.
Consider a language which uses a simple "first occurrence first"
semantic when linking objects. If the user deletes the first object, any
cross link to that object has to be recalculated. Because we do not know
about the semantics of your language and the existing cross links
(currently we do not track them), we simply clear any cross links and
recalculate them afterwards.
> More generally, how are these references put back together? Are they
> simply rebuilt? In which case perhaps the element factory isn't the base
> place to do this after all, or I should be caching the references,
> allowing them to be deleted and then putting them back for those items
> that are not removed?
Yes they are simply rebuilt. I'm not sure whether the element factory is
the best place for your particular use case but I guess that's at least
a good match in combination with a scope provider and some algorithm
that removes unused objects.
>
> Sorry for so many questions..
>
You're welcome.
Sebastian
--
Need professional support for Eclipse Modeling?
Go visit: http://xtext.itemis.com
|
|
| |
Re: Processing ecore with non-containment references [message #275427 is a reply to message #246213] |
Mon, 27 July 2009 18:13   |
Eclipse User |
|
|
|
Hi Miles,
I guess you are right, although I assume (actually I hope) that you
mixed linker and element factory up. The element factory instantiates
while the linker establishes the cross links.
Hope that helps,
Sebastian
--
Need professional support for Eclipse Modeling?
Go visit: http://xtext.itemis.com
Am 27.07.2009 23:07 Uhr, schrieb Miles Parker:
> On 2009-07-27 12:44:30 -0700, Sebastian Zarnekow
> <Sebastian.Zarnekow@itemis.de> said:
>>
>> Yes they are simply rebuilt. I'm not sure whether the element factory
>> is the best place for your particular use case but I guess that's at
>> least a good match in combination with a scope provider and some
>> algorithm that removes unused objects.
>
> OK, just to be clear.. I am assuming that by rebuild we are not
> recreating the node objects, just the references. If so, it seems that
> the following general stratregy should work..
>
> 1. Create all of the appropriate target model objects (linker) and
> references (element factory) as I'm doing.
> 2. For any non-containment references we need to retain, overider
> clearReference so that if and only if they no longer have an appropriate
> reference path to an containment object, remove the references.
>
> That would make perfect sense. Put simply, as I have customized behavior
> to allow non-containment references to become containment references,
> the cleaning linker has no way of knowing that. So I need to identify
> those that might be used for containment and treat them in the same way
> that one would treat 'real' containment references. Right?
>
|
|
|
Re: Processing ecore with non-containment references [message #300712 is a reply to message #275427] |
Mon, 27 July 2009 20:21   |
Eclipse User |
|
|
|
Ha. It's a bit more confusing.
First the part about linker isn't important -- I was following your
advice about creating attributes in a prior post
( http://dev.eclipse.org/newslists/news.eclipse.modeling.tmf/m sg00403.html)
and added a singleton as well; it only belongs to one class and isn't
referenced anywhere else, but unless I create, the validator complains.
But it sounds like I can prob. do that in facotry and it's not related
to this issue at all.
But for Ecore element factory, remember that the initial issue was that
the non-contained references never show up in the linker because the
linker seems to rely on their having been added through containment. So
based on a (mis-reading?) of your advice, I overrode add(..) in the
customized ecore element factory as that was the only hook available
for trapping the non-containment reference. This seems an ok use as in
the process of creating and object, references (including containment)
are also created, so I'm simply adding some additional logic there.
Somewhat similar to EMF command pattern.
And so its funny, but because I am not coming from parser world object
and reference creation seem like two sides of the same coin. You create
an object, which needs a reference, which needs another object.., and
you just have to ensure that there isn't any circularity there. So it
isn't obvious to me where the line is drawn.
On 2009-07-27 15:13:44 -0700, Sebastian Zarnekow
<Sebastian.Zarnekow@itemis.de> said:
> Hi Miles,
>
> I guess you are right, although I assume (actually I hope) that you
> mixed linker and element factory up. The element factory instantiates
> while the linker establishes the cross links.
>
> Hope that helps,
> Sebastian
>
> 1. Create all of the appropriate target model objects (linker) and
> references (element factory) as I'm doing.
> 2. For any non-containment references we need to retain, overider
> clearReference so that if and only if they no longer have an appropriate
> reference path to an containment object, remove the references.
>
|
|
|
Re: Processing ecore with non-containment references [message #367057 is a reply to message #300712] |
Tue, 28 July 2009 10:25   |
Eclipse User |
|
|
|
Hi Miles,
it seems to be as I've told you before: Xtext is not a best fit for your
use case. Maybe we should consider an on-site support session to review
the overall design of your metamodel and your approach to provide a
concrete syntax for it.
Your question regarding circular dependencies: EMF handles them very
well with its proxy mechanism. If you install proxies in the first place
for non containment references, they will be resolved by the framework
(unless you explicitly refused it in your metamodel). Proxies that
"point" to the same real object will be resolved to the very same instance.
Generally speaking, the parser instantiates the objects and sets the
containment references. When all objects exist, the linker will step in
and try to establish the cross links. Maybe that's why you are talking
about two sides of the same coin. Both steps together will provide the
final graph of semantic objects.
Regards,
Sebastian
--
Need professional support for Eclipse Modeling?
Go visit: http://xtext.itemis.com
Am 28.07.2009 2:21 Uhr, schrieb Miles Parker:
>
> Ha. It's a bit more confusing.
>
> First the part about linker isn't important -- I was following your
> advice about creating attributes in a prior post
> ( http://dev.eclipse.org/newslists/news.eclipse.modeling.tmf/m sg00403.html)
> and added a singleton as well; it only belongs to one class and isn't
> referenced anywhere else, but unless I create, the validator complains.
> But it sounds like I can prob. do that in facotry and it's not related
> to this issue at all.
>
> But for Ecore element factory, remember that the initial issue was that
> the non-contained references never show up in the linker because the
> linker seems to rely on their having been added through containment. So
> based on a (mis-reading?) of your advice, I overrode add(..) in the
> customized ecore element factory as that was the only hook available for
> trapping the non-containment reference. This seems an ok use as in the
> process of creating and object, references (including containment) are
> also created, so I'm simply adding some additional logic there. Somewhat
> similar to EMF command pattern.
>
> And so its funny, but because I am not coming from parser world object
> and reference creation seem like two sides of the same coin. You create
> an object, which needs a reference, which needs another object.., and
> you just have to ensure that there isn't any circularity there. So it
> isn't obvious to me where the line is drawn.
>
>
> On 2009-07-27 15:13:44 -0700, Sebastian Zarnekow
> <Sebastian.Zarnekow@itemis.de> said:
>
>> Hi Miles,
>>
>> I guess you are right, although I assume (actually I hope) that you
>> mixed linker and element factory up. The element factory instantiates
>> while the linker establishes the cross links.
>>
>> Hope that helps,
>> Sebastian
>
>>
>> 1. Create all of the appropriate target model objects (linker) and
>> references (element factory) as I'm doing.
>> 2. For any non-containment references we need to retain, overider
>> clearReference so that if and only if they no longer have an appropriate
>> reference path to an containment object, remove the references.
>>
>
|
|
|
Understanding the linker, was Re: Processing ecore with non-containment references [message #369114 is a reply to message #367057] |
Tue, 28 July 2009 12:58   |
Eclipse User |
|
|
|
On 2009-07-28 07:25:04 -0700, Sebastian Zarnekow
<Sebastian.Zarnekow@itemis.de> said:
> it seems to be as I've told you before: Xtext is not a best fit for
> your use case. Maybe we should consider an on-site support session to
> review the overall design of your metamodel and your approach to
> provide a concrete syntax for it.
Honestly, this is actually something of an experiment. I'm most
interested in how existing ecore (meta) models and Xtext can interact
-- or more abstractlly the relationship between ideal representations
and textual representations. It's frustrating because everything works
perfectly staticly -- the model doesn't validate constistently
interactivly, but whenever I open and close the editor it does, and the
created ecore native model is perfect. So I'm sure that it can be done
in XText, its just a matter of understanding the limits or perhaps
expanding them. So I do understand that this is mostly something for me
to figure out. :) Basically, it seems that all that is really needed is
some kind of "parse-time linker" (or is that "link-time parser" :))
that allows developers to specify their own semantics for infering
containment references based on cross-references.
The hardest part has been trying to figure out what is going on with
the linker. So for a slightly different question, can you say
something brief about what is going on with "doLink", vs. "linkModel",
before, during, after and then especially the "ensure" versions of
these? And then I'll drop this thread.:)
> Generally speaking, the parser instantiates the objects and sets the
> containment references. When all objects exist, the linker will step in
> and try to establish the cross links. Maybe that's why you are talking
> about two sides of the same coin. Both steps together will provide the
> final graph of semantic objects.
Yep, and the non-containment -> containment bit fits somewhere in the
middle which is where the confusion is because the parser, linker order
is inherently containment -> non-containment! Kind of an interesting
issue.
|
|
|
Re: Understanding the linker, was Re: Processing ecore with non-containment references [message #369139 is a reply to message #369114] |
Tue, 28 July 2009 16:38   |
Eclipse User |
|
|
|
Hi Miles,
I didn't want to scare you ;-) Please feel free to ask anything you want
in the newsgroup. It is as I told you: I got the impression that it
might be more helpful to do some pair programming because at one point
or another I doubt that I fully understand your specific problems.
The lifecycle (when not using the LazyLinker) is as follows:
1) User enters some data.
2) Xtext computes the minimal region that has to be parsed (We do
partial parsing).
3) The partial parsing process will create a semantic object that is
most likely not the root type of your model.
4) Xtext computes the to-be-replaced instance of your model and adds the
newly created instance instead.
5) Thats the point where the linker starts its job.
6) Xtext clears all cross references because we don't want to end up
with any dangling instances (beforeModelLinked).
7) doLinkModel will traverse the model and try to link any cross
reference with an existing AbstractNode (ensureLinked() will be called
for any object beginning at the root with a depth first traversal as
done by EcoreUtil.getAllContents())
8) there are hooks to set default values for any cross reference that
does not have a associated AbstractNode (canSetDefaultValues() +
setDefaultValueImpl())
9) There is a hook to do interesting stuff after the model has been linked.
3*) The parser will create a semantic model which is not linked. Only
containment references and attributes are assigned.
7*) ILinkingService#getLinkedObjects is actually used to compute the
list of objects that should be linked. You may create instances on
demand and return them as linked objects.
Please file a bugzilla for the link-time-parser / parse-time-linker or
whatever you want to call it. I'ld say: Customizable object construction
and grammar <-> metamodel mapping.
Again: Feel free to ask as many questions as you have.
Regards,
Sebastian
--
Need professional support for Eclipse Modeling?
Go visit: http://xtext.itemis.com
Am 28.07.2009 18:58 Uhr, schrieb Miles Parker:
> On 2009-07-28 07:25:04 -0700, Sebastian Zarnekow
> <Sebastian.Zarnekow@itemis.de> said:
>
>> it seems to be as I've told you before: Xtext is not a best fit for
>> your use case. Maybe we should consider an on-site support session to
>> review the overall design of your metamodel and your approach to
>> provide a concrete syntax for it.
>
> Honestly, this is actually something of an experiment. I'm most
> interested in how existing ecore (meta) models and Xtext can interact --
> or more abstractlly the relationship between ideal representations and
> textual representations. It's frustrating because everything works
> perfectly staticly -- the model doesn't validate constistently
> interactivly, but whenever I open and close the editor it does, and the
> created ecore native model is perfect. So I'm sure that it can be done
> in XText, its just a matter of understanding the limits or perhaps
> expanding them. So I do understand that this is mostly something for me
> to figure out. :) Basically, it seems that all that is really needed is
> some kind of "parse-time linker" (or is that "link-time parser" :)) that
> allows developers to specify their own semantics for infering
> containment references based on cross-references.
>
> The hardest part has been trying to figure out what is going on with the
> linker. So for a slightly different question, can you say something
> brief about what is going on with "doLink", vs. "linkModel", before,
> during, after and then especially the "ensure" versions of these? And
> then I'll drop this thread.:)
>
>
>> Generally speaking, the parser instantiates the objects and sets the
>> containment references. When all objects exist, the linker will step
>> in and try to establish the cross links. Maybe that's why you are
>> talking about two sides of the same coin. Both steps together will
>> provide the final graph of semantic objects.
>
> Yep, and the non-containment -> containment bit fits somewhere in the
> middle which is where the confusion is because the parser, linker order
> is inherently containment -> non-containment! Kind of an interesting issue.
>
|
|
|
Re: Understanding the linker, was Re: Processing ecore with non-containment references [message #369535 is a reply to message #369139] |
Tue, 28 July 2009 18:47   |
Eclipse User |
|
|
|
On 2009-07-28 13:38:25 -0700, Sebastian Zarnekow
<Sebastian.Zarnekow@itemis.de> said:
> Hi Miles,
>
> I didn't want to scare you ;-) Please feel free to ask anything you
> want in the newsgroup. It is as I told you: I got the impression that
> it might be more helpful to do some pair programming because at one
> point or another I doubt that I fully understand your specific problems.
Right, thanks. I'm just a poor open source developer ;), but as always
on the look out for a customer that needs what we want to do. (For any
customers listening, that's a joke..)
The life-cycle stuff is *very* helpful.
> The lifecycle (when not using the LazyLinker) is as follows:
> 1) User enters some data.
> 2) Xtext computes the minimal region that has to be parsed (We do
> partial parsing).
> 3) The partial parsing process will create a semantic object that is
> most likely not the root type of your model.
> 4) Xtext computes the to-be-replaced instance of your model and adds
> the newly created instance instead.
And all contained objects of that instance as well?
> 5) Thats the point where the linker starts its job.
> 6) Xtext clears all cross references because we don't want to end up
> with any dangling instances (beforeModelLinked).
> 7) doLinkModel will traverse the model and try to link any cross
> reference with an existing AbstractNode (ensureLinked() will be called
> for any object beginning at the root with a depth first traversal as
> done by EcoreUtil.getAllContents())
> 8) there are hooks to set default values for any cross reference that
> does not have a associated AbstractNode (canSetDefaultValues() +
> setDefaultValueImpl())
> 9) There is a hook to do interesting stuff after the model has been linked.
>
> 3*) The parser will create a semantic model which is not linked. Only
> containment references and attributes are assigned.
> 7*) ILinkingService#getLinkedObjects is actually used to compute the
> list of objects that should be linked. You may create instances on
> demand and return them as linked objects.
>
> Please file a bugzilla for the link-time-parser / parse-time-linker or
> whatever you want to call it. I'ld say: Customizable object
> construction and grammar <-> metamodel mapping.
I will -- after I play around w/ it a bit more -- and I think your
suggestion is more clear. I realized that I misspoke on the last
posting -- For: "that allows developers to specify their own semantics
for [infering containment references based on cross-references]", I
meant "..infering imported model containment references based on
(orthogonal) source DSL containments." Cross-references aren't really
relevant (which again is why this isn't purely a linker issue). More
generally, perhaps we're talking about something like "Support parse
and/or link time transformation of imported meta-models from source
DSL". Transformation is kind of a scary word to be used in this
context, but its more or less what we mean as we're really talking
about a kind of "interactive M2M". I see two possiblities:
1) Just provide some hooks like current linker and scope provider.
Ideally this would provide some kind of abstraction like the EMF
command framework (but perhaps a bit more lightweight ;)) as the
DefaultEcoreElementFactory already does. So basically just record and
re-apply the references that the element factory creates post link
leaving out any dead links. Does that make sense?
2) XText Language constructs that allow this directly. If you did this,
it could be useful outside of the imported meta-model issue, but of
course it is muich more ambitious! I'm thinking of something like being
able to specify side-effects like..
Node returns MNode :
(name=ID)? targets+=Node (parent.members+=targets targets.name="target
of "+name)
I think 1) should work fine.. :)
|
|
|
Re: Understanding the linker, was Re: Processing ecore with non-containment references [message #372065 is a reply to message #369535] |
Wed, 29 July 2009 04:18  |
Eclipse User |
|
|
|
Hi Miles,
please see below.
Am 29.07.2009 0:47 Uhr, schrieb Miles Parker:
> On 2009-07-28 13:38:25 -0700, Sebastian Zarnekow
> <Sebastian.Zarnekow@itemis.de> said:
>
>> Hi Miles,
>>
>> I didn't want to scare you ;-) Please feel free to ask anything you
>> want in the newsgroup. It is as I told you: I got the impression that
>> it might be more helpful to do some pair programming because at one
>> point or another I doubt that I fully understand your specific problems.
>
> Right, thanks. I'm just a poor open source developer ;), but as always
> on the look out for a customer that needs what we want to do. (For any
> customers listening, that's a joke..)
>
> The life-cycle stuff is *very* helpful.
>
Nice to meet you.
>> The lifecycle (when not using the LazyLinker) is as follows:
>> 1) User enters some data.
>> 2) Xtext computes the minimal region that has to be parsed (We do
>> partial parsing).
>> 3) The partial parsing process will create a semantic object that is
>> most likely not the root type of your model.
>> 4) Xtext computes the to-be-replaced instance of your model and adds
>> the newly created instance instead.
>
> And all contained objects of that instance as well?
Correct. The inserted object is the root of a subtree of objects. We
replace the subtree and not a single instance from the middle of a
containment hierachy.
>
>> 5) Thats the point where the linker starts its job.
>> 6) Xtext clears all cross references because we don't want to end up
>> with any dangling instances (beforeModelLinked).
>> 7) doLinkModel will traverse the model and try to link any cross
>> reference with an existing AbstractNode (ensureLinked() will be called
>> for any object beginning at the root with a depth first traversal as
>> done by EcoreUtil.getAllContents())
>> 8) there are hooks to set default values for any cross reference that
>> does not have a associated AbstractNode (canSetDefaultValues() +
>> setDefaultValueImpl())
>> 9) There is a hook to do interesting stuff after the model has been
>> linked.
>>
>> 3*) The parser will create a semantic model which is not linked. Only
>> containment references and attributes are assigned.
>> 7*) ILinkingService#getLinkedObjects is actually used to compute the
>> list of objects that should be linked. You may create instances on
>> demand and return them as linked objects.
>>
>> Please file a bugzilla for the link-time-parser / parse-time-linker or
>> whatever you want to call it. I'ld say: Customizable object
>> construction and grammar <-> metamodel mapping.
>
> I will -- after I play around w/ it a bit more -- and I think your
> suggestion is more clear. I realized that I misspoke on the last posting
> -- For: "that allows developers to specify their own semantics for
> [infering containment references based on cross-references]", I meant
> "..infering imported model containment references based on (orthogonal)
> source DSL containments." Cross-references aren't really relevant (which
> again is why this isn't purely a linker issue). More generally, perhaps
> we're talking about something like "Support parse and/or link time
> transformation of imported meta-models from source DSL". Transformation
> is kind of a scary word to be used in this context, but its more or less
> what we mean as we're really talking about a kind of "interactive M2M".
> I see two possiblities:
>
> 1) Just provide some hooks like current linker and scope provider.
> Ideally this would provide some kind of abstraction like the EMF command
> framework (but perhaps a bit more lightweight ;)) as the
> DefaultEcoreElementFactory already does. So basically just record and
> re-apply the references that the element factory creates post link
> leaving out any dead links. Does that make sense?
>
> 2) XText Language constructs that allow this directly. If you did this,
> it could be useful outside of the imported meta-model issue, but of
> course it is muich more ambitious! I'm thinking of something like being
> able to specify side-effects like..
>
> Node returns MNode :
> (name=ID)? targets+=Node (parent.members+=targets targets.name="target
> of "+name)
>
> I think 1) should work fine.. :)
>
Well I like both ideas. But they scare me anyway :-)
It would be quite interesting to plug some kind of bidirectional
transformation between the actual content of the resource and the result
of the parser+linker. This would raise the requirement to trace to the
originating instances to find the respective regions in the text for
various operations in the IDE ... Sounds complicated as well :-)
Regards,
Sebastian
--
Need professional support for Eclipse Modeling?
Go visit: http://xtext.itemis.com
|
|
|
Goto Forum:
Current Time: Mon May 12 08:49:28 EDT 2025
Powered by FUDForum. Page generated in 0.09194 seconds
|