Custom FragmentProvider : issue with Acceleo [message #1786233] |
Fri, 27 April 2018 12:43 |
Emilien Lavigne Messages: 5 Registered: October 2017 |
Junior Member |
|
|
Hello,
I have an xtext DSL to describe some component's templates. It is based on a custom metamodel "template.ecore". Both the metamodel and the DSL projects are exported in plugins.
In an other workspace, I have a "My.template" file , where i declare some templates.
In an XMI file ("My.component") based on an other metamodel ("component.ecore", which contains references to "template.ecore"), I can reference the templates contained in My.template, and it works fine
I want to run an Acceleo script on My.component, so in the Acceleo project:
- In the registerPackages method, after registering the "template" and "component" package, I manually load the "My.template" file :
public void registerPackages(ResourceSet resourceSet) {
super.registerPackages(resourceSet);
if (!isInWorkspace(AMSA.ComponentPackage.class)) {
resourceSet.getPackageRegistry().put(AMSA.ComponentPackage.eINSTANCE.getNsURI(), AMSA.ComponentPackage.eINSTANCE);
}
if (!isInWorkspace(AMSAt.TemplatePackage.class)) {
resourceSet.getPackageRegistry().put(AMSAt.TemplatePackage.eINSTANCE.getNsURI(), AMSAt.TemplatePackage.eINSTANCE);
}
try {
URI model2URI = URI.createFileURI("Path-to-My.template");
ModelUtils.load(model2URI, resourceSet);
} catch (IOException e) {
e.printStackTrace();
}
}
- In the registerResourceFactories method, I call the doSetup method of the DSL:
public void registerResourceFactories(ResourceSet resourceSet) {
super.registerResourceFactories(resourceSet);
amsaTemplate.xtext.TemplateDescriptionStandaloneSetup.doSetup();
}
Until then, everything works fine, I can use components and templates in my Acceleo scripts.
Problem appears when I try to implement my own Fragment Provider in the DSL, in order to reference the templates with their qualified names instead of their positions (following this article : Cross-References from XMI to Xtext)
I add a AmsaTemplateFragmentProvider.xtend file in the DSL sources :
package amsaTemplate.xtext.ressource
import com.google.inject.Inject
import java.util.Map
import org.eclipse.emf.ecore.EObject
import org.eclipse.emf.ecore.resource.Resource
import org.eclipse.xtext.naming.IQualifiedNameConverter
import org.eclipse.xtext.naming.IQualifiedNameProvider
import org.eclipse.xtext.resource.IFragmentProvider
import org.eclipse.xtext.util.IResourceScopeCache
class AmsaTemplateFragmentProvider implements IFragmentProvider {
@Inject IQualifiedNameConverter qualifiedNameConverter
@Inject IQualifiedNameProvider qualifiedNameProvider
@Inject IResourceScopeCache cache
static val CACHE_KEY = 'name2element'
override getEObject(Resource resource, String fragment, Fallback fallback) {
try {
val qualifiedName = qualifiedNameConverter.toQualifiedName(fragment)
return getName2ElementMap(resource, fallback).get(qualifiedNameConverter.toString(qualifiedName))
} catch (Exception exc) {
return fallback.getEObject(fragment)
}
}
/**
* Returns a map qualifiedName -> EObject that is calculated on demand and cached.
*/
def private Map<String, EObject> getName2ElementMap(Resource resource, Fallback fallback) {
cache.get(CACHE_KEY, resource, [
val name2element = <String, EObject>newHashMap
resource.allContents.forEach [
name2element.put(getFragment(it, fallback), it)
]
return name2element
])
}
override getFragment(EObject obj, Fallback fallback) {
try {
return qualifiedNameConverter.toString(qualifiedNameProvider.getFullyQualifiedName(obj))
}
catch (Exception exc) {
return fallback.getFragment(obj)
}
}
}
And then I bind it in the TemplateDescriptionRuntimeModule.xtend file
/*
* generated by Xtext 2.13.0
*/
package amsaTemplate.xtext
import amsaTemplate.xtext.ressource.AmsaTemplateFragmentProvider
/**
* Use this class to register components to be used at runtime / without the Equinox extension registry.
*/
class TemplateDescriptionRuntimeModule extends AbstractTemplateDescriptionRuntimeModule {
override bindIFragmentProvider() {
AmsaTemplateFragmentProvider
}
}
The fragmentPovider works fine so qualified named are used to reference the templates in the XMI (and the links work in the XMI editor), but when i try to launch the acceleo application, I have the following exception :
Quote:Exception in thread "main" java.lang.NoClassDefFoundError: org/eclipse/xtext/xbase/lib/Exceptions
at amsaTemplate.xtext.ressource.AmsaTemplateFragmentProvider.getEObject(AmsaTemplateFragmentProvider.java:42)
at org.eclipse.xtext.resource.XtextResource.basicGetEObject(XtextResource.java:363)
at org.eclipse.xtext.resource.XtextResource.getEObject(XtextResource.java:349)
at org.eclipse.xtext.linking.lazy.LazyLinkingResource.getEObject(LazyLinkingResource.java:232)
at org.eclipse.emf.ecore.resource.impl.ResourceSetImpl.getEObject(ResourceSetImpl.java:223)
at org.eclipse.emf.ecore.util.EcoreUtil.resolve(EcoreUtil.java:201)
at org.eclipse.emf.ecore.util.EcoreUtil.resolve(EcoreUtil.java:261)
at org.eclipse.emf.ecore.impl.BasicEObjectImpl.eResolveProxy(BasicEObjectImpl.java:1477)
at AMSA.impl.LeafComponentImpl.getLeafTemplate(LeafComponentImpl.java:130)
at AMSA.impl.LeafComponentImpl.eGet(LeafComponentImpl.java:201)
...
Did I miss something to activate or register the FragmentProvder in a standalone use case ? I don't find anything about it...
Thanks for your help,
Best regards
Emilien
|
|
|
|
|
|
|
|
|
|
Powered by
FUDForum. Page generated in 0.03522 seconds