在Xtext生成DSL项目中,编辑器内访问ResourceSet的正确方式咨询
在Xtext编辑器环境中正确创建DSL模型并加入ResourceSet
你完全没必要用StandaloneSetup——这确实是个坑,因为Xtext在Eclipse编辑器环境下已经有一套成熟的ResourceSet管理机制,手动启动StandaloneSetup大概率会导致双Injector冲突,各种奇奇怪怪的问题随之而来。下面是正确的操作方式:
1. 获取Xtext管理的ResourceSet
在编辑器环境里,有几种可靠的方式拿到框架维护的ResourceSet:
方式一:从当前激活的XtextEditor获取
如果你的向导是和当前打开的DSL文件关联的,可以直接从活跃编辑器入手:
// 获取当前活跃的Xtext编辑器 XtextEditor activeEditor = (XtextEditor) PlatformUI.getWorkbench() .getActiveWorkbenchWindow().getActivePage().getActiveEditor(); // 从编辑器拿到对应的文档和资源 IXtextDocument document = activeEditor.getDocument(); XtextResource currentResource = (XtextResource) document.getResource(); // 这就是Xtext已经管理好的ResourceSet ResourceSet resourceSet = currentResource.getResourceSet();
方式二:通过ResourceSetProvider针对项目获取
如果你的向导是为某个特定项目生成文件,推荐用IResourceSetProvider,它会为项目返回对应的ResourceSet,这也是Xtext官方推荐的方式:
// 先注入IResourceSetProvider(确保你的类被Xtext的Injector管理) @Inject private IResourceSetProvider resourceSetProvider; // 然后传入目标项目 IProject targetProject = ...; // 你的向导选中的项目 ResourceSet resourceSet = resourceSetProvider.get(targetProject);
如果你的向导类还没被注入,可以手动获取全局Injector来注入自己:
Injector injector = PlatformUI.getWorkbench().getService(IInjectorProvider.class).getInjector(); injector.injectMembers(yourWizardClassInstance);
2. 创建DSL模型并写入新文件
拿到ResourceSet之后,就可以创建模型对象并绑定到新资源了:
// 1. 定义新文件的URI(注意用平台资源URI格式) URI newFileUri = URI.createPlatformResourceURI( targetProject.getName() + "/src/main/dsl/new-model.yourdsl", true); // 2. 在ResourceSet中创建新的Resource Resource newResource = resourceSet.createResource(newFileUri); // 3. 创建DSL模型实例(替换成你的DSL根元素类) YourDslRootModel root = YourDslFactory.eINSTANCE.createYourDslRootModel(); // 给模型设置属性、添加子元素 root.setName("NewModel"); // ... 其他模型操作 // 4. 将模型加入Resource的内容列表 newResource.getContents().add(root); // 5. 保存资源到文件 try { newResource.save(Collections.emptyMap()); } catch (IOException e) { // 处理保存异常,比如给用户弹出错误提示 e.printStackTrace(); }
3. 为什么不能用StandaloneSetup?
StandaloneSetup是为非UI环境(比如命令行批量处理、单元测试)设计的初始化工具,它会创建一套独立的Injector和ResourceSet体系。而在Eclipse编辑器里,Xtext已经通过SharedStateModule初始化了全局的Injector,所有编辑器、资源都共享这套体系。如果强行启动StandaloneSetup,会出现两个独立的Injector,导致模型对象不兼容、资源无法被编辑器识别等问题,完全没必要给自己找麻烦。
内容的提问来源于stack exchange,提问作者fx88
相关产品推荐
相关产品推荐

