Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » EMF » SetCommand and Bidirectional references
SetCommand and Bidirectional references [message #383671] Mon, 05 April 2004 19:35 Go to next message
Michal Antkiewicz is currently offline Michal AntkiewiczFriend
Messages: 16
Registered: July 2009
Junior Member
In my model I had the following classes:
A{
}
B {
A a;
}
and I was subclassing SetCommand to set the reference a
and do some additional stuff.

Now I want to have:
A {
B b; // opposite="a" resolveProxies="false"
}
B {
A a; // opposite="b" resolveProxies="false"
}

After changing that createSetCommand of BItemProvider is
no longer executed!

What's the problem? SetCommand is not used with bidirectional
references? What to do?

To clarify, B can have one A, and A can be referenced by many B.

Michal Antkiewicz
Re: SetCommand and Bidirectional references [message #383674 is a reply to message #383671] Mon, 05 April 2004 20:46 Go to previous messageGo to next message
Ed Merks is currently offline Ed MerksFriend
Messages: 33113
Registered: July 2009
Senior Member
Michal,

Setting A's b will automatically set B's a, so a command to update the
opposite isn't needed.


Michal Antkiewicz wrote:

> In my model I had the following classes:
> A{
> }
> B {
> A a;
> }
> and I was subclassing SetCommand to set the reference a
> and do some additional stuff.
>
> Now I want to have:
> A {
> B b; // opposite="a" resolveProxies="false"
> }
> B {
> A a; // opposite="b" resolveProxies="false"
> }
>
> After changing that createSetCommand of BItemProvider is
> no longer executed!
>
> What's the problem? SetCommand is not used with bidirectional
> references? What to do?
>
> To clarify, B can have one A, and A can be referenced by many B.
>
> Michal Antkiewicz


Ed Merks
Professional Support: https://www.macromodeling.com/
Re: SetCommand and Bidirectional references [message #383675 is a reply to message #383674] Mon, 05 April 2004 20:58 Go to previous messageGo to next message
Michal Antkiewicz is currently offline Michal AntkiewiczFriend
Messages: 16
Registered: July 2009
Junior Member
Yes I know, but the problem is, that I want to extend the SetCommand to be
a compound command and do some additional things.

I have already done that and everything worked excelent. After I've made
the reference bidirectional the createSetCommand of BItemProvider is no
longer executed. I have code like that (BItemProvider):

protected Command createSetCommand(EditingDomain domain, EObject owner,
EStructuralFeature feature, Object value) {
if (feature == ExamplePackage.eINSTANCE.getB_A()) {
return new SetACommand(domain, owner, feature, value);
}
return super.createSetCommand(domain, owner, feature, value);
}

And this SetACommand is a compound command.


The model is (again, updated)
A {
EList b; // type="B" opposite="a" resolveProxies="false"
}
B {
A a; // opposite="b" resolveProxies="false"
}

a references at most one A. When setting this reference I want do
perform additional actions that's why I have extended SetCommand.

Michal
Re: SetCommand and Bidirectional references [message #383676 is a reply to message #383675] Mon, 05 April 2004 21:30 Go to previous messageGo to next message
Ed Merks is currently offline Ed MerksFriend
Messages: 33113
Registered: July 2009
Senior Member
Michal,

All you can really do is include the same kind of logic at the A side of
things...


Michal Antkiewicz wrote:

> Yes I know, but the problem is, that I want to extend the SetCommand to be
> a compound command and do some additional things.
>
> I have already done that and everything worked excelent. After I've made
> the reference bidirectional the createSetCommand of BItemProvider is no
> longer executed. I have code like that (BItemProvider):
>
> protected Command createSetCommand(EditingDomain domain, EObject owner,
> EStructuralFeature feature, Object value) {
> if (feature == ExamplePackage.eINSTANCE.getB_A()) {
> return new SetACommand(domain, owner, feature, value);
> }
> return super.createSetCommand(domain, owner, feature, value);
> }
>
> And this SetACommand is a compound command.
>
> The model is (again, updated)
> A {
> EList b; // type="B" opposite="a" resolveProxies="false"
> }
> B {
> A a; // opposite="b" resolveProxies="false"
> }
>
> a references at most one A. When setting this reference I want do
> perform additional actions that's why I have extended SetCommand.
>
> Michal


Ed Merks
Professional Support: https://www.macromodeling.com/
Re: SetCommand and Bidirectional references [message #383677 is a reply to message #383675] Mon, 05 April 2004 21:28 Go to previous messageGo to next message
Frank Budinsky is currently offline Frank BudinskyFriend
Messages: 478
Registered: July 2009
Senior Member
Michal,

Doesn't the SetACommand need to be constructed with feature
ExamplePackage.eINSTANCE.getA_B() and with the value and owner arguments
reversed?

Frank.

Michal Antkiewicz wrote:

> Yes I know, but the problem is, that I want to extend the SetCommand to be
> a compound command and do some additional things.
>
> I have already done that and everything worked excelent. After I've made
> the reference bidirectional the createSetCommand of BItemProvider is no
> longer executed. I have code like that (BItemProvider):
>
> protected Command createSetCommand(EditingDomain domain, EObject owner,
> EStructuralFeature feature, Object value) {
> if (feature == ExamplePackage.eINSTANCE.getB_A()) {
> return new SetACommand(domain, owner, feature, value);
> }
> return super.createSetCommand(domain, owner, feature, value);
> }
>
> And this SetACommand is a compound command.
>
> The model is (again, updated)
> A {
> EList b; // type="B" opposite="a" resolveProxies="false"
> }
> B {
> A a; // opposite="b" resolveProxies="false"
> }
>
> a references at most one A. When setting this reference I want do
> perform additional actions that's why I have extended SetCommand.
>
> Michal
Re: SetCommand and Bidirectional references [message #383678 is a reply to message #383677] Tue, 06 April 2004 00:03 Go to previous messageGo to next message
Michal Antkiewicz is currently offline Michal AntkiewiczFriend
Messages: 16
Registered: July 2009
Junior Member
Well, not. When setting B.a reference. I need to get
ExamplePackage.eINSTANCE.getB_A() feature.
The theory is: "BItemProvider acts as a command factory for B".

But I was observing ItemProviderAdapter.class in the debugger. So what
really happens when setting B.a reference (choosing A in properties view
of an editor) is that AItemProvider creates two commands:
- RemoveCommand for ExamplePackage.eINSTANCE.getA_B() feature to
remove B from previous reference of old A.
- AddCommand for ExamplePackage.eINSTANCE.getA_B() feature to
add B to reference A.b of a new A.

Of course, because this is a bidirectional reference B.a is set
automatically, but
there is no command doing that!

So the solution I see is to extend that AddCommand on A side to do these
additional operations for B. But this looks like very ugly solution.
Higher coupling and bad design....

My problem is, that when choosing A for B, I have to create a couple of
things
for B and set-up some references properly to make model consistent. That's
bad
I have to put this whole logic to AItemProvider.

Thanks,
Michal Antkiewicz

> Doesn't the SetACommand need to be constructed with feature
> ExamplePackage.eINSTANCE.getA_B() and with the value and owner arguments
> reversed?
>
> Michal Antkiewicz wrote:
>
> > Yes I know, but the problem is, that I want to extend the SetCommand to
be
> > a compound command and do some additional things.
> >
> > I have already done that and everything worked excelent. After I've made
> > the reference bidirectional the createSetCommand of BItemProvider is no
> > longer executed. I have code like that (BItemProvider):
> >
> > protected Command createSetCommand(EditingDomain domain, EObject owner,
> > EStructuralFeature feature, Object value) {
> > if (feature == ExamplePackage.eINSTANCE.getB_A()) {
> > return new SetACommand(domain, owner, feature, value);
> > }
> > return super.createSetCommand(domain, owner, feature, value);
> > }
> >
> > And this SetACommand is a compound command.
> >
> > The model is (again, updated)
> > A {
> > EList b; // type="B" opposite="a" resolveProxies="false"
> > }
> > B {
> > A a; // opposite="b" resolveProxies="false"
> > }
> >
> > a references at most one A. When setting this reference I want do
> > perform additional actions that's why I have extended SetCommand.
> >
> > Michal
>
Re: SetCommand and Bidirectional references [message #383679 is a reply to message #383678] Tue, 06 April 2004 10:14 Go to previous messageGo to next message
Ed Merks is currently offline Ed MerksFriend
Messages: 33113
Registered: July 2009
Senior Member
Michal,

When you have a bidirectional reference between A and B, it's fair to say that
they are tightly coupled and that both are intimately aware of the other; their
packages, if they are in separate packages, will be mutually dependant. When
the A side is many-valued, that's really the side that should be manipulated
directly since this is the side from which you can control the order of the
Bs. Since your design is such that when a, A-B relation is established,
something special needs to be done on one of the ends, it doesn't really seem to
make significant design difference which end does the special handling; you can
always get A to ask B to create some type of user-defined command to do it's own
special thing...


Michal Antkiewicz wrote:

> Well, not. When setting B.a reference. I need to get
> ExamplePackage.eINSTANCE.getB_A() feature.
> The theory is: "BItemProvider acts as a command factory for B".
>
> But I was observing ItemProviderAdapter.class in the debugger. So what
> really happens when setting B.a reference (choosing A in properties view
> of an editor) is that AItemProvider creates two commands:
> - RemoveCommand for ExamplePackage.eINSTANCE.getA_B() feature to
> remove B from previous reference of old A.
> - AddCommand for ExamplePackage.eINSTANCE.getA_B() feature to
> add B to reference A.b of a new A.
>
> Of course, because this is a bidirectional reference B.a is set
> automatically, but
> there is no command doing that!
>
> So the solution I see is to extend that AddCommand on A side to do these
> additional operations for B. But this looks like very ugly solution.
> Higher coupling and bad design....
>
> My problem is, that when choosing A for B, I have to create a couple of
> things
> for B and set-up some references properly to make model consistent. That's
> bad
> I have to put this whole logic to AItemProvider.
>
> Thanks,
> Michal Antkiewicz
>
> > Doesn't the SetACommand need to be constructed with feature
> > ExamplePackage.eINSTANCE.getA_B() and with the value and owner arguments
> > reversed?
> >
> > Michal Antkiewicz wrote:
> >
> > > Yes I know, but the problem is, that I want to extend the SetCommand to
> be
> > > a compound command and do some additional things.
> > >
> > > I have already done that and everything worked excelent. After I've made
> > > the reference bidirectional the createSetCommand of BItemProvider is no
> > > longer executed. I have code like that (BItemProvider):
> > >
> > > protected Command createSetCommand(EditingDomain domain, EObject owner,
> > > EStructuralFeature feature, Object value) {
> > > if (feature == ExamplePackage.eINSTANCE.getB_A()) {
> > > return new SetACommand(domain, owner, feature, value);
> > > }
> > > return super.createSetCommand(domain, owner, feature, value);
> > > }
> > >
> > > And this SetACommand is a compound command.
> > >
> > > The model is (again, updated)
> > > A {
> > > EList b; // type="B" opposite="a" resolveProxies="false"
> > > }
> > > B {
> > > A a; // opposite="b" resolveProxies="false"
> > > }
> > >
> > > a references at most one A. When setting this reference I want do
> > > perform additional actions that's why I have extended SetCommand.
> > >
> > > Michal
> >


Ed Merks
Professional Support: https://www.macromodeling.com/
Re: SetCommand and Bidirectional references [message #383688 is a reply to message #383679] Tue, 06 April 2004 20:40 Go to previous messageGo to next message
Michal Antkiewicz is currently offline Michal AntkiewiczFriend
Messages: 16
Registered: July 2009
Junior Member
> When you have a bidirectional reference between A and B, it's fair to say
that
> they are tightly coupled and that both are intimately aware of the other;
their
> packages, if they are in separate packages, will be mutually dependant.
That's true, but AItemProvider and BItemProvider are not! When I was
overriding the createSetCommand of BItemProvider I was also setting
itemPropertyDescriptors = null, because I wanted them to be regenerated.
Now what am I suppose to do? AItemProvider has to set
itemPropertyDescriptors
of BItemProvider => coupling is higher, because previously they were
independent.

Another thing is that both AItemProvider and BItemProvider are statefull...

> Since your design is such that when a, A-B relation is established,
> something special needs to be done on one of the ends, it doesn't really
seem to
> make significant design difference which end does the special handling;
you can
> always get A to ask B to create some type of user-defined command to do
it's own
> special thing...
Yes that's true according to A and B, what about their item providers?

Michal Antkiewicz
>
>
> Michal Antkiewicz wrote:
>
> > Well, not. When setting B.a reference. I need to get
> > ExamplePackage.eINSTANCE.getB_A() feature.
> > The theory is: "BItemProvider acts as a command factory for B".
> >
> > But I was observing ItemProviderAdapter.class in the debugger. So what
> > really happens when setting B.a reference (choosing A in properties view
> > of an editor) is that AItemProvider creates two commands:
> > - RemoveCommand for ExamplePackage.eINSTANCE.getA_B() feature to
> > remove B from previous reference of old A.
> > - AddCommand for ExamplePackage.eINSTANCE.getA_B() feature to
> > add B to reference A.b of a new A.
> >
> > Of course, because this is a bidirectional reference B.a is set
> > automatically, but
> > there is no command doing that!
> >
> > So the solution I see is to extend that AddCommand on A side to do these
> > additional operations for B. But this looks like very ugly solution.
> > Higher coupling and bad design....
> >
> > My problem is, that when choosing A for B, I have to create a couple of
> > things
> > for B and set-up some references properly to make model consistent.
That's
> > bad
> > I have to put this whole logic to AItemProvider.
> >
> > Thanks,
> > Michal Antkiewicz
> >
> > > Doesn't the SetACommand need to be constructed with feature
> > > ExamplePackage.eINSTANCE.getA_B() and with the value and owner
arguments
> > > reversed?
> > >
> > > Michal Antkiewicz wrote:
> > >
> > > > Yes I know, but the problem is, that I want to extend the SetCommand
to
> > be
> > > > a compound command and do some additional things.
> > > >
> > > > I have already done that and everything worked excelent. After I've
made
> > > > the reference bidirectional the createSetCommand of BItemProvider is
no
> > > > longer executed. I have code like that (BItemProvider):
> > > >
> > > > protected Command createSetCommand(EditingDomain domain, EObject
owner,
> > > > EStructuralFeature feature, Object value) {
> > > > if (feature == ExamplePackage.eINSTANCE.getB_A()) {
> > > > return new SetACommand(domain, owner, feature, value);
> > > > }
> > > > return super.createSetCommand(domain, owner, feature, value);
> > > > }
> > > >
> > > > And this SetACommand is a compound command.
> > > >
> > > > The model is (again, updated)
> > > > A {
> > > > EList b; // type="B" opposite="a" resolveProxies="false"
> > > > }
> > > > B {
> > > > A a; // opposite="b" resolveProxies="false"
> > > > }
> > > >
> > > > a references at most one A. When setting this reference I want do
> > > > perform additional actions that's why I have extended SetCommand.
> > > >
> > > > Michal
> > >
>
Re: SetCommand and Bidirectional references [message #383691 is a reply to message #383688] Tue, 06 April 2004 21:44 Go to previous messageGo to next message
Ed Merks is currently offline Ed MerksFriend
Messages: 33113
Registered: July 2009
Senior Member
Michal,

The item provider for B will be notified when its A has changed, so you could
react to that notification and do something special. If the something special
needs to be a command (because it needs to be undoable), then creating a special
command against B (from within A's command) to do something would be the way to
go.


Michal Antkiewicz wrote:

> > When you have a bidirectional reference between A and B, it's fair to say
> that
> > they are tightly coupled and that both are intimately aware of the other;
> their
> > packages, if they are in separate packages, will be mutually dependant.
> That's true, but AItemProvider and BItemProvider are not! When I was
> overriding the createSetCommand of BItemProvider I was also setting
> itemPropertyDescriptors = null, because I wanted them to be regenerated.
> Now what am I suppose to do? AItemProvider has to set
> itemPropertyDescriptors
> of BItemProvider => coupling is higher, because previously they were
> independent.
>
> Another thing is that both AItemProvider and BItemProvider are statefull...
>
> > Since your design is such that when a, A-B relation is established,
> > something special needs to be done on one of the ends, it doesn't really
> seem to
> > make significant design difference which end does the special handling;
> you can
> > always get A to ask B to create some type of user-defined command to do
> it's own
> > special thing...
> Yes that's true according to A and B, what about their item providers?
>
> Michal Antkiewicz
> >
> >
> > Michal Antkiewicz wrote:
> >
> > > Well, not. When setting B.a reference. I need to get
> > > ExamplePackage.eINSTANCE.getB_A() feature.
> > > The theory is: "BItemProvider acts as a command factory for B".
> > >
> > > But I was observing ItemProviderAdapter.class in the debugger. So what
> > > really happens when setting B.a reference (choosing A in properties view
> > > of an editor) is that AItemProvider creates two commands:
> > > - RemoveCommand for ExamplePackage.eINSTANCE.getA_B() feature to
> > > remove B from previous reference of old A.
> > > - AddCommand for ExamplePackage.eINSTANCE.getA_B() feature to
> > > add B to reference A.b of a new A.
> > >
> > > Of course, because this is a bidirectional reference B.a is set
> > > automatically, but
> > > there is no command doing that!
> > >
> > > So the solution I see is to extend that AddCommand on A side to do these
> > > additional operations for B. But this looks like very ugly solution.
> > > Higher coupling and bad design....
> > >
> > > My problem is, that when choosing A for B, I have to create a couple of
> > > things
> > > for B and set-up some references properly to make model consistent.
> That's
> > > bad
> > > I have to put this whole logic to AItemProvider.
> > >
> > > Thanks,
> > > Michal Antkiewicz
> > >
> > > > Doesn't the SetACommand need to be constructed with feature
> > > > ExamplePackage.eINSTANCE.getA_B() and with the value and owner
> arguments
> > > > reversed?
> > > >
> > > > Michal Antkiewicz wrote:
> > > >
> > > > > Yes I know, but the problem is, that I want to extend the SetCommand
> to
> > > be
> > > > > a compound command and do some additional things.
> > > > >
> > > > > I have already done that and everything worked excelent. After I've
> made
> > > > > the reference bidirectional the createSetCommand of BItemProvider is
> no
> > > > > longer executed. I have code like that (BItemProvider):
> > > > >
> > > > > protected Command createSetCommand(EditingDomain domain, EObject
> owner,
> > > > > EStructuralFeature feature, Object value) {
> > > > > if (feature == ExamplePackage.eINSTANCE.getB_A()) {
> > > > > return new SetACommand(domain, owner, feature, value);
> > > > > }
> > > > > return super.createSetCommand(domain, owner, feature, value);
> > > > > }
> > > > >
> > > > > And this SetACommand is a compound command.
> > > > >
> > > > > The model is (again, updated)
> > > > > A {
> > > > > EList b; // type="B" opposite="a" resolveProxies="false"
> > > > > }
> > > > > B {
> > > > > A a; // opposite="b" resolveProxies="false"
> > > > > }
> > > > >
> > > > > a references at most one A. When setting this reference I want do
> > > > > perform additional actions that's why I have extended SetCommand.
> > > > >
> > > > > Michal
> > > >
> >


Ed Merks
Professional Support: https://www.macromodeling.com/
Re: SetCommand and Bidirectional references [message #383694 is a reply to message #383688] Tue, 06 April 2004 22:19 Go to previous message
Michal Antkiewicz is currently offline Michal AntkiewiczFriend
Messages: 16
Registered: July 2009
Junior Member
OK I have solved the problem. Now, I am setting itemPropertyDescriptors
= null of BItemProvider in its notifyChanged() whenever reference 'a' to A
changes. And now both item providers remain independent :-)

Everything works as previously.

Thanks
Michal Antkiewicz

> overriding the createSetCommand of BItemProvider I was also setting
> itemPropertyDescriptors = null, because I wanted them to be regenerated.
> Now what am I suppose to do? AItemProvider has to set
> itemPropertyDescriptors
> of BItemProvider => coupling is higher, because previously they were
> independent.
>
> Another thing is that both AItemProvider and BItemProvider are
statefull...
>
> > Since your design is such that when a, A-B relation is established,
> > something special needs to be done on one of the ends, it doesn't really
> seem to
> > make significant design difference which end does the special handling;
> you can
> > always get A to ask B to create some type of user-defined command to do
> it's own
> > special thing...
> Yes that's true according to A and B, what about their item providers?
>
> Michal Antkiewicz
> >
> >
> > Michal Antkiewicz wrote:
> >
> > > Well, not. When setting B.a reference. I need to get
> > > ExamplePackage.eINSTANCE.getB_A() feature.
> > > The theory is: "BItemProvider acts as a command factory for B".
> > >
> > > But I was observing ItemProviderAdapter.class in the debugger. So what
> > > really happens when setting B.a reference (choosing A in properties
view
> > > of an editor) is that AItemProvider creates two commands:
> > > - RemoveCommand for ExamplePackage.eINSTANCE.getA_B() feature to
> > > remove B from previous reference of old A.
> > > - AddCommand for ExamplePackage.eINSTANCE.getA_B() feature to
> > > add B to reference A.b of a new A.
> > >
> > > Of course, because this is a bidirectional reference B.a is set
> > > automatically, but
> > > there is no command doing that!
> > >
> > > So the solution I see is to extend that AddCommand on A side to do
these
> > > additional operations for B. But this looks like very ugly solution.
> > > Higher coupling and bad design....
> > >
> > > My problem is, that when choosing A for B, I have to create a couple
of
> > > things
> > > for B and set-up some references properly to make model consistent.
> That's
> > > bad
> > > I have to put this whole logic to AItemProvider.
> > >
> > > Thanks,
> > > Michal Antkiewicz
> > >
> > > > Doesn't the SetACommand need to be constructed with feature
> > > > ExamplePackage.eINSTANCE.getA_B() and with the value and owner
> arguments
> > > > reversed?
> > > >
> > > > Michal Antkiewicz wrote:
> > > >
> > > > > Yes I know, but the problem is, that I want to extend the
SetCommand
> to
> > > be
> > > > > a compound command and do some additional things.
> > > > >
> > > > > I have already done that and everything worked excelent. After
I've
> made
> > > > > the reference bidirectional the createSetCommand of BItemProvider
is
> no
> > > > > longer executed. I have code like that (BItemProvider):
> > > > >
> > > > > protected Command createSetCommand(EditingDomain domain, EObject
> owner,
> > > > > EStructuralFeature feature, Object value) {
> > > > > if (feature == ExamplePackage.eINSTANCE.getB_A()) {
> > > > > return new SetACommand(domain, owner, feature, value);
> > > > > }
> > > > > return super.createSetCommand(domain, owner, feature, value);
> > > > > }
> > > > >
> > > > > And this SetACommand is a compound command.
> > > > >
> > > > > The model is (again, updated)
> > > > > A {
> > > > > EList b; // type="B" opposite="a" resolveProxies="false"
> > > > > }
> > > > > B {
> > > > > A a; // opposite="b" resolveProxies="false"
> > > > > }
> > > > >
> > > > > a references at most one A. When setting this reference I want do
> > > > > perform additional actions that's why I have extended SetCommand.
> > > > >
> > > > > Michal
> > > >
> >
>
>
Previous Topic:generated property editor questions
Next Topic:EMF models in web application
Goto Forum:
  


Current Time: Fri Mar 29 06:41:48 GMT 2024

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

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

Back to the top