Custom FragmentProvider : issue with Acceleo [message #1786233] |
Fri, 27 April 2018 08:43  |
Eclipse User |
|
|
|
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
|
|
|
|
|
|
|
|
|
Re: Custom FragmentProvider : issue with Acceleo [message #1786261 is a reply to message #1786252] |
Sat, 28 April 2018 03:11  |
Eclipse User |
|
|
|
Hi
When you run an Acceleo transformation you are running a standalone Java application with some help from Eclipse in that the classpath is auto-generated from the MANIFEST.MF; it uses only what is registered in the MANIFEST.MF.
When you edit an Acceleo transformation you are running within Eclipse and everything registered in your Eclipse workspace can be accessible.
Adding org/eclipse/xtext/xbase/lib/Exceptions in the Main method forced you to fix the defective MANIFEST.MF. However since you already had an XXXStandaloneSetup() call one might hope that the transitive dependency on org/eclipse/xtext/xbase/lib would be there automatically. Without a repro I cannot tell whether there is an Xtext bug or not. It looks as if the XXX MANIFEST.MF should export org/eclipse/xtext/xbase/lib. Perhaps your XXX MANIFEST.MFgen has the relevant declaration awaiting your update of XXX 's MANIFEST.MF.
Regards
Ed Willink
|
|
|
Powered by
FUDForum. Page generated in 0.06604 seconds