Home » Modeling » TMF (Xtext) » Access all Resources in Eclipse(Xtext) Project
Access all Resources in Eclipse(Xtext) Project [message #1767945] |
Wed, 12 July 2017 10:05 |
Lukas Schaus Messages: 37 Registered: October 2016 |
Member |
|
|
Hello,
I am developing a DSL using xtext 2.12. The DSL supports a user in writing software requirements.
I have the following Use Case:
A user wants to structure his requirements in multiple files. If any of the files is saved I want to generate an overview of all requirements that are specified in all of the files.
I found a solution from 2011:
https://kthoms.wordpress.com/2011/07/
Unfortunately it does not seem to work in the current version of xtext.
How can I access all resources in my Generator
Thanks in advance.
Lukas
[Updated on: Wed, 12 July 2017 10:24] Report message to a moderator
|
|
| | |
Re: Access all Resources in Eclipse(Xtext) Project [message #1767975 is a reply to message #1767970] |
Wed, 12 July 2017 13:34 |
|
if i knew that pointer i would have pointed.
and as i said:
new Interface is Igenerator2 so you may need a Igenerator2
and as you have discovered its BuilderParticipant now
so i would have thought a naive adaption of these two would work.
untested
public class BuilderParticipant2 extends BuilderParticipant {
@Inject
private ResourceDescriptionsProvider resourceDescriptionsProvider;
@Inject
private IContainer.Manager containerManager;
@Inject(optional = true)
private IGenerator3 generator;
protected ThreadLocal<Boolean> buildSemaphor = new ThreadLocal<Boolean>();
@Override
public void build(IBuildContext context, IProgressMonitor monitor) throws CoreException {
buildSemaphor.set(false);
super.build(context, monitor);
}
@Override
protected void handleChangedContents(Delta delta, IBuildContext context,
EclipseResourceFileSystemAccess2 fileSystemAccess) throws CoreException {
super.handleChangedContents(delta, context, fileSystemAccess);
if (!buildSemaphor.get() && generator != null) {
invokeGenerator(delta, context, fileSystemAccess);
}
}
private void invokeGenerator(Delta delta, IBuildContext context, EclipseResourceFileSystemAccess2 access) {
buildSemaphor.set(true);
Resource resource = context.getResourceSet().getResource(delta.getUri(), true);
if (shouldGenerate(resource, context)) {
IResourceDescriptions index = resourceDescriptionsProvider.createResourceDescriptions();
IResourceDescription resDesc = index.getResourceDescription(resource.getURI());
List<IContainer> visibleContainers = containerManager.getVisibleContainers(resDesc, index);
for (IContainer c : visibleContainers) {
for (IResourceDescription rd : c.getResourceDescriptions()) {
context.getResourceSet().getResource(rd.getURI(), true);
}
}
MonitorBasedCancelIndicator cancelIndicator = new MonitorBasedCancelIndicator(
new NullProgressMonitor()); //maybe use reflection to read from fsa
GeneratorContext generatorContext = new GeneratorContext();
generatorContext.setCancelIndicator(cancelIndicator);
generator.doGenerate(context.getResourceSet(), access, generatorContext);
}
}
}
public interface IGenerator3 extends IGenerator2 {
public void doGenerate(ResourceSet input, IFileSystemAccess2 fsa, IGeneratorContext context);
}
and no its a pretty non std usecase.
Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
|
|
|
Re: Access all Resources in Eclipse(Xtext) Project [message #1768155 is a reply to message #1767975] |
Fri, 14 July 2017 08:31 |
Lukas Schaus Messages: 37 Registered: October 2016 |
Member |
|
|
Thank you very much Christian. The adaptations you made worked perfectly.
I additionally had to bind the IGenerator3 in the main project and the BuilderParticipant in the UI Project.
Also I implemented a new Interface that replaces the AbstractGenerator. The new AbstractGenerator2 implements my IGenerator3.
As you can see in the code below I managed to extract a root element from every file. (Root is the Root rule in my grammar)
Is there a way to join those root elements?
For anybody who has the same use case like me here the code:
MyDslGenerator:
class MyDslGenerator extends AbstractGenerator2 {
override doGenerate(ResourceSet input, IFileSystemAccess2 fsa, IGeneratorContext context) {
val allResources = input.resources.map(r|r.allContents.toIterable.filter(Root)).flatten
//do stuff
AbstractGenerator2:
public abstract class AbstractGenerator2 implements IGenerator3 {
@Override
public void doGenerate(Resource input, IFileSystemAccess2 fsa, IGeneratorContext context) {
}
@Override
public void beforeGenerate(Resource input, IFileSystemAccess2 fsa, IGeneratorContext context) {
}
@Override
public void afterGenerate(Resource input, IFileSystemAccess2 fsa, IGeneratorContext context) {
}
@Override
public void doGenerate(ResourceSet input, IFileSystemAccess2 fsa, IGeneratorContext context) {
}
}
IGenerator3:
interface IGenerator3 extends IGenerator2 {
def void doGenerate(ResourceSet input, IFileSystemAccess2 fsa, IGeneratorContext context);
}
class MyDslModule extends AbstractMarsLangRuntimeModule {
def Class<? extends IGenerator3> bindIGenerator3 () {
return MyDslGenerator
}
}
@FinalFieldsConstructor
class MyDslUiModule extends MyDslUiModule {
override def Class<? extends IXtextBuilderParticipant> bindIXtextBuilderParticipant() {
return BuilderParticipant2
}
}
|
|
|
Re: Access all Resources in Eclipse(Xtext) Project [message #1792969 is a reply to message #1768155] |
Thu, 26 July 2018 16:08 |
Denis Kuniß Messages: 13 Registered: January 2010 |
Junior Member |
|
|
Thanks to all. Helped me too to solve my problem. So want to give a little bit back:
As JavaProjectBasedBuilderParticipant has been deprecated, I tried to implement this based on the new org.eclipse.xtext.builder.BuilderParticipant which was recommended in the deprecation note.
The following worked for me, I just renamed the original IGenerator2 interface to IGeneratorForResourceSet
class BuilderParticipantForResourceSet extends BuilderParticipant {
@Inject
ResourceDescriptionsProvider resourceDescriptionsProvider;
@Inject
IContainer.Manager containerManager;
@Inject (optional=true)
IGeneratorForResourceSet generator;
protected ThreadLocal<Boolean> buildSemaphor = new ThreadLocal<Boolean>();
override void build(IBuildContext context, IProgressMonitor monitor) throws CoreException {
buildSemaphor.set(false);
super.build(context, monitor);
}
override void handleChangedContents(Delta delta, IBuildContext context, IFileSystemAccess fileSystemAccess) {
super.handleChangedContents(delta, context, fileSystemAccess);
if (!buildSemaphor.get() && generator !== null) {
invokeGenerator(delta, context, fileSystemAccess);
}
}
private def void invokeGenerator (Delta delta, IBuildContext context, IFileSystemAccess fileSystemAccess) {
buildSemaphor.set(true);
val Resource resource = context.getResourceSet().getResource(delta.getUri(), true);
if (shouldGenerate(resource, context)) {
val IResourceDescriptions index = resourceDescriptionsProvider.createResourceDescriptions();
val IResourceDescription resDesc = index.getResourceDescription(resource.getURI());
val List<IContainer> visibleContainers = containerManager.getVisibleContainers(resDesc, index);
for (IContainer c : visibleContainers) {
for (IResourceDescription rd : c.getResourceDescriptions()) {
context.getResourceSet().getResource(rd.getURI(), true);
}
}
generator.doGenerate(context.getResourceSet(), fileSystemAccess as IFileSystemAccess2);
}
}
}
Still having one doubt: Is this working without Eclipse too? I thought, the ui package is used for Eclipse inside only. Am I wrong?
|
|
|
Goto Forum:
Current Time: Fri Mar 29 10:25:54 GMT 2024
Powered by FUDForum. Page generated in 0.04182 seconds
|