Home » Modeling » ATL » One to many transformation
| One to many transformation [message #911862] |
Wed, 12 September 2012 09:16  |
Cristiano De Faveri Messages: 13 Registered: August 2012 |
Junior Member |
|
|
Hi All,
I have a scenario which a target model should create a sequence of classes due to the list of Strings another class holds.
The code snippet below illustrates the problem. I have FindClause which has bindingObjects whichs holds a list of aliases (EStrings).
For each Aliases I have to create a ObjectSource class which alias will be each FindClause.bindingObject.Alias of the list and className will be an String according to the type attribute of BindingObject.
I started a rule Find2From and created a helper to return the className based on FindClause.bindingObject.type, however how to fill alias attribute based on the FindClause.bindingObject.alias list ?
Many thanks in advance.
**** INModel ****
+-FindClause (clause : EString, bindingObject : BindingObject (1..*))
+-BindingObject (type : ObjectType, alias : EString (1..*))
+-ObjectType ( value : EString)
*******OUTModel*******
+-FromClause (clause : EString, objectList : ObjectSource (1.*))
+-ObjectSource(alias : EString, className : EString)
rule Find2From {
from
findClause : ajqlModel!FindClause
to
fromClause : hqlModel!FromClause (
clause <- 'From',
ObjectSource <- Sequence {source}
)
source : hqlModel!ObjectSource (
-- className <- thisModule.getObjectName(findClause.bindingObject.type)
-- alias <- ?[/color]??
)
}
|
|
| | |
| Re: One to many transformation [message #915514 is a reply to message #913109] |
Mon, 17 September 2012 08:53   |
Hugo Bruneliere Messages: 467 Registered: July 2009 |
Senior Member |
|
|
Hello,
By using two consecutive "collect" operations, you're obtaining a Sequence(Sequence(ObjectSource)).
To get a Sequence(ObjectSource), you have to explicitly call the "flatten" operation (cf. ATL user guide).
The error may come from this.
Best regards,
Hugo
------------------------------------------
Hugo Bruneliere - R&D Engineer
AtlanMod research team (Inria, EMN & LINA)
Ecole des Mines de Nantes
Nantes - France
------------------------------------------
|
|
|
| Re: One to many transformation [message #915761 is a reply to message #915514] |
Mon, 17 September 2012 19:02   |
Cristiano De Faveri Messages: 13 Registered: August 2012 |
Junior Member |
|
|
Hi Hugo,
Thanks for your tips.
I tried to insert flatten() into the statement, but without any success.
In order to understand what is going on, I just break down the structure into imperative statements to collect more information about it. I tried some debug statements and even debug environment, but it does not help me a lot.
This is the code I tried to change with flatten() clause.
ObjectList <- query1Clause.query.find.bindingObject -> collect (bindIt | bindIt.alias -> collect (aliasIt | thisModule.getSourceObject(bindIt.type, aliasIt ))) -> flatten()
The error remains the same : org.eclipse.m2m.atl.engine.emfvm.VMException: Operation not found: AJQL2HQL : ASMModule.including(java.util.ArrayList)
I broke down the structure like this :
1. Remove ObjectList from fromClause :
_fromClause : hqlModel!FromClause(
clause <- 'From'
),
...
2. Then I wrote a simple imperative code to figure out what's going on :
...
do {
'debuging...'.println();
for (it in query1Clause.query.find.bindingObject) { -- iterates over bindingObject
'bindingObj...'.println();
thisModule.getObjectName(it.type).println();
for (it2 in it.alias) { -- iterates over alias inside bindingObjects
_fromClause.ObjectList -> including(thisModule.getSourceObject (it.type, it2));
-- append ObjectSource to ObjectList (try to at least) - Here the error raises
}
}
}
This approach leads to a java.lang.ArrayIndexOutOfBoundsException exception
The iteration is working fine, I could see every information when traversing the model, even getSourceObject helper. The issue has been raised when trying to fill out the list property (
I'm trying different paths in order to solve this problem, unfortunately without success. Do you have any another advise or some debug tip I could use ?
Many thanks Hugo for your assistance.
|
|
|
| Re: One to many transformation [message #915933 is a reply to message #915761] |
Tue, 18 September 2012 04:38   |
Hugo Bruneliere Messages: 467 Registered: July 2009 |
Senior Member |
|
|
Hello,
The second error comes from the fact that you're using a variable (_fromClause.ObjectList) which has not be initialized yet.
Something like the following may work better:
_fromClause.ObjectList <- Sequence{};
for (it2 in it.alias) {
_fromClause.ObjectList <- _fromClause.ObjectList->including(thisModule.getSourceObject (it.type, it2));
}
Anyway I would not try to solve your problem by using an imperative "do" section, because it seems that you're introducing another error that is different from the original one.
Considering your real error (cf. your initial post), it seems that you're doing an illegal call to the "including" operation on a given sequence: have you checked that this is not coming from the "getSourceObject" rule or from the "getObjectName" helper?
Best regards,
Hugo
------------------------------------------
Hugo Bruneliere - R&D Engineer
AtlanMod research team (Inria, EMN & LINA)
Ecole des Mines de Nantes
Nantes - France
------------------------------------------
|
|
|
| Re: One to many transformation [message #916099 is a reply to message #915933] |
Tue, 18 September 2012 10:22   |
Cristiano De Faveri Messages: 13 Registered: August 2012 |
Junior Member |
|
|
Hi Hugo,
I'll keep the original declarative issue per your recommendation. The imperative code was just to try to break down the problem.
Debugging the expression like this
-> collect (aliasIt | thisModule.getSourceObject(bindIt.type, aliasIt).debug()
I can see this result after the first iteration :
Sequence {Sequence {}}
OK, according to your previous message, since collect over collect will generate a sequence over a sequence.
Debug(), in this case, is running before trying to insert ObjectSource object into the sequence. The problem seems the Sequence expects a Sequence and not a single object returned by getSourceObject(..). Even though, I believe that the message Operation not found ASMModule.including(java.util.ArrayList) would not be appropriate in this situation since it is a Sequence anyway. But I'm not sure if this would be the problem.
I tried to flat the sequence before inserting but without success as well.
I shared a small project focused on this problem containing ecore metamodel, a simple model and atl files. This is the project I'm currently working on to try to solve the issue. If you can take a look Hugo, I'd be very very grateful.
www.defavari.com.br/public/ATLProject/
Thank you again.
|
|
|
| Re: One to many transformation [message #916135 is a reply to message #916099] |
Tue, 18 September 2012 11:44   |
Hugo Bruneliere Messages: 467 Registered: July 2009 |
Senior Member |
|
|
From what I've seen, you're applying the "flatten" operation onto the nested collection which has no effect (as it is already a simple collection of elements).
The "flatten" operation should be applied onto the nesting collection:
query1Clause.query.find.bindingObject
-> collect (bindIt | bindIt.alias
-> collect (aliasIt | thisModule.getSourceObject(bindIt.type, aliasIt))
) -> flatten()
Does it work with this?
Hugo
------------------------------------------
Hugo Bruneliere - R&D Engineer
AtlanMod research team (Inria, EMN & LINA)
Ecole des Mines de Nantes
Nantes - France
------------------------------------------
|
|
|
| Re: One to many transformation [message #916139 is a reply to message #916135] |
Tue, 18 September 2012 11:53   |
Cristiano De Faveri Messages: 13 Registered: August 2012 |
Junior Member |
|
|
Yes, I tried flatten() at the end also. Same issue.
By the way, the stack shows something like
...(name: QueryStatement) (instanceClassName: null) ...
In my perception, this instanceClassName: null does not have any influence on that. I checked my ecore model, validate it (EMF tools) and check it visually as well. It seems OK.
Cristiano
e.m2m.atl.engine.emfvm.VMException: Operation not found: AJQL2HQL : ASMModule.including(java.util.ArrayList)
at __applyQuery2Query#97(AJQL2HQL.atl[27:29-28:85])
local variables: self=AJQL2HQL : ASMModule, link=TransientLink {rule = Query2Query, sourceElements = {query1Clause = [email]org.eclipse.emf.ecore.impl.DynamicEObjectImpl@430636bc[/email] (eClass: [email]org.eclipse.emf.ecore.impl.EClassImpl@78993cb9[/email] (name: Query) (instanceClassName: null) (abstract: false, interface: false))}, targetElements = {_queryStatement = [email]org.eclipse.emf.ecore.impl.DynamicEObjectImpl@4cf39304[/email] (eClass: [email]org.eclipse.emf.ecore.impl.EClassImpl@40d3853d[/email] (name: QueryStatement) (instanceClassName: null) (abstract: false, interface: false)), _whereClause = [email]org.eclipse.emf.ecore.impl.DynamicEObjectImpl@b391314[/email] (eClass: [email]org.eclipse.emf.ecore.impl.EClassImpl@7ed0890a[/email] (name: WhereClause) (instanceClassName: null) (abstract: false, interface: false)), _selectClause = [email]org.eclipse.emf.ecore.impl.DynamicEObjectImpl@50138bcd[/email] (eClass: [email]org.eclipse.emf.ecore.impl.EClassImpl@60679695[/email] (name: SelectClause) (instanceClassName: null) (abstract: false, interface: false)), _fromClause = [email]org.eclipse.emf.ecore.impl.DynamicEObjectImpl@333f68cd[/email] (eClass: [email]org.eclipse.emf.ecore.impl.EClassImpl@30cf41a5[/email] (name: FromClause) (instanceClassName: null) (abstract: false, interface: false)), _expression = [email]org.eclipse.emf.ecore.impl.DynamicEObjectImpl@7f98504[/email] (eClass: [email]org.eclipse.emf.ecore.impl.EClassImpl@2cd53091[/email] (name: Expression) (instanceClassName: null) (abstract: false, interface: false)), query2Clause = [email]org.eclipse.emf.ecore.impl.DynamicEObjectImpl@e8bcdb3[/email] (eClass: [email]org.eclipse.emf.ecore.impl.EClassImpl@83fdb62[/email] (name: Query) (instanceClassName: null) (abstract: false, interface: false))}, variables = {}}, query1Clause=IN!<unnamed>, query2Clause=OUT!<unnamed>, _queryStatement=OUT!<unnamed>, _selectClause=OUT!<unnamed>, _fromClause=OUT!<unnamed>, _whereClause=OUT!<unnamed>, _expression=OUT!<unnamed>, bindIt=IN!<unnamed>, aliasIt='b'
at __exec__#8(AJQL2HQL.atl)
local variables: self=AJQL2HQL : ASMModule, e=TransientLink {rule = Query2Query, sourceElements = {query1Clause = [email]org.eclipse.emf.ecore.impl.DynamicEObjectImpl@430636bc[/email] (eClass: [email]org.eclipse.emf.ecore.impl.EClassImpl@78993cb9[/email] (name: Query) (instanceClassName: null) (abstract: false, interface: false))}, targetElements = {_queryStatement = [email]org.eclipse.emf.ecore.impl.DynamicEObjectImpl@4cf39304[/email] (eClass: [email]org.eclipse.emf.ecore.impl.EClassImpl@40d3853d[/email] (name: QueryStatement) (instanceClassName: null) (abstract: false, interface: false)), _whereClause = [email]org.eclipse.emf.ecore.impl.DynamicEObjectImpl@b391314[/email] (eClass: [email]org.eclipse.emf.ecore.impl.EClassImpl@7ed0890a[/email] (name: WhereClause) (instanceClassName: null) (abstract: false, interface: false)), _selectClause = [email]org.eclipse.emf.ecore.impl.DynamicEObjectImpl@50138bcd[/email] (eClass: [email]org.eclipse.emf.ecore.impl.EClassImpl@60679695[/email] (name: SelectClause) (instanceClassName: null) (abstract: false, interface: false)), _fromClause = [email]org.eclipse.emf.ecore.impl.DynamicEObjectImpl@333f68cd[/email] (eClass: [email]org.eclipse.emf.ecore.impl.EClassImpl@30cf41a5[/email] (name: FromClause) (instanceClassName: null) (abstract: false, interface: false)), _expression = [email]org.eclipse.emf.ecore.impl.DynamicEObjectImpl@7f98504[/email] (eClass: [email]org.eclipse.emf.ecore.impl.EClassImpl@2cd53091[/email] (name: Expression) (instanceClassName: null) (abstract: false, interface: false)), query2Clause = [email]org.eclipse.emf.ecore.impl.DynamicEObjectImpl@e8bcdb3[/email] (eClass: [email]org.eclipse.emf.ecore.impl.EClassImpl@83fdb62[/email] (name: Query) (instanceClassName: null) (abstract: false, interface: false))}, variables = {}}
at main#24(AJQL2HQL.atl)
local variables: self=AJQL2HQL : ASMModule
[Updated on: Tue, 18 September 2012 11:54] Report message to a moderator
|
|
| |
| Re: One to many transformation [message #916624 is a reply to message #916362] |
Wed, 19 September 2012 04:39   |
Hugo Bruneliere Messages: 467 Registered: July 2009 |
Senior Member |
|
|
Hello,
Thanks for the complementary information.
Right now, I cannot really see where the error is coming from.
Have you already tried to use the ATL Debugger on this transformation?
Maybe this could help to better trace what actually happens during the transformation execution...
Hugo
------------------------------------------
Hugo Bruneliere - R&D Engineer
AtlanMod research team (Inria, EMN & LINA)
Ecole des Mines de Nantes
Nantes - France
------------------------------------------
|
|
| | |
| Re: One to many transformation [message #918671 is a reply to message #918212] |
Fri, 21 September 2012 04:25   |
Hugo Bruneliere Messages: 467 Registered: July 2009 |
Senior Member |
|
|
Hi,
What happens if you just let the original nested "collects" (with the correct call to "flatten") and write your called rule like this:
rule getSourceObject (type : ajqlModel!ObjectType , findAlias: String) {
to
_objectSource : hqlModel!ObjectSource
(
alias <- findAlias.debug(),
className <- thisModule.getObjectName(type).debug()
)
do {
_objectSource;
}
} Does it works?
Hugo
------------------------------------------
Hugo Bruneliere - R&D Engineer
AtlanMod research team (Inria, EMN & LINA)
Ecole des Mines de Nantes
Nantes - France
------------------------------------------
|
|
| |
| Re: One to many transformation [message #921582 is a reply to message #919026] |
Mon, 24 September 2012 04:43  |
Hugo Bruneliere Messages: 467 Registered: July 2009 |
Senior Member |
|
|
(imperative) called rules are not (declarative) matched rules and so don't behave in the ATL standard way.
Hugo
------------------------------------------
Hugo Bruneliere - R&D Engineer
AtlanMod research team (Inria, EMN & LINA)
Ecole des Mines de Nantes
Nantes - France
------------------------------------------
|
|
|
Goto Forum:
Current Time: Fri May 24 07:10:13 EDT 2013
Powered by FUDForum. Page generated in 0.01990 seconds
|