Home » Modeling » EMF » problems with eSet function
problems with eSet function [message #419847] |
Mon, 09 June 2008 17:58 |
Aline Messages: 32 Registered: July 2009 |
Member |
|
|
Hi,
I have some issues with the eSet function... I think there are some
subtilities I don't know.
Here is my first problem:
I have two editors, the first one is the EMF-generated one, and the second
is mine. I have a problem when I changed the value of a combobox in the
property view. When the value is changed, the object is updated in both
editors. But, there is no dirty mark and when, I closed the application
and restart it, the changes are of course not taken in account.
I've implemented IPropertySource so the properties' management is entirely
done by me. Maybe I've done sthg wrong... :(
My second problem is that I'm trying to do the same dialog box shown when
you tried to associate objects to each other (EReference). In my model,
you can associate arrows to different bows. When I choose to associate a
new arrow, it is not added and the previous arrows are also deleted. In
debug mode, I noticed that the arrows were correctly added before being
deleted in the end (I don't know where exactly because it was after a loop
or sthg...)
For both problems, I do something like that :
EList<EObject> eList = (EList<EObject>) eObject.eGet(feature);
eObject.eSet(feature, eList);
Apparently, it is only for objects instance of ManyInverse :s
I don't know if more code samples are needed... I'm afraid there will be
too much
Can anyone help me ?
Thanks in advance,
Aline
|
|
|
Re: problems with eSet function [message #419848 is a reply to message #419847] |
Mon, 09 June 2008 18:17 |
Ed Merks Messages: 33140 Registered: July 2009 |
Senior Member |
|
|
Aline,
Comments below.
Aline wrote:
> Hi,
>
> I have some issues with the eSet function... I think there are some
> subtilities I don't know.
>
> Here is my first problem:
> I have two editors, the first one is the EMF-generated one, and the
> second is mine. I have a problem when I changed the value of a
> combobox in the property view. When the value is changed, the object
> is updated in both editors. But, there is no dirty mark and when, I
> closed the application and restart it, the changes are of course not
> taken in account.
The EMF one keeps track of dirtiness using the command stack. Only if
commands are being executed properly will it know the state is dirty.
> I've implemented IPropertySource so the properties' management is
> entirely done by me. Maybe I've done sthg wrong... :(
I wonder why you'd need to do that? The item providers support it
already...
>
> My second problem is that I'm trying to do the same dialog box shown
> when you tried to associate objects to each other (EReference). In my
> model, you can associate arrows to different bows. When I choose to
> associate a new arrow, it is not added and the previous arrows are
> also deleted. In debug mode, I noticed that the arrows were correctly
> added before being deleted in the end (I don't know where exactly
> because it was after a loop or sthg...)
It sounds like perhaps some bidirectional stuff is involved.
>
>
> For both problems, I do something like that :
>
> EList<EObject> eList = (EList<EObject>) eObject.eGet(feature);
> eObject.eSet(feature, eList);
You should be using commands if you want to support undo (and of course
the command stack helps with dirtiness as well).
This is also kind of a standard mistake folks make. If you get the
list, you can modify it directly. There's no need to set it back. And
in fact, when you call eSet with a list, the target list is cleared
first, and then the new contents are added using addAll. So of course
if the target list and the source list are the same object, the net
effect is to clear the source and the target and then to add the empty
source to the empty target.
>
> Apparently, it is only for objects instance of ManyInverse :s
>
> I don't know if more code samples are needed... I'm afraid there will
> be too much
You really should be using commands since I imagine you'll want to
support undo and redo.
>
> Can anyone help me ?
If you want to manipulate the model and not have command stack support
that's fine. Just don't eSet a list to itself. You'll need to track
dirtiness too. You could use Resource.setTrackingModification(true) to
track isModified on the resource.
>
> Thanks in advance,
>
> Aline
>
>
Ed Merks
Professional Support: https://www.macromodeling.com/
|
|
|
Re: problems with eSet function [message #419849 is a reply to message #419848] |
Mon, 09 June 2008 19:21 |
Aline Messages: 32 Registered: July 2009 |
Member |
|
|
Hi,
thanks for your quick response.
Ed Merks wrote:
>> I've implemented IPropertySource so the properties' management is
>> entirely done by me. Maybe I've done sthg wrong... :(
> I wonder why you'd need to do that? The item providers support it
> already...
I did that because my editor is not directly based on EMF. I use a
graphical library and I thought that I had to do the link between EMF and
my graphical items.
>> For both problems, I do something like that :
>>
>> EList<EObject> eList = (EList<EObject>) eObject.eGet(feature);
>> eObject.eSet(feature, eList);
> You should be using commands if you want to support undo (and of course
> the command stack helps with dirtiness as well).
My mistake, for the second problem I modified the list before the eSet
function. But I think it doesn't change a lot.. ^^!
I tried to do that :
Command setCommande = SetCommand.create(editingDomain, eObject, feature,
value);
if ( setCommande.canExecute() )
editingDomain.getCommandStack().execute(setCommande);
but the command are not executable, that's why I tried with eSet since it
worked with properties (textproperty).
I will see more carefully your comments tomorrow at work ^^! Thanks again
for your rapidity,
Aline
|
|
|
Re: problems with eSet function [message #419864 is a reply to message #419849] |
Tue, 10 June 2008 11:23 |
Aline Messages: 32 Registered: July 2009 |
Member |
|
|
Hi Ed,
I replace all the eSet function with a SetCommand command and it solves
the problem with the combobox (it was not that simple of course ^^). Thank
you :p
But I still have a problem for the second problem :(
When an arrow is added to the list of arrows, the value is a list but
apparently, the command is not executed here, but when I clicked on "OK"
button (which is logical). At that moment, it seems that the value is an
Integer and the feature is expecting a List.
Here is a sample of my code :
...
else if ( eObject.eGet(feature) instanceof ManyInverse ) {
if ( value instanceof ManyInverse )
setCommande = SetCommand.create(editingDomain, eObject, feature,
(List)value);
}
...
if ( setCommande != null && setCommande.canExecute() ) {
System.err.println("-->> execution de la commande <<--");
editingDomain.getCommandStack().execute(setCommande);
}
It seems weird to me to make a test on value because the variable
"setCommande" can be null.
Can you help me ?
Thank you in advance,
Aline
|
|
|
Re: problems with eSet function [message #419868 is a reply to message #419864] |
Tue, 10 June 2008 12:09 |
Ed Merks Messages: 33140 Registered: July 2009 |
Senior Member |
|
|
Aline,
Comments below.
Aline wrote:
> Hi Ed,
>
> I replace all the eSet function with a SetCommand command and it
> solves the problem with the combobox (it was not that simple of course
> ^^). Thank you :p
> But I still have a problem for the second problem :(
>
> When an arrow is added to the list of arrows, the value is a list but
> apparently, the command is not executed here, but when I clicked on
> "OK" button (which is logical). At that moment, it seems that the
> value is an Integer and the feature is expecting a List.
> Here is a sample of my code :
>
> ...
>
> else if ( eObject.eGet(feature) instanceof ManyInverse ) {
> if ( value instanceof ManyInverse )
> setCommande = SetCommand.create(editingDomain, eObject,
> feature, (List)value);
This is making me think that "value" is actually directly the list
returned by an eGet...
> }
>
> ...
>
> if ( setCommande != null && setCommande.canExecute() ) {
> System.err.println("-->> execution de la commande <<--");
> editingDomain.getCommandStack().execute(setCommande);
> }
>
> It seems weird to me to make a test on value because the variable
> "setCommande" can be null.
>
> Can you help me ?
Be sure when you are editing, that you make a copy of the list, change
that copy, and use that as the value you set.
> Thank you in advance,
>
> Aline
>
Ed Merks
Professional Support: https://www.macromodeling.com/
|
|
| |
Re: problems with eSet function [message #419875 is a reply to message #419868] |
Tue, 10 June 2008 14:27 |
Eclipse User |
|
|
|
Originally posted by: richkulp.us.NO_SPAM.ibm.com
Hi Ed,
Isn't there a SetCommand that allows one to just insert/change/remove an
individual entry from a list?
It seems pretty heavy that you have to:
--Be sure when you are editing, that you make a copy of the list, change
that copy, and use that as the value you set.
If the feature was a containment feature that would cause a lot of churn
as it unsets and resets the container of each eObject in the list.
--
Thanks,
Rich Kulp
|
|
| |
Re: problems with eSet function [message #419879 is a reply to message #419877] |
Tue, 10 June 2008 17:53 |
Eclipse User |
|
|
|
Originally posted by: richkulp.us.NO_SPAM.ibm.com
Hi Ed,
I just didn't see that. My mistake. All I saw was your recommendation of
making a complete copy of the list and the setting the entire list back
into the setting using the command. That implied to me a complete clear
of the old list and then set in the new list. I didn't know the command
was smart enough to see that it could do it in an incremental way and
not remove those that were the same in both the before and after list.
--
Thanks,
Rich Kulp
|
|
|
Re: problems with eSet function [message #420104 is a reply to message #419879] |
Wed, 18 June 2008 07:50 |
Aline Messages: 32 Registered: July 2009 |
Member |
|
|
Hi,
I have some issues again concerning commands ^^!
When I execute a SetCommand, it seems that it is executed twice... :(
Here is my command :
System.err.println("AM>> property changed:");
Command setCommand = null;
if ( ... )
...
...
else if ( eObject.eGet(feature) instanceof
org.eclipse.emf.ecore.util.EObjectWithInverseResolvingEList. ManyInverse ||
eObject.eGet(feature) instanceof
org.eclipse.emf.ecore.util.EObjectWithInverseEList.ManyInver se) {
if ( value instanceof
org.eclipse.emf.ecore.util.EObjectWithInverseResolvingEList. ManyInverse ||
value instanceof
org.eclipse.emf.ecore.util.EObjectWithInverseEList.ManyInver se )
setCommand = SetCommand.create(editingDomain, eObject, feature,
(List)value);
}
else
setCommand = SetCommand.create(editingDomain, eObject, feature, value);
/* execution de la commande de set */
if ( setCommand != null && setCommand.canExecute() ) {
System.err.println("-->> execution de la commande <<--");
editingDomain.getCommandStack().execute(setCommand);
}
The output in the console is :
AM>> property changed:
-->> execution de la commande <<--
AM>> property changed:
So the command seems to be executed only once.
But the XML-file looks like this :
<membres nom="toto" prenom=""
estAssignee="//@phases.0/@actions.0/@taches.0
//@phases.0/@actions.0/@taches.0"/>
And there are two affectations.
So of course, when I reload the file, I have an exception:
org.eclipse.emf.ecore.resource.impl.ResourceSetImpl$1Diagnos ticWrappedException:
org.eclipse.emf.ecore.xmi.IllegalValueException: Value
'projet.impl.TacheImpl@4d28c7 (ddptot: null, ddptard: null, dfptot: null,
dfptard: null, estCritique: false, dateDebut: Tue Jun 16 14:42:26 CEST
3908, dateFin: Sat Jun 20 14:42:29 CEST 3908, progression: 10.0)' is not
legal.
And when I remove the second affectation, the file is loaded.
Can anyone help me ? (I don't know if there are enough information... :s)
Thanks in advance,
Aline
|
|
|
Re: problems with eSet function [message #420111 is a reply to message #420104] |
Wed, 18 June 2008 10:40 |
Ed Merks Messages: 33140 Registered: July 2009 |
Senior Member |
|
|
Aline,
Comments below.
Aline wrote:
> Hi,
>
>
>
> I have some issues again concerning commands ^^!
>
>
>
> When I execute a SetCommand, it seems that it is executed twice... :(
>
>
>
> Here is my command :
>
>
>
> System.err.println("AM>> property changed:");
>
> Command setCommand = null;
>
> if ( ... )
>
> ...
>
> ..
>
> else if ( eObject.eGet(feature) instanceof
> org.eclipse.emf.ecore.util.EObjectWithInverseResolvingEList. ManyInverse
> ||
> eObject.eGet(feature) instanceof
> org.eclipse.emf.ecore.util.EObjectWithInverseEList.ManyInver se) {
I really don't expect this kind of testing of the value's implementation
class. I'd expect you to look at the feature itself, test that it's an
EReference, test that it has an opposite and test that the feature has
isMany true.
>
> if ( value instanceof
> org.eclipse.emf.ecore.util.EObjectWithInverseResolvingEList. ManyInverse
> || value instanceof
> org.eclipse.emf.ecore.util.EObjectWithInverseEList.ManyInver se )
The fact that the value is clearly a list implementation being used by
some object to hold its value seems highly unlikely to be a good thing.
>
> setCommand = SetCommand.create(editingDomain, eObject,
> feature, (List)value);
Most likely you need to copy the list, i.e., new ArrayList((List)value).
>
> }
>
> else
>
> setCommand = SetCommand.create(editingDomain, eObject, feature,
> value);
>
>
>
> /* execution de la commande de set */
>
> if ( setCommand != null && setCommand.canExecute() ) {
>
> System.err.println("-->> execution de la commande <<--");
>
> editingDomain.getCommandStack().execute(setCommand);
>
> }
>
>
>
> The output in the console is :
>
>
>
> AM>> property changed:
>
> -->> execution de la commande <<--
>
>
>
> AM>> property changed:
>
>
>
> So the command seems to be executed only once.
>
> But the XML-file looks like this :
>
>
>
> <membres nom="toto" prenom=""
> estAssignee="//@phases.0/@actions.0/@taches.0
> //@phases.0/@actions.0/@taches.0"/>
>
> And there are two affectations.
>
>
>
> So of course, when I reload the file, I have an exception:
>
>
>
> org.eclipse.emf.ecore.resource.impl.ResourceSetImpl$1Diagnos ticWrappedException:
> org.eclipse.emf.ecore.xmi.IllegalValueException: Value
> 'projet.impl.TacheImpl@4d28c7 (ddptot: null, ddptard: null, dfptot:
> null, dfptard: null, estCritique: false, dateDebut: Tue Jun 16
> 14:42:26 CEST 3908, dateFin: Sat Jun 20 14:42:29 CEST 3908,
> progression: 10.0)' is not legal.
>
>
>
> And when I remove the second affectation, the file is loaded.
>
>
>
> Can anyone help me ? (I don't know if there are enough information... :s)
>
>
>
> Thanks in advance,
>
> Aline
>
Ed Merks
Professional Support: https://www.macromodeling.com/
|
|
|
Re: problems with eSet function [message #420114 is a reply to message #420111] |
Wed, 18 June 2008 12:25 |
Aline Messages: 32 Registered: July 2009 |
Member |
|
|
Hi,
Ed Merks wrote:
>> else if ( eObject.eGet(feature) instanceof
>> org.eclipse.emf.ecore.util.EObjectWithInverseResolvingEList. ManyInverse
>> ||
>> eObject.eGet(feature) instanceof
>> org.eclipse.emf.ecore.util.EObjectWithInverseEList.ManyInver se) {
> I really don't expect this kind of testing of the value's implementation
> class. I'd expect you to look at the feature itself, test that it's an
> EReference, test that it has an opposite and test that the feature has
> isMany true.
ok thanks. I also replace the different EList by EObjectEList so it is
simplier.
>> if ( value instanceof
>> org.eclipse.emf.ecore.util.EObjectWithInverseResolvingEList. ManyInverse
>> || value instanceof
>> org.eclipse.emf.ecore.util.EObjectWithInverseEList.ManyInver se )
> The fact that the value is clearly a list implementation being used by
> some object to hold its value seems highly unlikely to be a good thing.
The value is a List the first time the command is executed (it is given in
the parameters of the function). The second time, it is an Integer. So if
I manage to execute the command only once, the if condition will
disappear. But are you saying that the value mustn't be a List ? If so,
how is it possible to update a list of values ? The SetCommand command
will do it automatically with the value to add ? But if there are many
values to add, it means that I have to do a loop for each values in the
list ?
>>
>> setCommand = SetCommand.create(editingDomain, eObject,
>> feature, (List)value);
> Most likely you need to copy the list, i.e., new ArrayList((List)value).
Indeed, the value already is a copy. I have some kind of a MVC
architecture. The value is duplicated in the view and the command is
executed in the model. Like this :
view:
EObjectEList<EObject> eList = (EObjectEList<EObject>) _eObject.eGet(_feature);
EObjectEList<EObject> eListCopy = (EObjectEList<EObject>) eList.clone();
eListCopy.removeAll(_eSelectedOwned);
ArcheryEditorAdvisor.controller.notifyPropertyChanged(_eObje ct, _feature,
eListCopy);
model:
public void notifyPropertyChanged(EObject eObject, EStructuralFeature
feature, Object value) {
...
if ( setCommand != null && setCommand.canExecute() ) {
System.err.println("-->> execution de la commande <<--");
editingDomain.getCommandStack().execute(setCommand);
}
}
But the command is still executed twice :(
Any ideas ?
Thanks,
Aline
|
|
|
Re: problems with eSet function [message #420120 is a reply to message #420114] |
Wed, 18 June 2008 15:22 |
Ed Merks Messages: 33140 Registered: July 2009 |
Senior Member |
|
|
Aline,
Comments below.
Aline wrote:
> Hi,
> Ed Merks wrote:
>>> else if ( eObject.eGet(feature) instanceof
>>> org.eclipse.emf.ecore.util.EObjectWithInverseResolvingEList. ManyInverse
>>> ||
>>> eObject.eGet(feature) instanceof
>>> org.eclipse.emf.ecore.util.EObjectWithInverseEList.ManyInver se) {
>> I really don't expect this kind of testing of the value's
>> implementation class. I'd expect you to look at the feature itself,
>> test that it's an EReference, test that it has an opposite and test
>> that the feature has isMany true.
>
> ok thanks. I also replace the different EList by EObjectEList so it is
> simplier.
I'm just kind of bothered that this is information you can determine
from the feature itself, without making assumptions about the list
implementation being used to implement the value.
>
>>> if ( value instanceof
>>> org.eclipse.emf.ecore.util.EObjectWithInverseResolvingEList. ManyInverse
>>> || value instanceof
>>> org.eclipse.emf.ecore.util.EObjectWithInverseEList.ManyInver se )
>> The fact that the value is clearly a list implementation being used
>> by some object to hold its value seems highly unlikely to be a good
>> thing.
>
> The value is a List the first time the command is executed (it is
> given in the parameters of the function).
Where'd the list come from.? Why is it a list exactly like one that an
EObject uses to represent the state of a multi-valued feature.
> The second time, it is an Integer.
Hmmm.
> So if I manage to execute the command only once, the if condition will
> disappear. But are you saying that the value mustn't be a List ?
I'm wondering why it's a list just like the one used to represent the
state of a multi-valued feature. It's expect the value to be an
ArrayList or something like that.
> If so, how is it possible to update a list of values ?
Yes, by specifying a list representing the desired values. But that
list should not be a list that's liable to change as the target list is
being updated.
> The SetCommand command will do it automatically with the value to add
> ? But if there are many values to add, it means that I have to do a
> loop for each values in the list ?
It should do that all automatically.
>
>>>
>>> setCommand = SetCommand.create(editingDomain, eObject,
>>> feature, (List)value);
>> Most likely you need to copy the list, i.e., new ArrayList((List)value).
>
> Indeed, the value already is a copy.
Then why is it an implementation of a special list, just like the one
used in a multi-valued feature?
> I have some kind of a MVC architecture. The value is duplicated in the
> view and the command is executed in the model. Like this :
>
> view: EObjectEList<EObject> eList = (EObjectEList<EObject>)
> _eObject.eGet(_feature);
>
> EObjectEList<EObject> eListCopy = (EObjectEList<EObject>) eList.clone();
Oh dear. You don't want a clone. A clone will still behave in a
fashion to do bidirectional updates. Just use new ArrayList(...).
>
> eListCopy.removeAll(_eSelectedOwned);
> ArcheryEditorAdvisor.controller.notifyPropertyChanged(_eObje ct,
> _feature, eListCopy);
>
> model:
> public void notifyPropertyChanged(EObject eObject, EStructuralFeature
> feature, Object value) {
>
> ...
> if ( setCommand != null && setCommand.canExecute() ) {
>
> System.err.println("-->> execution de la commande <<--");
>
> editingDomain.getCommandStack().execute(setCommand);
>
> }
> }
>
> But the command is still executed twice :(
Cloning looks like a bad idea.
>
> Any ideas ?
> Thanks,
>
> Aline
>
Ed Merks
Professional Support: https://www.macromodeling.com/
|
|
| |
Re: problems with eSet function [message #420152 is a reply to message #420149] |
Thu, 19 June 2008 12:50 |
Ed Merks Messages: 33140 Registered: July 2009 |
Senior Member |
|
|
Aline,
Comments below.
Aline wrote:
> Hi,
>
>
> Ed Merks wrote:
>>> else if ( eObject.eGet(feature) instanceof
> org.eclipse.emf.ecore.util.EObjectWithInverseResolvingEList. ManyInverse
> ||
>>> eObject.eGet(feature) instanceof
> org.eclipse.emf.ecore.util.EObjectWithInverseEList.ManyInver se) {
>> I'm just kind of bothered that this is information you can determine
>> from the feature itself, without making assumptions about the list
>> implementation being used to implement the value.
>
> Do you mean that "instanceof" must disappear ? (sorry my english is
> not good enough). Now, this line has changed like you said with the
> different tests on the feature. I also removed all the EObjectEList
> objects and replaced them by ArrayList like you said.
Yes. As I said, I'd expect you'd test the feature's isMany, test that
is an instance of EReference, and test whether that reference has an
opposite.
>
>>> The second time, it is an Integer.
>> Hmmm.
>
> I totally agree.
>>> EObjectEList<EObject> eListCopy = (EObjectEList<EObject>)
>>> eList.clone();
>> Oh dear. You don't want a clone. A clone will still behave in a
>> fashion to do bidirectional updates. Just use new ArrayList(...).
>
> ok XD I changed it ^^
>
>>> But the command is still executed twice :(
>> Cloning looks like a bad idea.
>
> I removed all the clones but it is still executed twice T__T. Maybe
> there is something I've done wrong before...
No doubt, but I can only deduce things from the information you provide
and I see nothing giving me useful clues with regard to this problem.
> I'm wondering why there is the same uri twice in the XML-file even if
> the command seems to be executed only once...
It's extremely difficult to add duplicates to a list! I'm not sure how
that would have been accomplished...
> And when I removed the EReference object, both uris are removed :s
>
> Thank you very much for your explanations. I wanted to buy the EMF
> book second edition but it seems that it is not released yet in France
> and I'm a little hesitant to buy a book (the first edition) which can
> be deprecated a few months after.
Yes, it makes more sense to buy the new edition, but it is available
online as a rough cut. It's almost done...
>
> Aline
>
Ed Merks
Professional Support: https://www.macromodeling.com/
|
|
| |
Goto Forum:
Current Time: Wed Apr 24 22:08:09 GMT 2024
Powered by FUDForum. Page generated in 0.04238 seconds
|