Home » Archived » EMF-IncQuery » Passing arguments to IncQuery Patterns at Runtime(Attempt to use patterns dynamically at runtime)
|
Re: Passing arguments to IncQuery Patterns at Runtime [message #1691051 is a reply to message #1690940] |
Wed, 01 April 2015 21:41 |
Zoltan Ujhelyi Messages: 392 Registered: July 2015 |
Senior Member |
|
|
Hi,
The short answer to your question is that it is kind-of possible, but with limitations.
More concretely, the arguments can be passed to patterns during runtime via the Matcher (see documentation at https://wiki.eclipse.org/EMFIncQuery/UserDocumentation/API#Matcher), and the matcher will only return matches were the property is the selected value. However, in general, passing conditions is not really possible, as this would require a condition interpreter inside the patterns... It would be possible using external implementation referred inside check expressions, but I do not recommend this path because of high maintenance costs.
To be more constructive, you could post-process the matches with your additional conditions: first gather all matches, and filter out all does not match your condition. This way, you could use IncQuery to (1) gather the required information, (2) get change notifications as needed while still maintain the additional filtering requirements.
I hope, this was helpful. If not, please ask for further clarification.
Cheers,
Zoltán
|
|
| |
Re: Passing arguments to IncQuery Patterns at Runtime [message #1691328 is a reply to message #1691105] |
Mon, 06 April 2015 05:04 |
Pulkit Manocha Messages: 7 Registered: April 2015 |
Junior Member |
|
|
Thanks for replying!
Quote: Hi,
I would like to briefly point out that it is also possible to generate patterns according to your liking; either textually (generate the .eiq file) or the actual runtime query representation. This is certainly possible (and done before), but we do not have any easy-to-understand examples that are accessible online; it is a difficult path to take, and the benefits are probably outweighed by the effort.
For your problem, it is probably easier to follow Zoltán's suggestions, and post-process the match results with your custom conditions.
Generating patterns might be ideal for the kind of project I'm working on. Despite the drawbacks, I'd still like to have a look at how that could be done. If not for the project then to learn more of IncQuery. Could you point out any resources/tutorials/anything which I could use to learn how to generate patterns?
Quote: More concretely, the arguments can be passed to patterns during runtime via the Matcher (see documentation, and the matcher will only return matches were the property is the selected value
Could you elaborate how we can do this? I am using IncQuery 0.7 and I couldn't find any method in the matcher class that could let me do this.
Moreover, the following method seemed to be missing (couldn't find it in any class) in my IncQuery and I'm not sure about what exactly it does:
public Collection<EClassNamesMatch> getAllMatches(EClass pC, final String pN) {}
I apologize if these doubts seem trivial since I'm a bit new to IncQuery.
|
|
|
Re: Passing arguments to IncQuery Patterns at Runtime [message #1691335 is a reply to message #1691328] |
Mon, 06 April 2015 07:30 |
Jan Reimann Messages: 140 Registered: July 2009 |
Senior Member |
|
|
Hi Pulkit,
from my point of view there are two alternatives to generate patterns:
1) generating a model, 2) generating text.
1) can be achieved because the pattern language is based on an Ecore
model (the metamodel of the pattern language) for which a Xtext-based
textual syntax is provided. Thus, internally every pattern is a model
and you could use any (model) transformation language to generate a new
pattern model. Especially the Java API generated by EMF could be used to
produce a pattern model dependent from another structure/model/whatever.
A little snippet could look as follows:
// generate pattern model
PatternModel patternModel =
EMFPatternLanguageFactory.eINSTANCE.createPatternModel();
patternModel.setPackageName("your.package");
Pattern pattern = PatternLanguageFactory.eINSTANCE.createPattern();
patternModel.getPatterns().add(pattern);
pattern.setName("EClassWithGivenName");
Variable var = PatternLanguageFactory.eINSTANCE.createVariable();
var.setName("Cls");
ClassType classType = EMFPatternLanguageFactory.eINSTANCE.createClassType();
classType.setTypename("EClass");
var.setType(classType);
pattern.getParameters().add(var);
PatternBody patternBody = factory.createPatternBody();
pattern.getBodies().add(patternBody);
// create your check constraint
// Constraint checkConstraint = ...;
// patternBody.getConstraints().add(constraint);
// print as text
URI targetUri = URI.createFileURI("your.file.uri");
ResourceSet resourceSetTarget = new ResourceSetImpl();
Resource targetResource = resourceSetTarget.getResource(targetUri, true);
targetResource.getContents().add(patternModel);
targetResource.save(Collections.EMPTY_MAP);
This snippet generates the following (empty) pattern.
pattern EClassWithGivenName(Cls : EClass) {
}
The advantage of this approach is that it is type safe because it is
independent from the textual syntax and the pattern model is created
based on the available concepts of the metamodel. But the drawback is
that you have to dive deeply into the pattern language metamodel for
being able to construct pattern models efficiently. But what I have done
recently is, to take a base pattern which is loaded and then the
additional parts are just added to it. So the overhead can be controlled
somehow.
2) But I think the second alternative suits better for your use case
since you only want to generate check expressions. So you could take a
base pattern and just consider it as text:
String base = "pattern EClassWithGivenName(Cls : EClass) {" +
" EClass.name(Cls,Name);" +
" check(<<PLACEHOLDER>>);" +
"}";
String checkExpression = "(Name as String).equals(\"MyClass\")";
String newPattern = base.replace("<<PLACEHOLDER>>", checkExpression);
The advantage of this approach is that it's pretty simple. The
disadvantage is that the patterns are Strings without any type
information regarding the pattern language's metamodel. Thus, errors in
your patterns can only be detected when you try to load them in the
editor. But I think this can be controlled pretty well when you take a
base (template) pattern and replace placeholders.
I hope that helps.
cheers,
Jan
Am 06.04.2015 um 07:04 schrieb Pulkit Manocha:
> Thanks for replying!
>
> Quote:
>> Hi,
>>
>> I would like to briefly point out that it is also possible to generate
>> patterns according to your liking; either textually (generate the .eiq
>> file) or the actual runtime query representation. This is certainly
>> possible (and done before), but we do not have any easy-to-understand
>> examples that are accessible online; it is a difficult path to take,
>> and the benefits are probably outweighed by the effort.
>>
>> For your problem, it is probably easier to follow Zoltán's
>> suggestions, and post-process the match results with your custom
>> conditions.
>
>
> Generating patterns might be ideal for the kind of project I'm working
> on. Despite the drawbacks, I'd still like to have a look at how that
> could be done. If not for the project then to learn more of IncQuery.
> Could you point out any resources/tutorials/anything which I could use
> to learn how to generate patterns?
>
>
> Quote:
>> More concretely, the arguments can be passed to patterns during
>> runtime via the Matcher (see documentation, and the matcher will only
>> return matches were the property is the selected value
>
>
> Could you elaborate how we can do this? I am using IncQuery 0.7 and I
> couldn't find any method in the matcher class that could let me do this.
> Moreover, the following method seemed to be missing (couldn't find it in
> any class) in my IncQuery and I'm not sure about what exactly it does:
> public Collection<EClassNamesMatch> getAllMatches(EClass pC, final
> String pN) {}
>
> I apologize if these doubts seem trivial since I'm a bit new to IncQuery.
>
>
|
|
|
Re: Passing arguments to IncQuery Patterns at Runtime [message #1691368 is a reply to message #1691335] |
Mon, 06 April 2015 16:36 |
Zoltan Ujhelyi Messages: 392 Registered: July 2015 |
Senior Member |
|
|
Hi,
about generating patterns, Jan's answer is basically the same I would suggest. Additionally, I would say generating the text should be more safe - we try to keep the EMF metamodel of the language stable, but sometimes there needs to be some minor additions, and in general it is a bit cumbersome to use. On the other hand, we are trying to keep the textual syntax possible (I guess it is still backwards compatible with the first release).
About the getAllMatches API: the pattern matcher classes each have a getAllMatches method with some parameters. Generic pattern matchers (that can be used without generating any code) have one that receives an array of Objects, where null means the parameter of the corresponding index is unset; while generated pattern matcher classes (created from all patterns) have generated typesafe methods, where each parameter can be set as the corresponding Java classes - such a getAllMatches method is the one you were asking about is available from either the headless example (http://git.eclipse.org/c/incquery/org.eclipse.incquery.examples.git/tree/headless), but only in the generated code. Although this uses a newer API of IncQuery, but such methods are available since the first release (maybe with a little bit different parameters.
Finally, unless you require compatibility with old Eclipse versions, I'd suggest to upgrade your EMF-IncQuery version to 0.9 (or if that is not possible for some reason, at least to 0.8 ), as the runtime API was greatly updated for version 0.8, and there were several performance fixes and enhancements that should make it easier to work with pattern matchers from EMF-IncQuery. Especially the generic API, that you would need to use to support generated patterns was changed noticeably, so I'd suggest an update before you have to migrate existing code.
Cheers,
Zoltán
[Updated on: Mon, 06 April 2015 16:36] by Moderator Report message to a moderator
|
|
|
Re: Passing arguments to IncQuery Patterns at Runtime [message #1691417 is a reply to message #1691368] |
Tue, 07 April 2015 06:50 |
Harkirat Singh Lamba Messages: 8 Registered: March 2015 |
Junior Member |
|
|
Hi,
We have some more doubts writing patterns at runtime
(1). To create queries at runtime, should we use the Generic API or the auto-genertaed classes ?
In the latter case, we can generate the java code of the classes in src-gen at runtime, compile them to create .class files and load the Classes.
We have observed the code in src-gen is generated at the time of building workspace so we wanted to take a look at the Builder code that does this.
(2). Is there any Github link from where we can fork the source code of the Incquery Project (0.9.1 version) ?
[Updated on: Tue, 07 April 2015 06:51] Report message to a moderator
|
|
|
Re: Passing arguments to IncQuery Patterns at Runtime [message #1691421 is a reply to message #1691417] |
Tue, 07 April 2015 07:52 |
Zoltan Ujhelyi Messages: 392 Registered: July 2015 |
Senior Member |
|
|
Hi,
(1) By default, I would use the generic API, as it is designed for exactly this use case. Although you can execute the code generator and include the generated classes in you application, but using the generic API should be much easier.
(2) There is no up-to-date EMF-IncQuery mirror on Github, and development happens on the eclipse.org infrastructure (repository browser here: http://git.eclipse.org/c/incquery/org.eclipse.incquery.git/), where there is already a tag for 0.9.1.
On the other hand, I would be interested why do you need to fork EMF-IncQuery. If it is some issue or use case you need to fix, if you would share it with us, we might support it out-of-the-box. It depends on the use case and implementation complexity, but in general we try to support as many cases as possible.
Cheers,
Zoltán
|
|
| | |
Re: Passing arguments to IncQuery Patterns at Runtime [message #1691605 is a reply to message #1691600] |
Wed, 08 April 2015 12:43 |
Zoltan Ujhelyi Messages: 392 Registered: July 2015 |
Senior Member |
|
|
Hi,
I will try to answer both of your posts together.
---
If you want to serialize pattern definitions in a textual format from an EMF model instance, you have to have an extensionparser registered for the eiq extension. If you have the EMF-IncQuery UI available as a plug-in in your Eclipse instance, you don't have to do anything, as it gets registered via an extension point (more specifically, the org.eclipse.incquery.patternlanguage.emf.ui does this).
If you don't have this plug-in available, make sure you call the EMFPatternLanguageStandaloneSetup#doSetup() static method before you try to use EMF-IncQuery. However, an important warning: do _not_ call this method if the org.eclipse.incquery.patternlanguage.emf.ui plug-in available, otherwise very strange issues may come ahead (e.g. strange classcastexceptions from inside Xtext).
After either the org.eclipse.incquery.patternlanguage.emf.ui is loaded in a plug-in environment, or the doSetup is called, when saving a file with the '.eiq' extension, the file should be serialized in a text form.
---
The thread you mentioned is related to older releases (0.6 and 0.7); there the generator was creating an xml representation of the pattern definitions that were used by the runtime (in this case, that was the opposite problem you were having).
---
Finally, the generic API assumes, you have a Pattern object, and it does not matter whether it is loaded from a textual form, from xmi form or only available in memory; so I guess, the original question is independent of the issues you are mentioning. For uses of the generic API, see our corresponding wiki page at https://wiki.eclipse.org/EMFIncQuery/UserDocumentation/API/Advanced#The_IncQuery_Generic_API; in the example we are loading the models from a textual eiq file; but if you already have the pattern object in-memory, consider only the part using the SpecificationBuilder...
Cheers,
Zoltán
|
|
| |
Re: Passing arguments to IncQuery Patterns at Runtime [message #1692073 is a reply to message #1692071] |
Mon, 13 April 2015 07:50 |
Zoltan Ujhelyi Messages: 392 Registered: July 2015 |
Senior Member |
|
|
Hi,
sadly, we consider the programmatic construction of patterns one of the weak points of the API. You could use the EMF API for the metamodel, but that can be, as you also said, hard to use. We don't have any other example that uses this approach - we are currently focusing on separating the runtime by the query specification interface from the specification aspect, and we are mostly relying on the pattern language based specification (instead of generating the patterns).
We have an additional, EMF-independent runtime API (if you open a generated query specification class, you can see a doGetContainedBodies() method that uses this approach. However, using this API is even more cumbersome, as (1) it is not documented; (2) it is not EMF-specific; EMF types are referred as Java Objects without any kind of validation (in case of incorrect patterns you either get an exception, or empty match sets) and (3) it needs to be carefully integrated into the query specification API.
We were thinking about providing a better API for defining patterns/query specification programmatically, but we don't have spare efforts in the short term to fix this issue.
About other tools that are useful: I guess, using Xtend instead of Java should reduce the amount of boilerplate code required; or maybe EMF-specific model transformation tools, such as ATL, Epsilon or the new VIATRA API could help.
Cheers,
Zoltán
|
|
| | | | |
Goto Forum:
Current Time: Fri Apr 19 03:33:59 GMT 2024
Powered by FUDForum. Page generated in 0.02771 seconds
|