Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » GMF (Graphical Modeling Framework) » How to simulate a label of a link when link and label are of different EClasses?
How to simulate a label of a link when link and label are of different EClasses? [message #232069] Wed, 03 June 2009 03:56 Go to next message
Alessander Botti Benevides is currently offline Alessander Botti BenevidesFriend
Messages: 20
Registered: July 2009
Junior Member
Hi people, in order to simulate labels of links, when the label and the
link are of different EClasses, I'm using the following metamodel:

EClass A // The real nodes
EClass B // The node which simulates a label
EClass C // The link which represents the real association between the
nodes
EReference source1 : A
EReference target1 : A
EClass D // The link created in order to simulate the invisible link
between the simulated label and the real association
EReference source2 : B
EReference target2 : C

Therefore, EClass A is graphically represented as a Node A; EClass B is
represented as a Node B; EClass C is represented as a Link C in which the
"Source Feature" is source1 and "Target Feature" is target1; and EClass D
is represented as a Link D in which the "Source Feature" is source2 and
"Target Feature" is target2. An example of a model is show in the "figure"
below:

[Node B] B1
|
| (Link D) D1
|
[Node A] A1---------------[Node A] A2
(Link C) C1

Now, imagine B1 as a label of C1: this is exactly the appearance I want to
create for D1, D1 shall only be visible when the user moves B1. How can I
do that? Also, B1 and D1 are created automatically when I create C1, so I
have no control of where D1 connects on C1. Is there a way I can specify
where it will connects on C1, just like the "Alignment Facet BEGINNING"
and "Alignment Facet END" that works in "Diagram Labels"? An example is
show below, where the nodes B1 and B2 and the links D1 and D2, connected
on the link C1, are simulating that B1 and B2 are labels of C1, with
"Alignment Facet BEGINNING" and "Alignment Facet END":

[Node B] B1 [Node B] B2
| |
(Link D) D2 | | (Link D) D1
| |
[Node A] A1---------------[Node A] A2
(Link C) C1

Any help is very appreciated because I'm having this problem for years!!!
And I have no hope that Bug 138179 "Allow to define labels based on
attributes of referenced objects"
(https://bugs.eclipse.org/bugs/show_bug.cgi?id=138179) will be fixed :(

Best regards,
Alessander
Re: How to simulate a label of a link when link and label are of different EClasses? [message #232156 is a reply to message #232069] Wed, 03 June 2009 11:33 Go to previous messageGo to next message
Alexander Shatalin is currently offline Alexander ShatalinFriend
Messages: 2928
Registered: July 2009
Senior Member
Hello Alessander,

I think you can correct this problem even now. My proposal is: try modelling
this situation as a label for link EClass C with small addition: text for
this label should be loaded/stored in a different element (associated EClass
B) I have two suggestions how to implement it now:

1. Create derived property for link element (EClass C) like: BLabel. Re-generated
model code and implement properly generated getBLabel()/setBLabel() methods
to load/save value into associated instance of EClass B. Use this property
in a FeatureLabelMapping created below this LinkMapping in .gmfmep model.

2. Use LabelMapping instead of FeatureLabelMapping to model this link label.
As a result generated LabelEditPart (WrappingLabelEditPart ?) will call ParserService
from its getParserMethod(), but generated ParserProvider will not return
any parser for specified ParserHintAdapter parameter - in this case used
is responsible for registering/returning appropriate parser implementation
using GMF ParserService. As a next step you have to implement your own ParserProvider/modify
generated one to return proper IParser implementation for this ParserHintAdapter.
IParser interface is not so complex, so you can implement it and load/save
label text into EClass B instance associated with EClass C instance passes
ad a parameter into this IParser implementation.

This is another way - in case you can not modify domain meta-model you can
still use arbitrary model element property value to visualize link label
by implementing custom parser.

-----------------
Alex Shatalin
Re: How to simulate a label of a link when link and label are of different EClasses? [message #232278 is a reply to message #232156] Wed, 03 June 2009 15:31 Go to previous messageGo to next message
Alessander Botti Benevides is currently offline Alessander Botti BenevidesFriend
Messages: 20
Registered: July 2009
Junior Member
Hi Alex, thank you very much for your answer!

I followed the first approach you suggested and was easy to implement, but
unfortunately I need to get EClass B in the "Properties View" when I click
on the label, and by this method I get EClass C.

I didn't tried the second solution yet, but it seems to me that it will
get the same problem, am I right?

I also have tried to create a label of EClass C and then change its
element to the automatically created element of EClass B by changing
addFixedChild(EditPart childEditPart) in CEditPart.java

The generated addFixedChild for this example:
protected boolean addFixedChild(EditPart childEditPart) {
if (childEditPart instanceof OntoUML.diagram.edit.parts.CLabelEditPart) {
((OntoUML.diagram.edit.parts.CLabelEditPart) childEditPart)
.setLabel(getPrimaryShape()
.getFigureCLabelFigure());
return true;
}
}

My alteration:
protected boolean addFixedChild(EditPart childEditPart) {
if (childEditPart instanceof OntoUML.diagram.edit.parts.CLabelEditPart) {
((OntoUML.diagram.edit.parts.CLabelEditPart) childEditPart)
.setLabel(getPrimaryShape()
.getFigureCLabelFigure());
((View) getModel()).setElement(generatedEClassB);
// From an EClass C, I can find the generated EClass B instance
// (generatedEClassB). There is an EReference from EClass C to
// EClass B that I didn't show in the metamodel, in order to make
// it more simple...
return true;
}
}

I got the following error:
Caused by: java.lang.ClassCastException: OntoUML.impl.BImpl cannot be cast
to OntoUML.C

Even if I set the element of childEditPart to the same element that it is
currently using, by doing the next line of code, I got an error:
((View) getModel()).setElement(resolveSemanticElement());
Caused by: java.lang.IllegalStateException: Cannot modify resource set
without a write transaction

As you see, I have a poor understanding of how GMF works :(
Is there a way to change the element of the label from C1 (of EClass C) to
B1 (of EClass B)?
I also have tried to change CEditPart.java in order to create a new View
for B1 as a label of C1, but having no success. I found no information of
how to programatically create Views or EditPart instances for elements.
Can you help me?

Thank you for your answer,
Best regards,
Alessander
Re: How to simulate a label of a link when link and label are of different EClasses? [message #232436 is a reply to message #232278] Thu, 04 June 2009 15:56 Go to previous messageGo to next message
Alexander Shatalin is currently offline Alexander ShatalinFriend
Messages: 2928
Registered: July 2009
Senior Member
Hello Alessander,

> I didn't tried the second solution yet, but it seems to me that it
> will get the same problem, am I right?
Yes, you are right.

Try modifying generated ???PropertySection.transformSelection(Object selected)
method to display properties of associated instance of EClass B instead of
properties of instance of EClass C. Try something like:

/**
* Modify/unwrap selection.
* @generated NOT
*/
protected Object transformSelection(Object selected) {
if (selected instanceof <EClassCLabel>EditPart) {
Object model = ((<EClassCLabel>EditPart) selected).getModel();
if (model instanceof View) {
EObject modelElement = ((View) model).getElement();
if (modelElement instanceof <EClassC>) {
return ((<EClassC>) modelElement).getEClassB();
}
}
}
........

-----------------
Alex Shatalin
Re: How to simulate a label of a link when link and label are of different EClasses? [message #232477 is a reply to message #232436] Thu, 04 June 2009 20:37 Go to previous messageGo to next message
Alessander Botti Benevides is currently offline Alessander Botti BenevidesFriend
Messages: 20
Registered: July 2009
Junior Member
Thank you very very much by the code, it works great!!!
Finally my editor is near to be ready!
But I have one last question:
How can I make the label of Link C update when I change the properties of
the instance of EClass B?

Thank you again,
Best regards,
Alessander
Re: How to simulate a label of a link when link and label are of different EClasses? [message #232573 is a reply to message #232477] Fri, 05 June 2009 10:41 Go to previous messageGo to next message
Alexander Shatalin is currently offline Alexander ShatalinFriend
Messages: 2928
Registered: July 2009
Senior Member
Hello Alessander,

In case you are implementing custom parser then you can handle it by implementing
ISemanticParser interface (see corresponding code working with this interface
in ????LabelEditPart).
If you handle this situation with derived property then you have to listen
for EMf notification and wrap/sent corresponding notification like in case
property value was canged - i think this should work.

-----------------
Alex Shatalin
Re: How to simulate a label of a link when link and label are of different EClasses? [message #232833 is a reply to message #232573] Mon, 08 June 2009 01:25 Go to previous messageGo to next message
Alessander Botti Benevides is currently offline Alessander Botti BenevidesFriend
Messages: 20
Registered: July 2009
Junior Member
Hello Alex,

I tried to not upset you by asking for more specific instructions, but I
spent most of these days trying to resolve it and could not make it work :(

I tried to follow your second sugestion, because I have added a derived
attribute in EClass C (I'll call it "derivedCAttribute: String") which
gets its value from an attribute of EClass B (I'll call it "BAttribute:
String"), by an EReference "CtoB" from EClass C to EClass B. Also, there
is an EReference "BtoC" which is the EOpposite of "CtoB". My tentative was:

(i) implement the method setDerivedCAttribute(String newCAttribute) in
CImpl.java, making a call to eNotify:
setDerivedCAttribute(String newCAttribute) {
eNotify(new ENotificationImpl(this, Notification.SET,
???Package.C__derivedCAttribute, "", ""));
}

(ii) modify setBAttribute(String newCAttribute) in BImpl.java in order to
call my implementation of the method setDerivedCAttribute:
setBAttribute(String newCAttribute) {
...
this.getBtoC().setDerivedCAttribute("");
...
}

(iii) modify notifyChanged(Notification notification) in
CItemProvider.java in order to fire a notification for derivedCAttribute:
public void notifyChanged(Notification notification) {
updateChildren(notification);

switch (notification.getFeatureID(C.class)) {
...
case ???Package.C__derivedCAttribute:
fireNotifyChanged(new ViewerNotification(notification,
notification.getNotifier(), false, true));
return;
}
super.notifyChanged(notification);
}

(iv) implement handleNotificationEvent(Notification event) in
CEditPart.java in order to properly change the label of the EClass C
instance, when the associated EClass B instance has changed its BAttribute:
protected void handleNotificationEvent(Notification event) {
-code to update the label-
super.handleNotificationEvent(event);
}

So, I thought that when I change BAttribute, the setDerivedCAttribute
would be called, making a notification and the method notifyChanged would
send it to CEditPart.java, which would notice it by the method
handleNotificationEvent and the label would be updated. But the problem is
that the notification does not arrives on handleNotificationEvent. All the
notifications which comes from proper EClass C attributes are working, and
the other "normal" labels are fine. But, this scheme to indirectly notify
instances of EClass C of changes on instances of EClass B is not
working... could you help me more?

Thank you very much for your help!
Best regards,
Alessander
Re: How to simulate a label of a link when link and label are of different EClasses? [message #232891 is a reply to message #232833] Mon, 08 June 2009 10:33 Go to previous messageGo to next message
Alexander Shatalin is currently offline Alexander ShatalinFriend
Messages: 2928
Registered: July 2009
Senior Member
Hello Alessander,

Unfortunately I never tried this myself.

Theoretically this should work (unless some flags have to be set on EMF side).

-----------------
Alex Shatalin
Re: How to simulate a label of a link when link and label are of different EClasses? [message #233182 is a reply to message #232891] Tue, 09 June 2009 20:58 Go to previous messageGo to next message
Alessander Botti Benevides is currently offline Alessander Botti BenevidesFriend
Messages: 20
Registered: July 2009
Junior Member
Hi Alex,

I finally managed to make it work! Thank you very much for your help, I
would not have succeeded without it.
I'll describe how I did it in the steps shown below. As you can see, some
steps of my previous message are unnecessary (I'll try to make a GMF
Recipe):

(i) make sure that both derivedCAttribute and BAttribute have the property
"Notify" set to true in the genmodel file. Also, derivedCAttribute should
have the properties "derived" and "volatile" set to true in the ecore file;

(ii) implement the method getDerivedCAttribute() in CImpl.java:
public String getDerivedCAttribute() {
if (getCtoB() != null) {
return getCtoB().getBAttribute();
else
return "";
}

(iii) implement the method setDerivedCAttribute(String newCAttribute) in
CImpl.java, making a call to eNotify: public void
setDerivedCAttribute(String newCAttribute) {
if (eNotificationRequired())
eNotify(new ENotificationImpl(this, Notification.SET,
???Package.C__DERIVEDCATTRIBUTE, getDerivedCAttribute(), newCAttribute));
}

(iv) modify setBAttribute(String newBAttribute) in BImpl.java in order to
call the implementation of the method setDerivedCAttribute:
public void setBAttribute(String newBAttribute) {
if (getBtoC() != null)
getBtoC().setDerivedCAttribute(newBAttribute);
String oldBAttribute = BAttribute;
BAttribute = newBAttribute;
if (eNotificationRequired())
eNotify(new ENotificationImpl(this, Notification.SET,
???Package.B__BATTRIBUTE, oldBAttribute, BAttribute));
}

Thank you very much for your help!
Best regards,
Alessander Botti Benevides
Re: How to simulate a label of a link when link and label are of different EClasses? [message #233238 is a reply to message #233182] Wed, 10 June 2009 10:22 Go to previous message
Alexander Shatalin is currently offline Alexander ShatalinFriend
Messages: 2928
Registered: July 2009
Senior Member
Hello Alessander,

> (i) make sure that both derivedCAttribute and BAttribute have the
> property "Notify" set to true in the genmodel file. Also,
Ok. So this looks like a missing point in the prev. scenario. Thanks for
posting here you investigations. From now I know which .genmodel attribute
should I set to make derived EMF feature sending notifications.

-----------------
Alex Shatalin
Previous Topic:Delete all the View when deleting an element
Next Topic:Add Button to Toolbar
Goto Forum:
  


Current Time: Thu Apr 25 15:24:43 GMT 2024

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

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

Back to the top