对不起,我花了这么长时间回应。我尝试了基督徒的建议,并不是非常满意,而且优先级转移了。现在,我将再次探讨这个问题,并且为了记录其他人(并清除我的头),我会记下我迄今为止所做的事情,因为这并不是那么简单并且需要大量的实验。
我不会发布完整的课程,但只有相关的部分。如果您需要更多细节,请随时咨询。
我的语法,定义现在看起来是这样的:
Model:
stakeholders+=StakeholderDecl*
requirements+=Requirement*;
Requirement:
'As a' stakeholder=[Stakeholder] 'I want' want=('everything' | 'cookies' | 'results')
;
StakeholderDecl returns Stakeholder :
'Stakeholder' Stakeholder
;
Stakeholder:
name=ID
;
让大家注意的是,下面的一切需要在.ui
包来完成。
首先,我创建StakeholdersProvider.xtend
:
class StakeholdersProvider extends AbstractResourceDescription {
// this is the dummy for an "external source". Just raw data.
val nameList = newArrayList("buddy", "boss")
val cache = nameList.map[it.toDescription]
private val uri = org.eclipse.emf.common.util.URI.createPlatformResourceURI("neverland", true)
def public List<IEObjectDescription> loadAdditionalStakeholders() {
cache
}
def private IEObjectDescription toDescription(String name) {
ExternalFactoryImpl.init()
val ExternalFactory factory = new ExternalFactoryImpl()
val Stakeholder obj = factory.createStakeholder as StakeholderImpl
obj.setName(name)
new StakeholderDescription(name, obj, uri)
}
. . .
override getURI() {
uri
}
def public boolean isProvided(EObject object) {
if(object.eClass.classifierID != ExternalPackageImpl.STAKEHOLDER) {
false
}
else {
val stakeholder = object as Stakeholder
nameList.exists[it == stakeholder.name]
}
}
}
注意,供应商也是resourceDescription及其课程的URI是无稽之谈。
有了这个提供商,我写了ScopeWrapper.xtend
:
class ScopeWrapper implements IScope {
private var IScope scope;
private var StakeholdersProvider provider
new(IScope scopeParam, StakeholdersProvider providerParam) {
scope=scopeParam
provider = providerParam
}
override getAllElements() {
val elements = scope.allElements.toList
val ret = provider.loadAdditionalStakeholders()
ret.addAll(elements)
ret
}
override getSingleElement(QualifiedName name) {
allElements.filter[it.name == name].head
}
. . .
}
和ResourceDescriptionWrapper.xtend
class ResourceDescriptionsWrapper implements IResourceDescriptions {
private StakeholdersProvider provider;
private IResourceDescriptions descriptions;
new(IResourceDescriptions descriptionsParam, StakeholdersProvider providerParam) {
descriptions = descriptionsParam
provider = providerParam
}
override getAllResourceDescriptions() {
val resources = descriptions.allResourceDescriptions.toList
resources.add(provider)
resources
}
override getResourceDescription(URI uri) {
if(uri == provider.URI) provider
else descriptions.getResourceDescription(uri)
}
override getExportedObjects() {
val descriptions = descriptions.exportedObjects.toList
descriptions.addAll(provider.exportedObjects)
descriptions
}
. . . some overrides for getExportedObjects-functions
}
所有这一切都是连接在一起MyGlobalScopeProvider.xtend
class MyGlobalScopeProvider extends TypesAwareDefaultGlobalScopeProvider {
val provider = new StakeholdersProvider()
override getScope(Resource context, EReference reference, Predicate<IEObjectDescription> filter) {
val scope = super.getScope(context, reference, filter)
return new ScopeWrapper(scope, provider)
}
override public IResourceDescriptions getResourceDescriptions(Resource resource) {
val superDescr = super.getResourceDescriptions(resource)
return new ResourceDescriptionsWrapper(superDescr, provider)
}
}
这是在MyDslUiModule.java
注册
public Class<? extends IGlobalScopeProvider> bindIGlobalScopeProvider() {
return MyGlobalScopeProvider.class;
}
到目前为止好。我现在得到boss
和buddy
作为利益相关者。但是,当我使用其中一个2时,编辑器中出现错误,抱怨悬挂引用和控制台中的错误日志记录,利益相关方cannot be exported as the target is not contained in a resource
。搞清楚这些2可能都跟我试图修复错误记录,创造了MyresourceDescriptionStrategy.xtend
class MyResourcesDescriptionStrategy extends DefaultResourceDescriptionStrategy {
val provider = new StakeholdersProvider()
override isResolvedAndExternal(EObject from, EObject to) {
if (provider.isProvided(to)) {
// The object is a stakeholder that was originally provided by
// our StakeholdersProvider. So we mark it as resolved.
true
} else {
super.isResolvedAndExternal(from, to)
}
}
}
,并在UiModule线它:
public Class<? extends IDefaultResourceDescriptionStrategy> bindDefaultResourceDescriptionStrategy() {
return MyResourcesDescriptionStrategy.class;
}
这修复记录错误,但“悬参考”的问题遗迹。我寻找解决方案,most prominent result建议定义一个IResourceServiceProvider
本来是解决我的问题的最佳方法。 我会花更多时间在当前的方法上,并尝试使用ResourceProvider。
编辑:我得到了“悬挂参考”问题修复。在StakeholdersProvider.xtend
的loadAdditionalStakeholders()
函数现在看起来是这样的:
override loadAdditionalStakeholders() {
val injector = Guice.createInjector(new ExternalRuntimeModule());
val rs = injector.getInstance(ResourceSet)
val resource = rs.createResource(uri)
nameList.map[it.toDescription(resource)]
}
def private IEObjectDescription toDescription(String name, Resource resource) {
ExternalFactoryImpl.init()
val ExternalFactory factory = new ExternalFactoryImpl()
val Stakeholder obj = factory.createStakeholder as StakeholderImpl
obj.setName(name)
// not sure why or how but when adding the obj to the resource, the
// the resource will be set in obj . . . thus no more dangling ref
resource.contents += obj
new StakeholderDescription(name, obj, uri)
}
你会基本上适应全球范围内供应商对你的外部的东西创造eobjects那里。手动解析和缓存问题不能为一般usacase回答,它是非常具体的每个用例(分贝vs文件与其他)以及这些资源如何以及何时改变以及它们如何检测其变化 – 2015-03-31 10:32:20
Thx Christian。是的,我故意忽略了“特定”部分。我明天会尝试你的建议。仍然不知道如何将EObjects连接到我的xtext文件中,但至少现在我知道要在哪里深入挖掘...... – agschaid 2015-04-01 22:52:21