XtextResource couldn't resolve references to an external Ecore model [message #820714] |
Wed, 14 March 2012 13:34 |
Huy Tran Messages: 7 Registered: December 2011 |
Junior Member |
|
|
Hi all,
I followed Christian's guidance from h**p://christiandietrich.wordpress.com/2011/07/17/xtext-2-0-and-uml (many thanks, Christian) to develop a DSL that consists of references to an Ecore model.
The Domain Ecore model (for the readability, I'm using Emfatic syntax).
@namespace(uri="hxxp://domain", prefix="domain")
package domain;
class Model {
attr String name;
val A refA;
}
class A {
attr String name;
}
The Domain Xtext DSL:
Model: 'module' name=FQN imports+=Import* crossReference+=CrossReference*;
CrossReference: name=ID 'references to' referenced+=[domain::A|FQN];
FQN returns ecore::EString: ID ("." ID)* ;
FqnWildcard: FQN '.*'? ;
Import: 'import' importedNamespace = FqnWildcard ;
Then I created simple instances of those. The instance of the Domain Ecore model (My.domaind) is
<domain:Model ... name="My">
<refA name="anInstanceOfA"/>
</domain:Model>
and the instance of the DSL (My.domaindsl):
module mydomain
referenceToAnInstanceOfA references to My.anInstanceOfA
The Xtext editor of the Domain DSL can auto-complete the cross-reference to "My.anInstanceOfA" (with the help of an additional "IResourceServiceProvider" as mentioned in Christian's article), so I'm supposed there are no issues with the DSL editors. Unfortunately, I've got a problem when trying to load the aforementioned Xtext DSL in a simple standalone Java program:
String dslPath = "My.domaindsl";
String modelPath = "My.domain";
DomainDslStandaloneSetup setup = new DomainDslStandaloneSetup();
Injector injector = setup.createInjectorAndDoEMFRegistration();
XtextResourceSet set = injector.getInstance(XtextResourceSet.class);
set.addLoadOption(XtextResource.OPTION_RESOLVE_ALL, Boolean.TRUE);
set.getPackageRegistry().put(DomainPackage.eNS_URI, DomainPackage.eINSTANCE);
set.getResourceFactoryRegistry().getExtensionToFactoryMap().put("domain", new XMIResourceFactoryImpl());
Resource dslResource = set.getResource(URI.createFileURI(new File(dslPath).getAbsolutePath()), true);
Resource modelResource = set.getResource(URI.createFileURI(new File(modelPath).getAbsolutePath()), true);
if (dslResource != null)
{
dslResource.load(Collections.EMPTY_MAP);
if (dslResource.getErrors() != null)
{
for (Diagnostic d : dslResource.getErrors())
System.err.println(d.getMessage());
}
}
The aforementioned code showed the error "Couldn't resolve reference to A 'My.anInstanceOfA'". When I printed out dslResource.getContents().get(0), the result is:
<?xml version="1.0" encoding="UTF-8"?>
<domainDsl:Model xmi:version="2.0" ... name="mydomain">
<crossReference name="referenceToAnInstanceOfA">
<referenced href="file:/.../domain-test/My.domaindsl#xtextLink_::0.2.0::1::/4"/>
</crossReference>
</domainDsl:Model>
My question is: What should be added to the Java code in order to properly resolve the cross-references?
Thank you very much in advance for your time and support.
Huy
[Updated on: Wed, 14 March 2012 13:35] Report message to a moderator
|
|
|
|
|
|
|
|
|
|
Re: XtextResource couldn't resolve references to an external Ecore model [message #821656 is a reply to message #821638] |
Thu, 15 March 2012 16:54 |
|
Just be complete: here a sample snippet
public class Test {
public static void main(String[] args) throws IOException {
// register the testpackage to ecore
EPackage.Registry.INSTANCE.put(TestPackage.eNS_URI, TestPackage.eINSTANCE);
Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().put("test", new XMIResourceFactoryImpl());
// register the resourceserviceprovider
new TestSupport().registerServices(true);
// register the dsl
Injector injector = new MyDslStandaloneSetup().createInjectorAndDoEMFRegistration();
// load all model file to the resourceset
ResourceSet rs = injector.getInstance(ResourceSet.class);
Resource r1 = rs.getResource(URI.createURI("src/test.test"), true);
Resource r2 = rs.getResource(URI.createURI("src/test.mydsl"), true);
// work with the resources (the elements come from test.test)
r2.load(null);
for (ElementRef ref : ((Model)r2.getContents().get(0)).getRef()) {
System.out.println(ref.getElement().getName());
}
}
}
Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
|
|
|
|
Powered by
FUDForum. Page generated in 0.02218 seconds