Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » Sirius » Domain/Element-based edge issue
Domain/Element-based edge issue [message #1444862] Tue, 14 October 2014 17:01 Go to next message
Stéphane Seyvoz is currently offline Stéphane SeyvozFriend
Messages: 21
Registered: October 2014
Junior Member
Hi Sirius community,

I recently started using Sirius and it is quite a nice framework.
However, I'm encountering issues during my "odesign" file development.

Introduction

The project I work with is a "component-based" development tool, in which we already use Xtext and its related Ecore model. In our Architecture Description Language, we define one component per file. Such a component can "contain" sub-"components", "provide" and "require" interfaces, and "bind" interfaces of sub-"component" instances together (quite classical).

You can find the "SimplifiedADL.xtext" Xtext grammar attached to this post.

The "simple" related Ecore diagram, without the Interfaces types cross-references:
index.php/fa/19503/0/

EClass tree:
index.php/fa/19504/0/

To understand how our scoping works, here is how we do this done with Xtext:
- User side:
binds sourceComponent.sourceInterface to targetComponent.targetInterface


- Developer side
public IScope scope_Binding_sourceInterface(final Binding binding, final EReference ref) {
	Architecture sourceComponentArch = binding.getSourceComponent().getType();
	List<RequiredInterface> reqItfList = EcoreUtil2.eAllOfType(sourceComponentArch, RequiredInterface.class);
	return Scopes.scopeFor(reqItfList);
}

public IScope scope_Binding_targetInterface(final Binding binding, final EReference ref) {
	Architecture targetComponentArch = binding.getTargetComponent().getType();
	List<ProvidedInterface> reqItfList = EcoreUtil2.eAllOfType(targetComponentArch, ProvidedInterface.class);
	return Scopes.scopeFor(reqItfList);
}

When describing a binding, our "sourceInterface" is scope-related to its preceding "sourceComponent", as for the "targetComponent" and "targetInterface".
The source and target component are instances in the scope of the current assembly (composite) file, but their provided/required interfaces come from their own "type" model and definition file.

The problem (with my odesign / VSM)

I could quite easily create a mapping with composite element as a free-form Container, sub-components as Nodes, provided and required interfaces as Bordered Nodes, and used Sirius/Acceleo expressions to do so.

But when it comes to Domain/Element-based edges mapped on my "Binding" entities, and the Source and Target Finder Expressions, there has been no way to make things work (I've been reading the "Writing_Queries" and Diagrams#edges section of Sirius documentation much though...).

Here is a captures of my "odesign" edge properties:
index.php/fa/19505/0/

A screenshot of the result in my "hosted" debug Eclipse instance running the model and visualization:
index.php/fa/19506/0/

The problem with Source and Target Finder Expressions such as:
[self.sourceInterface/]
and
[self.targetInterface/]
is that, as in my Eclipse screenshot, the queries find the would-be-unique sourceInterface, but if I have two component instances of the same type, all corresponding RequiredInterface elements are matched, and I obtain... 2 graphical Edges... For 1 textual / model Binding node.

I've been trying countless expressions in my development and runtime interpreters, to try to restrict the collections of source and target entries, as well as edge pre-conditions, I've searched this forum topics about "Element based edge", but nothing succeeded.

In the runtime Eclipse instance, I use the "self.target" entities and "self" in the development instance as should be. Funnily, in the runtime test Eclipse, it's easier when clicking on one of my "Bordered Nodes" interfaces to retrieve if a binding exists or not in the model, starting with graphical elements like:
[self.eInverse()->filter(DNode).target.eInverse()->filter(simplifiedADL::Binding)/]


I would enjoy using this in order to "select" / match entities as a pre-condition, however I don't know how to get the graphical DNode from the host expressions.

Conclusion

So here I am with no clue on how to restrict Edges per parent "Component"/"Node" thanks to an appropriate mapping/expression... Your help would be gladly welcome !

Thanks !

[Updated on: Wed, 15 October 2014 09:53]

Report message to a moderator

Re: Domain/Element-based edge issue [message #1445033 is a reply to message #1444862] Tue, 14 October 2014 23:24 Go to previous messageGo to next message
Nikolay Manolov is currently offline Nikolay ManolovFriend
Messages: 24
Registered: June 2012
Junior Member
Hi Stéphane,

Could it be that you have only one "interface" element in your semantic model? Meaning e0.i0 and e1.i0 are the same,
The expression that you said help you find if a binding exists is somewhat confusing to me
lets say you click on the e0.i0 in the graphical editor and evaluate the expression
[self.eInverse()->filter(DNode).target.eInverse()->filter(simplifiedADL::Binding)/]

self = graphical i0
self.eInverse()->filter(DNode) = graphical e0
self.eInverse()->filter(DNode).target = semantic e0
self.eInverse()->filter(DNode).target.eInverse()->filter(simplifiedADL::Binding) = all bindings referencing e0 ( but you want bindings referencing i0)

If I am not mistaken a more appropriate expression would be
[self.target.eInverse()->filter(simplifiedADL::Binding)/] or get the semantic i0 and retrieve the bindings referencing it.

If it is the case that e0 and e1 share the same interface then the two connections are basically one and the same and this is I think the correct behaviour of the edge mapping.

Care to share your sample projects for testing ?
Re: Domain/Element-based edge issue [message #1445331 is a reply to message #1445033] Wed, 15 October 2014 09:40 Go to previous messageGo to next message
Stéphane Seyvoz is currently offline Stéphane SeyvozFriend
Messages: 21
Registered: October 2014
Junior Member
Hi Nikolay,

First, thanks for your reply.
You're exactly right about the expression I quoted and what it computes. The expression may not be using the good philosophy concerning how Sirius works though.

I considered doing for each edge creation, since my source selection selected all graphical "i0" Bordered Nodes, knowing already that since their semantical "alter ego" would already be referenced by a semantical Binding (hence their creation), to check that the Node "hosting" the according Bordered Node was at least referred to by a binding, in order to check its semantical validity, to to trigger or not the edge creation.

To put it in a reverse and simpler way, I wanted to check if any binding exists that concerns e0 (and not e1) that has an i0 interface.

I agree this may be a kind of graphical-API-based "hack" instead of valid selection, but since the selection selects a unique "i0", leading to an expected "dual" edge representation as you mention, I feel quite powerless.

Additional question: Do you mean that the expressions (even pre-condition where we can access the "sourceView" "targetView" and "containerView" variables...) can only apply to semantical model elements, forbidding me to do my "hackish" thing ?

Or may there be a way to resolve the issue otherwise ?

As a comparison of my screenshot example (with D, E, F...) with Object-Oriented Programming, the following would be close semantically (pseudo-code):

/* 1 class - 0..* objects */
class E {
  I i0;
}

/* Here implement I once, whereas we can have multiple provided named interfaces (i0, i1...) of the same type in our model */
class F implements I { ... }

class D {
  F f0;
  E e0;
  E e1;
  
  // static initializer
  static {
    f0 = new F();
    e0 = new E();
    e1 = new E();
    
    // similar to our binding expression except that f0 is accessed through the unique "I" interface
    e0.i0 = (I) f0; 
  }
}


In my idea, it is normal for me to have a unique "i0" in my model, since I deal with structural / type / meta information that is legitimately shared between the "e0" and "e1" instances. How could I resolve this ? Maybe my Xtext-generated Ecore model isn't sufficient as it is and I have to put an effort on it ? Or do you think there is another way to handle the case ?

I shared the "simplified" project on GitHub but cannot create links here since I did not post at least 5 messages in these forums. So here is a pseudo-link:
github.com/StephaneSeyvoz/EclipseSiriusTests

You will find:
- "modeling_test_0" the test project to be import in the "runtime" test Eclipse
- all the others can directly be imported in development Eclipse with the 3 Xtext modules for my "SADL" and "SITF", plus the "Sirius"-suffixed module. The Ecore models are always generated from the MWE2 workflow.

I hope it helps, and thank you for your time !

[Updated on: Wed, 15 October 2014 12:59]

Report message to a moderator

Re: Domain/Element-based edge issue [message #1445389 is a reply to message #1445331] Wed, 15 October 2014 11:08 Go to previous messageGo to next message
Nikolay Manolov is currently offline Nikolay ManolovFriend
Messages: 24
Registered: June 2012
Junior Member
EDIT: skip to next post. I have totally misunderstood what is going on here.

It is just the way Sirius works.
When you define a mapping, a graphical representation is created for each Semantic Candidate and each occurrence of a Semantic Candidate. You can limit the list of Semantic Candidates but in your case the list can be either empty or contain i0. If it contains i0, two connections will be created. If it is empty obviously no connections will be created.
>
This is not a solution but to give you an idea of a different Sirius implementation ... and hopefully you get an inspiration
You could try mapping the ports not the interface but the component instead. You can still set the label to display the name of the interface. You can have different representations of the same element. (so Component->Node, Component->Port) Then your edge mapping will be defined on the ports again but use sourceComponent and targetComponent (instead of source- targetInterface). The problem there is that if you have more than one interface (and you probably will) then all ports of a component will be mapped to the same component and each binding will be replicated by the number of interfaces. The same problem with connection replication but this time because the same component is used.

Frankly right now I cannot think of a way to implement this in Sirius.
Naturally, you could change your metamodel to have different interface elements, but this should NOT be done just to accommodate the needs of the graphical editor.

[Updated on: Wed, 15 October 2014 15:21]

Report message to a moderator

Re: Domain/Element-based edge issue [message #1445414 is a reply to message #1445389] Wed, 15 October 2014 12:02 Go to previous messageGo to next message
Stéphane Seyvoz is currently offline Stéphane SeyvozFriend
Messages: 21
Registered: October 2014
Junior Member
Edit: Irrelevant now, solution found later.

[Updated on: Wed, 15 October 2014 17:35]

Report message to a moderator

Re: Domain/Element-based edge issue [message #1445542 is a reply to message #1445414] Wed, 15 October 2014 15:30 Go to previous messageGo to next message
Nikolay Manolov is currently offline Nikolay ManolovFriend
Messages: 24
Registered: June 2012
Junior Member
Hi Stéphane,

I confused the list of Semantic Candidates with the Precondition Expression in the Advanced tab. Sorry about that.
So I might have a solution.
I have not tested it but if we add a precondition the duplicate connection might not be created.
Could you please try an expression like the following in the Properties->Advanced-> Precondition Expression for the Edge Creation

[self.targetComponent->includes(targetView.eInverse()->filter(DNode).target)/]

Here, If I've done it correctly, we say that the Binding's (list of) targetComponent must be equal to (must include) the component whose graphical representation references the targetView (port,Interface)

If this works you should add respectively the same condition for the source Component.
Re: Domain/Element-based edge issue [message #1445604 is a reply to message #1445542] Wed, 15 October 2014 17:23 Go to previous message
Stéphane Seyvoz is currently offline Stéphane SeyvozFriend
Messages: 21
Registered: October 2014
Junior Member
Aaaahhh ! I knew there had something to be investigated there (the pre-conditions in the Advanced tab).

Your expression did not work straight out of the box, but after some tinkering, I managed to obtain the following working expression:

[sourceView.eInverse()->filter(DNode).target->includes(self.sourceComponent) and targetView.eInverse()->filter(DNode).target->includes(self.targetComponent)/]


Everytime I tried to check the return values of the variations of expressions thanks to the "->isEmpty()" "->isOclKindOf()" "->count()" operators to check if my "double" edges would show or not...

In the end the only issue with your expression was that
sourceView.eInverse()->filter(DNode).target

was the part returning a Sequence(EObject) to be checked for inclusion (not the other way).

Result sample screenshots (I've tested a number of combinations to check the behaviour and everything is ok now):
index.php/fa/19531/0/
index.php/fa/19530/0/

Thank you so much !

[Updated on: Wed, 15 October 2014 17:45]

Report message to a moderator

Previous Topic:Reused tools insertion point
Next Topic:Disable Tools/Mappings in the specification
Goto Forum:
  


Current Time: Wed Apr 01 18:55:42 GMT 2020

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

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

Back to the top