Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » TMF (Xtext) » Efficiently getting EObjects of a particular type given only their parent Xtext+Sirius IProject
Efficiently getting EObjects of a particular type given only their parent Xtext+Sirius IProject [message #1859616] Tue, 20 June 2023 12:32 Go to next message
Matt Windsor is currently offline Matt WindsorFriend
Messages: 13
Registered: July 2022
Junior Member
Hi all,

I'm working on a plugin that, as part of its feature set, needs to correlate data stored in EMF/Xtext modelling projects (on a language I'll call Bar here; Bar is an Xtext DSL with a Sirius6 representation) with data stored outside of the modelling workflow but still associated with the same Eclipse project. This means that, for instance, I need to get a list of all EObjects of type Foo from outside of any context where I already have a Resource or EObject; all I seem to have is the IProject. (I've seen a lot of people asking how to query EMF through an IProject, but they all seem to be trying to generate something; I don't think this use case is answered by generation?)

So far, I have Java17 code similar to this, where I'm using the internal textual-UI injector of language Bar to get myself the Xtext resource set provider, using that to get a resource set, and then... manually scraping through the files of the project to see if any look like they contain Bar models and feeding them into the resource set before I do an EMF query:

public class FooFinder {
	private List<Foo> _result;
	private ResourceSet _resourceSet;

	public Result find(IProject project) throws CoreException, IOException {
		_result = new ArrayList<>();
		
		getResources(project);
		fetchFoo();
		
		return _result;
	}

	private void getResources(IProject project) throws CoreException, IOException {
		if (project == null) {
			return;
		}

		getResourceSet(project);
		processContainer(project);
	}
	
	private void getResourceSet(IProject project) {
		var inj = BarActivator.getInstance().getInjector(BarActivator.LANGUAGE_ID);
		var prov = inj.getInstance(IResourceSetProvider.class);
		_resourceSet = prov.get(project);
	}
	
	private void processContainer(IContainer container) throws CoreException, IOException {
		for (var member : container.members()) {
			if (member instanceof IContainer c) {
				processContainer(c);
			} else if (member instanceof IFile f) {
				processFile(f);
			}
		}
	}
	
	private void processFile(IFile file) throws IOException {
		if (!isBarFile(file)) {
			return;
		}
		
		var uri = URI.createPlatformResourceURI(file.getFullPath().toString(), true);
		_resourceSet.getResource(uri, true);
	}
	
	private boolean isBarFile(IFile file) {
		return file.getFileExtension().equals("bar");  // there is probably a better way of checking this
	}
	
	private void fetchFoo() {
		for (var res : _resourceSet.getResources()) {			
			_result.addAll(EcoreUtil2.typeSelect(EcoreUtil2.eAllContentsAsList(res), Foo.class));
		}
	}
}


This works inasmuch as it retrieves the correct model data, but:


  • it seems unidiomatic, and liable to be manually performing tasks that something in Xtext or Sirius should be taking care of;
  • I've been advised that it is probably performing redundant loading and validation activities;
  • this is especially true given that the Bar language has a Sirius view that will almost certainly be open when this query is run, and will likely already have some or all of the resources available;
  • if I do this, how do I write back any changes I want to make to the models programmatically, given I've mostly abandoned any of the Xtext infrastructure on the way to getting these models?


Thanks,
~ Matt

[Updated on: Tue, 20 June 2023 12:39]

Report message to a moderator

Re: Efficiently getting EObjects of a particular type given only their parent Xtext+Sirius IProject [message #1859617 is a reply to message #1859616] Tue, 20 June 2023 13:42 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14721
Registered: July 2009
Senior Member
the question is what are you going to do with the foos.

Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Day Job: https://www.everest-systems.com
Re: Efficiently getting EObjects of a particular type given only their parent Xtext+Sirius IProject [message #1859618 is a reply to message #1859617] Tue, 20 June 2023 14:00 Go to previous messageGo to next message
Matt Windsor is currently offline Matt WindsorFriend
Messages: 13
Registered: July 2022
Junior Member
Thanks for the reply!

I'd be performing queries based on matching them up with data from a database, for instance 'list all Foo such that there exists a Foobar in the database that references this Foo', then displaying the results to the user in various Eclipse/SWT views/dialogs, more specifically:


  • the call to perform the query is coming from a Command from within the eclipse3 API stack (eg a button or menu item in some view), and isn't initiated by any action on the model;
  • the database is exposed as an Eclipse service, which might make it visible at the Xtext side;
  • I have access to the IProject, but not directly to the EObjects, Resources, or ResourceSets;
  • there is a graphical view of part of the model available through Sirius, which I could try call into to try get to the EMF model, but not all of the things that I want to do will involve Sirius so that feels strange.


I expected I'd need to do the query at the Command level by pulling Foo out of the EMF model, transforming it into a form that can be sent to the database, then performing the query. If it's easier to somehow invoke a generator with a handle to the database, get it to generate the results of the query, then either scrape the generated files back into something I can present to the user (or just point the user to the generated files), I could look into that, though I'd prefer the workflow to be as in-Eclipse as possible.
Re: Efficiently getting EObjects of a particular type given only their parent Xtext+Sirius IProject [message #1859625 is a reply to message #1859618] Tue, 20 June 2023 16:37 Go to previous messageGo to next message
Ed Willink is currently offline Ed WillinkFriend
Messages: 7675
Registered: July 2009
Senior Member
Hi

I have access to the IProject, but not directly to the EObjects, Resources, or ResourceSets;

This is not necessarily true. You have access to the current selection which via a derived ISelection will reference directly or indirectly an EObject from which you can navigate up to the ResourceSet and down to all the Foo's.

You may find some helpful ideas in https://git.eclipse.org/r/plugins/gitiles/ocl/org.eclipse.ocl/+/refs/heads/master/plugins/org.eclipse.ocl.xtext.base.ui/src/org/eclipse/ocl/xtext/base/ui/utilities/BaseUIUtil.java

Regards

Ed Willink
Re: Efficiently getting EObjects of a particular type given only their parent Xtext+Sirius IProject [message #1859627 is a reply to message #1859625] Tue, 20 June 2023 18:04 Go to previous messageGo to next message
Ed Willink is currently offline Ed WillinkFriend
Messages: 7675
Registered: July 2009
Senior Member
Alternatively you may use the currentView / currentEditor as the gateway to model discovery. For Xtext you may find that a custom XtextEditor derivation can provide the richer API necessary to make progress from the downcast editor.
Re: Efficiently getting EObjects of a particular type given only their parent Xtext+Sirius IProject [message #1859628 is a reply to message #1859627] Tue, 20 June 2023 18:06 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14721
Registered: July 2009
Senior Member
you might also consider querying the Xtext index depending your usecase

Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Day Job: https://www.everest-systems.com
Re: Efficiently getting EObjects of a particular type given only their parent Xtext+Sirius IProject [message #1859629 is a reply to message #1859627] Tue, 20 June 2023 18:26 Go to previous messageGo to next message
Matt Windsor is currently offline Matt WindsorFriend
Messages: 13
Registered: July 2022
Junior Member
Thanks for this! I think I missed some more context though (the project isn't externally distributable which makes things difficult to explain, apologies! [edit: this message got truncated on submission, I'll re-reply later with what I meant to say; apologies]

[Updated on: Tue, 20 June 2023 18:28]

Report message to a moderator

Re: Efficiently getting EObjects of a particular type given only their parent Xtext+Sirius IProject [message #1859645 is a reply to message #1859625] Wed, 21 June 2023 08:35 Go to previous messageGo to next message
Matt Windsor is currently offline Matt WindsorFriend
Messages: 13
Registered: July 2022
Junior Member
Ok, sorry for the mangled message earlier. I tried writing a reply on my phone and only a small part of it saved.

Ed Willink wrote on Tue, 20 June 2023 16:37

This is not necessarily true. You have access to the current selection which via a derived ISelection will reference directly or indirectly an EObject from which you can navigate up to the ResourceSet and down to all the Foo's.


The plugin structure is perhaps unusual (and inherited, so I'm unsure how easily I can change it): the plugin that is going to be doing the querying isn't an Xtext editor, but instead it has a couple of bespoke views that are IProject-aware but only concerned with displaying and manipulating the database. There is also the Sirius viewpoint over the EMF/Xtext model, but the Xtext editor itself isn't likely to get used and I can't rely on it being visible.

The flow of data from the database end to the EMF/Xtext end is a little awkward: when the user creates Foo representations in Sirius, the plugin for the Sirius viewpoint calls Commands in the database plugin which create the database representation of a Foo, then scrapes the results to use when constructing the EMF representation of a Foo (so both ends get separate representations of the same data; one EMF, one POJO). Right now, there is no flow of EMF data into the database plugin -- I'd have presumed this means I can't rely on selections as these would usually just pick up the POJO version not the EMF version?

Since the EMF/Xtext end is aware of the database end, there might be a way of getting it to supply some handle to part of the model, but again I'm unsure how to do this.

Thanks!
Re: Efficiently getting EObjects of a particular type given only their parent Xtext+Sirius IProject [message #1859646 is a reply to message #1859628] Wed, 21 June 2023 08:40 Go to previous messageGo to next message
Matt Windsor is currently offline Matt WindsorFriend
Messages: 13
Registered: July 2022
Junior Member
Christian Dietrich wrote on Tue, 20 June 2023 18:06

you might also consider querying the Xtext index depending your usecase


Hmm, I looked into this (particularly https://www.eclipse.org/Xtext/documentation/303_runtime_concepts.html), but got stuck on two things:


  • the API I could see for filtering to visible containers seemed to be expecting a resource description to serve as the reference point... unless I should just be directly using the index and not doing that filtering? Would I need to filter the resources to make sure they're in the project, the correct language, etc.?
  • I wasn't sure how to go from a resource description to a resource, unless I should just simply be taking the URI and loading it into a resource set (which seems like it'd be similar to scraping the project directories for xtext source files and reading them in).
Re: Efficiently getting EObjects of a particular type given only their parent Xtext+Sirius IProject [message #1859647 is a reply to message #1859646] Wed, 21 June 2023 09:26 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14721
Registered: July 2009
Senior Member
yes you need to filter for the project.
so you need any uri in the project
ask this to get resource descriptiomn
then ask it for container
then for visible ones.

but the project should be part of the uris.
=> you can filter based on the segment



Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Day Job: https://www.everest-systems.com
Re: Efficiently getting EObjects of a particular type given only their parent Xtext+Sirius IProject [message #1859649 is a reply to message #1859647] Wed, 21 June 2023 12:39 Go to previous messageGo to next message
Ed Willink is currently offline Ed WillinkFriend
Messages: 7675
Registered: July 2009
Senior Member
When I suggested using the current selection, I did not say that it had to be an Xtext editor. Any EMF-based view will do. Surely your UI has a selection? Sirius is certainly suitable for selection-based discovery.

Re: Efficiently getting EObjects of a particular type given only their parent Xtext+Sirius IProject [message #1860537 is a reply to message #1859649] Mon, 14 August 2023 09:32 Go to previous message
Matt Windsor is currently offline Matt WindsorFriend
Messages: 13
Registered: July 2022
Junior Member
Hi all,

I forgot to reply previously - what I've ended up doing, since other bits of my project have strengthened coupling to Sirius, is grabbing the local Sirius session(s) through the session manager and finding all semantic elements of the right type through that instead. I was initially worried this would miss resources when their representations weren't open in Eclipse, but this seems not to be the case.

Thanks for your help!
Previous Topic:LSP Support: Multiple Languages in one Server
Next Topic:How to implement nested conditional formatting?
Goto Forum:
  


Current Time: Mon Oct 07 20:43:52 GMT 2024

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

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

Back to the top