[英]Is it allowed to access another Resource in an Xtext validator?
我遇到了來自另一位開發人員的一些代碼,該開發人員試圖針對其他對象BooFar
驗證 object FooBar
,代碼執行如下操作:
// Xtend code
@Inject IContainer.Manager containerManager
@Inject IResourceDescriptions resourceDescriptions
@Inject Provider<XtextResourceSet> resourceSetProvider
@Check
def validate(FooBar foobar) {
var desc = resourceDescriptions.getResourceDescription(foobar.eResource.URI)
var visibleContainers = containerManager.getVisibleContainers(desc, resourceDescriptions)
for (visibleContainer : visibleContainers) {
var exported = visibleContainer.getExportedObjectsByType(ModelPackage.Literals.BOOFAR)
var allObjects = newArrayList
exported.forEach [boofar |
// this is the line I'm interested about -->
allObjects.add(resourceSetProvider.get.getEObject(boofar.EObjectURI, true) as BooFar)
]
// ...
}
// ...
}
因此,此驗證器嘗試訪問“類路徑”並加載所有導出的BOOFAR
對象以進行驗證。
現在我的問題是:這是否允許?
顯然不好,因為
resourceSetProvider
會為每個BOOFAR
EObjectDescription
創建一個新的ResourceSet
EObjectDescription
,都會加載並解析一個Resource
以解析EObject
我知道(至少我認為我知道)交叉驗證的更多(最?)最佳方法是將驗證所需的所有信息包含在EObjectDescription
object 的BooFar
中,因此,不是解決 object 而是驗證EObjectDescription
。
我的問題是:上述是否允許,代碼除了速度慢之外還有其他缺點嗎?
另外 -獎勵問題- 我還看到了針對已驗證資源的resourceSet
進行解析的代碼。 因此,在上面的示例代碼中,將有問題的行替換為
allObjects.add(EcoreUtil.resolve(boofar.EObjectOrProxy, foobar.eResource.resourceSet) as BooFar)
這是允許的嗎? 我的想法是,這可能會導致問題,因為此代碼會干擾XtextBuilder
的ResourceSet
,如果我們使用ParallelResourceLoader
那么它甚至可能導致競爭條件?
總結一下:我想知道上面的兩個變體是否只是不好的,甚至是被禁止的。
除了速度慢之外,代碼還不錯(理論上)。 雖然它總是取決於 allObjects 中的對象會發生什么。 假設兩個導出的對象來自同一個資源,列表將包含來自兩個不同資源的兩個對象,並且諸如相等檢查或比較之類的操作變得不必要地困難。
在自己的資源集的上下文中執行相同的操作通常沒問題。 在觸發驗證之前,構建器將並行加載。 盡管如此 - 根據您的項目結構 - 加載所有對象可能會超過 JVM 的 memory 限制。 通常,如果 Xmx 越來越接近,XtextBuilder 會嘗試釋放 memory。 如果驗證加載所有資源,則此機制無法啟動。
長話短說:基於 IEObjectDescriptions 進行驗證當然是推薦的方式。 每個對象都有自己的資源集的變體非常糟糕。 第二個變種只是不好。 兩者都被允許但不鼓勵。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.