Simplify OCL query [message #915575] |
Mon, 17 September 2012 11:02  |
Eclipse User |
|
|
|
Hello.
I am using programmatic OCL MDT and I have an OCL query that I would like to simplify, because right now I have to split it in two parts in order to make it work.
The query checks if a java type (TypeDeclaration) declares a static, public method (MethodDeclaration) whose return type is the same type. The thing is that the metamodel represents the Java AST so it's rather clumsy: there's a lot of type casting involved so I had to split the query in two:
First one gets all the MethodDeclarations from a TypeDeclaration:
self.bodyDeclarations->select(md : BodyDeclaration | md.oclIsKindOf(MethodDeclaration))
The resulting MethodDeclaration collection is iterated, executing the second query for every MethodDeclaration to see if it satisfies the constraint:
self.returnType.oclAsType(SimpleType).name.oclAsType(SimpleName).fullyQualifiedName = 'typeDeclarationName'
and
self.modifiers->exists(m : ExtendedModifier | m.oclAsType(Modifier)._static)
and
self.modifiers->exists(m : ExtendedModifier | m.oclAsType(Modifier).public)
The iteration stops when it finds the first match.
I would like to write a single OCL query for this, I guess it would be something like this:
self.bodyDeclarations->exists(md : BodyDeclaration | md.oclAsType(MethodDeclaration).returnType.oclAsType(SimpleType).name.oclAsType(SimpleName).fullyQualifiedName = 'typeDeclarationName'
and
md.oclAsType(MethodDeclaration).modifiers.exists(m : ExtendedModifier | m.oclAsType(Modifier)._static)
and
md.oclAsType(MethodDeclaration).modifiers.exists(m : ExtendedModifier | m.oclAsType(Modifier).public))
However, this does not return any value. I would like to know what am I doing wrong. Full code is:
checkTypeDeclaration(EObject TypeDeclaration) {
EPackage dom = EPackage.Registry.INSTANCE.getEPackage("org.amma.dsl.jdt.dom");
EClass typeDeclarationClass = (EClass) dom.getEClassifier("TypeDeclaration");
EClass methodDeclarationClass = (EClass) dom.getEClassifier("MethodDeclaration");
EClass simpleNameClass = (EClass) dom.getEClassifier("SimpleName");
OCL<?, EClassifier, ?, ?, ?, ?, ?, ?, ?, Constraint, EClass, EObject> ocl;
ocl = OCL.newInstance(EcoreEnvironmentFactory.INSTANCE);
EObject nameObj = (EObject) typeDeclaration.eGet(typeDeclarationClass.getEStructuralFeature("name"));
String name = (String) nameObj.eGet(simpleNameClass.getEStructuralFeature("fullyQualifiedName"));
OCLHelper<EClassifier, ?, ?, Constraint> helper = ocl.createOCLHelper();
helper.setContext(typeDeclarationClass);
OCLExpression<EClassifier> query = helper.createQuery("self.bodyDeclarations->exists(md : BodyDeclaration | md.oclAsType(MethodDeclaration).returnType.oclAsType(SimpleType).name.oclAsType(SimpleName).fullyQualifiedName = '" + name + "'
and
md.oclAsType(MethodDeclaration).modifiers.exists(m : ExtendedModifier | m.oclAsType(Modifier)._static)
and
md.oclAsType(MethodDeclaration).modifiers.exists(m : ExtendedModifier | m.oclAsType(Modifier).public))");
Query<EClassifier, EClass, EObject> eval = ocl.createQuery(query);
Object oclResult = eval.evaluate(typeDeclaration);
if (oclResult instanceof Boolean && ((Boolean) oclResult))
System.out.println(name);
}
Thanks in advance,
Javier.
[Updated on: Mon, 17 September 2012 11:06] by Moderator
|
|
|
Re: Simplify OCL query [message #915585 is a reply to message #915575] |
Mon, 17 September 2012 11:27   |
Eclipse User |
|
|
|
Hi
At a quick glance it looks as if you've bypassed the oclIsKindOf and so
you hit a problem when oclAsType returns invalid for a 'bad' source.
In OCL you need to do
.... ->select(oclIsKindOf(X)).oclAsType(X)
which is a bit tedious, so the Juno release (Ecore and Pivot variants)
introduce a new operation
.... ->selectByKind(X)
Regards
Ed Willink
On 17/09/2012 16:03, Missing name Mising name wrote:
> Hello.
>
> I am using programmatic OCL MDT and I have an OCL query that I would
> like to simplify, because right now I have to split it in two parts in
> order to make it work.
>
> The query checks if a java type (TypeDeclaration) declares a static,
> public method (MethodDeclaration) whose return type is the same type.
> The thing is that the metamodel represents the Java AST so it's rather
> clumsy: there's a lot of type casting involved so I had to split the
> query in two:
>
> First one gets all the MethodDeclarations from a TypeDeclaration:
>
> self.bodyDeclarations->select(md : BodyDeclaration |
> md.oclIsKindOf(MethodDeclaration))
>
> The resulting MethodDeclaration collection is iterated, executing the
> second query for every MethodDeclaration to see if it satisfies the
> constraint:
>
> self.returnType.oclAsType(SimpleType).name.oclAsType(SimpleName).fullyQualifiedName
> = 'typeDeclarationName'
> and
> self.modifiers->exists(m : ExtendedModifier |
> m.oclAsType(Modifier)._static)
> and
> self.modifiers->exists(m : ExtendedModifier |
> m.oclAsType(Modifier).public)
>
> The iteration stops when it finds the first match.
>
> I would like to write a single OCL query for this, I guess it would be
> something like this:
>
> self.bodyDeclarations->exists(md : BodyDeclaration |
> md.oclAsType(MethodDeclaration).returnType.oclAsType(SimpleType).name.oclAsType(SimpleName).fullyQualifiedName
> = 'typeDeclarationName'
> and
> md.oclAsType(MethodDeclaration).modifiers.exists(m : ExtendedModifier
> | m.oclAsType(Modifier)._static)
> and
> md.oclAsType(MethodDeclaration).modifiers.exists(m : ExtendedModifier
> | m.oclAsType(Modifier).public))
>
> However, this does not return any value. I would like to know what am
> I doing wrong. Full code is:
>
>
> EObject nameObj = (EObject)
> typeDeclaration.eGet(typeDeclarationClass.getEStructuralFeature("name"));
>
> String name = (String) nameObj.eGet(simpleNameClass
> .getEStructuralFeature("fullyQualifiedName"));
>
> OCLHelper<EClassifier, ?, ?, Constraint> helper = ocl.createOCLHelper();
> helper.setContext(typeDeclarationClass);
>
> OCLExpression<EClassifier> query =
> helper.createQuery("self.bodyDeclarations->exists(md : BodyDeclaration
> |
> md.oclAsType(MethodDeclaration).returnType.oclAsType(SimpleType).name.oclAsType(SimpleName).fullyQualifiedName
> = '" + name + "'
> and
> md.oclAsType(MethodDeclaration).modifiers.exists(m : ExtendedModifier
> | m.oclAsType(Modifier)._static)
> and
> md.oclAsType(MethodDeclaration).modifiers.exists(m : ExtendedModifier
> | m.oclAsType(Modifier).public))");
>
> Query<EClassifier, EClass, EObject> eval = ocl.createQuery(query);
> Object oclResult = eval.evaluate(typeDeclaration);
> if (oclResult instanceof Boolean && ((Boolean) oclResult2)) {
> System.out.println(name);
> }
>
>
> Thanks in advance,
>
> Javier.
|
|
|
|
|
|
|
|
|
Re: Simplify OCL query [message #923092 is a reply to message #922954] |
Tue, 25 September 2012 11:38  |
Eclipse User |
|
|
|
Hi
It seems odd, but without seeing the metamodels it's hard to tell
whether any implicit collects have fooled you.
Regards
Ed Willink
On 25/09/2012 14:39, Missing name Mising name wrote:
> I think I've found the problem:
>
> While this:
>
>
> md.oclAsType(MethodDeclaration).returnType.oclAsType(SimpleType).name.oclIsKindOf(SimpleName)
>
>
>
> returns true,
>
> this:
>
>
> md.oclAsType(MethodDeclaration).returnType.oclAsType(SimpleType).name.oclAsType(SimpleName)
>
>
>
> returns invalid, which doesn't make any sense to me.
|
|
|
Powered by
FUDForum. Page generated in 0.06655 seconds