Reputation: 2446
I have a dsl grammar in xtext that I am using in my eclipse plugin. in the plugin the user manually creates an new file (like the blog.dmodel file in https://eclipse.org/Xtext/documentation/102_domainmodelwalkthrough.html)
In my plugin code, when a user right clicks in the dmodel file, he can select from the right click menu an option that triggers a method called traverseAST() This method currently finds the
IWorkspaceRoot root = workspace.getRoot();
IProject project = root.getProject(projectName);
IFolder folder = project.getFolder(path);
IFile file = folder.getFile(fileName);
I understand that IFile is not what I can use to traverse the AST, so I am trying the following approach
@Inject
static ResourceSet resourceSet;
public traverseAST(){
IWorkspaceRoot root = workspace.getRoot();
IProject project = root.getProject(projectName);
IFolder folder = project.getFolder(path);
IFile file = folder.getFile(fileName);
org.eclipse.emf.common.util.URI uri = org.eclipse.emf.common.util.URI.createPlatformResourceURI(file.getFullPath().toString(), true);
ResourceSet set = new ResourceSetImpl();
Resource resource = set.createResource(uri);
TreeIterator<Object> x1 = EcoreUtil.getAllContents(resource, true);
TreeIterator<Object> x2 = EcoreUtil.getAllContents(resource, false);
}
My resource is org.eclipse.xtext.linking.lazy.LazyLinkingResource@1230a38d uri='platform:/resource/demo/src/blog.dmodel'
but both x1 and x2 are empty.
What am I doing wrong?
_____EDIT______ per Christian Dietrich suggestions my code is now
IWorkspaceRoot root = workspace.getRoot();
IProject project = root.getProject(projectName);
IFolder folder = project.getFolder(path);
IFile file = folder.getFile(fileNameWithoutExtension + suffix);
org.eclipse.emf.common.util.URI uri = org.eclipse.emf.common.util.URI.createPlatformResourceURI(file.getFullPath().toString(), true);
IResourceSetProvider rs1 = IResourceServiceProvider.Registry.INSTANCE.getResourceServiceProvider(uri).get(IResourceSetProvider.class);
ResourceSet rs = rs1.get(project);
Resource r = rs.getResource(uri, true);
the uri
value is
platform:/resource/demo/src/blog.dmodel
rs1
is
org.eclipse.xtext.ui.resource.XtextResourceSetProvider@2faab150
FactoryProxy[key=Key[type=org.eclipse.xtext.resource.XtextResourceSet, annotation=[none]], provider=com.google.inject.internal.ConstructorBindingImpl$Factory@6185cb4d]
rs
is org.eclipse.xtext.resource.SynchronizedXtextResourceSet@39fcefea resources=[org.eclipse.xtext.linking.lazy.LazyLinkingResource@25d48650 uri='platform:/resource/demo/src/blog.dmodel']
r is
org.eclipse.xtext.linking.lazy.LazyLinkingResource@25d48650 uri='platform:/resource/demo/src/blog.dmodel'
but the content is []
EDIT 2_
sharing more code per request.
my eclipse menu handler code BaseMenuHandler.java The following code is activated when the user is clicking on the option in the drop down menu. This is a standard addition of an option to an Eclipse menu static public class InsertEvents { @Override public Object execute(ExecutionEvent event) throws ExecutionException { IWorkspace workspace = ResourcesPlugin.getWorkspace(); IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); Traverse.traverseAST(page, workspace); }
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.ide.IDE;
import org.eclipse.xtext.resource.IResourceServiceProvider;
import org.eclipse.xtext.ui.resource.IResourceSetProvider;
public class Traverse{
public static void traverseAST(IWorkbenchPage page, IWorkspace workspace) {
IFile ifile = getSelectedIFile();
if (ifile != null) {
String fileName = ifile.getName();
String fileNameWithoutExtension = fileName.replace(ifile.getFileExtension().toString(), "");
String projectName = ifile.getProject().getName();
String path = ifile.getProjectRelativePath().toString().replace("/" + fileName, "");
IWorkspaceRoot root = workspace.getRoot();
IProject project = root.getProject(projectName);
IFolder folder = project.getFolder(path);
IFile file = folder.getFile(fileNameWithoutExtension + "dmodel");
if (suffix.equals("dmodel")){
String path1 = file.getFullPath().toString();
org.eclipse.emf.common.util.URI uri = org.eclipse.emf.common.util.URI.createPlatformResourceURI(file.getFullPath().toString(), true);
IResourceSetProvider rs1 = IResourceServiceProvider.Registry.INSTANCE.getResourceServiceProvider(uri).get(IResourceSetProvider.class);
ResourceSet rs = rs1.get(project);
Resource r = rs.getResource(uri, true);
TreeIterator<Object> x1 = EcoreUtil.getAllContents(r, true);
TreeIterator<Object> x2 = EcoreUtil.getAllContents(r, false);
}
}
the blog.dmodel code is the 15 minutes tutorial without any changes from here: https://eclipse.org/Xtext/documentation/102_domainmodelwalkthrough.html ____EDIT 3____ Following our conversation I've created main under the xtext project (blog.mydsl)
package blog.mydsl;
import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.example.domainmodel.DomainmodelStandaloneSetup;
import com.google.inject.Injector;
public class Main {
public static void main(String[] args) {
URI uri = URI.createURI("/Users/Desktop/demo.mydsl");
Injector i = new DomainmodelStandaloneSetup().createInjectorAndDoEMFRegistration();
ResourceSet rs = i.getInstance(ResourceSet.class);
Resource r = rs.getResource(uri, true);
TreeIterator<Object> x1 = EcoreUtil.getAllContents(r, true);
while (x1.hasNext()) {
System.out.println(x1.next());
}
TreeIterator<Object> x2 = EcoreUtil.getAllContents(r, false);
while (x2.hasNext()) {
System.out.println(x2.next());
}
}
}
This seems to be working. Since I did not do anything like the following Injector i = new DomainmodelStandaloneSetup().createInjectorAndDoEMFRegistration(); in my original code, should this be the way to go? should I move the plugin code to the blog.mydsl src folder? should I look into the URI?
Upvotes: 1
Views: 570
Reputation: 11868
The following should work.
@Inject
IResourceSetProvider resourceSetProvider;
...
URI uri = URI.createPlatformResourceURI(file.getFullPath().toString(), true);
ResourceSet rs = resourceSetProvider.get(project);
Resource r = rs.getResource(uri, true);
if you dont create your code via guice (YourDslExecutableExtensionFactory
) you can obtain an Injector
or the IResourceSetProvider
via IResourceServiceProvider.Registry.INSTANCE.getResourceServiceProvider(uri).get(IResourceSetProvider.class);
update:
which the code you shared (i had to improvise a lot) it looks more like a debugging issue. see
org.eclipse.emf.common.util.URI uri = org.eclipse.emf.common.util.URI
.createPlatformResourceURI(file.getFullPath().toString(), true);
IResourceSetProvider rs1 = IResourceServiceProvider.Registry.INSTANCE.getResourceServiceProvider(uri)
.get(IResourceSetProvider.class);
ResourceSet rs = rs1.get(project);
Resource r = rs.getResource(uri, true);
TreeIterator<Object> x1 = EcoreUtil.getAllContents(r, true);
while(x1.hasNext()) {
System.out.println(x1.next());
}
TreeIterator<Object> x2 = EcoreUtil.getAllContents(r, false);
while(x2.hasNext()) {
System.out.println(x2.next());
}
Upvotes: 1