Thursday, November 27, 2008

How to make an xtext language reference another by nsURI

In principle, Xtext allows two languages to refer to each other by means of the importMetamodel feature. If you specify the imported meta-model by means of a file URI, everything works out of the box. Unfortunately, file URIs are not suitable in many scenarios, so something less physical would be appropriate.

Due to a certain mismatch between the way openArchitectureWare (and thereby all the language's Xtend and Check files) and EMF access files and handle EPackage registration. The following describes the way to go in the version of Xtext that is shipped with oAW 4.3.1. Note that in TMF/Xtext we will provide easier support by means of classpath relative URIs.

Example

We consider the following two DSLs asl and bsl, where asl references bsl:

asl:
importMetamodel "http://www.example.org/my/bsl" as mybsl;
A:
(imports+=Import)*
(bs+=BRef)*;
Import:
"import" file=URI;
BRef:
"a" name=ID "b" b=[mybsl::B];

bsl:
B:
"b" name=ID;
To allow such cross-language reference, you have bsl has to be installed in the workbench you use for editing asl.

Install an xtext language

This usually boils down to deploying the language plug-in into the Eclipse workbench, e.g. by exporting it as deployable plug-ins and fragments into the dropins folder of the Eclipse installation.

There is one issue with the way xtext registers its meta-model. The EPackage is added to the EPackage.Registry programatically in the generated MetaModelRegistration class, such that we can call it inside or outside a running Eclipse. If running inside Eclipse, the MetaModelRegistration is called by the Activator of the language plug-in. This can be too late, as other plug-ins might not use the language but the meta-model, and rely on it to be accessible from the EPackage.Registry.

We cannot use EMFs dynamic_package extension point, as it requires the ecore file to be in a plug-in neutral folder. This is not the case in Xtext, as it stores the generated file in a source folder, which is no longer present once the plug-in is deployed.

There are two ways to solve this problem
1) Run the EMF generator to generate code from the ecore model. This will also register the generated EPackage Java class to the generated_package extension point of EMF.
2) Register a proxy class to the generated_package extension point, that implements EPackage (empty methods) and returns MetaModelRegistration.getEPackage() as its eINSTANCE. To ensure that the model is really loaded, you should delete the registered proxy in the static initializer and set the right resource loader before registering the package.

org.example.bsl.EPackageProxy:
package org.example.bsl;
...
public class EPackageProxy implements EPackage {
static {
ResourceLoader cl = ResourceLoaderFactory.createResourceLoader();
try {
ResourceLoaderFactory
.setCurrentThreadResourceLoader(new ResourceLoaderImpl(
EPackageProxy.class.getClassLoader()));
EPackage.Registry.INSTANCE.remove("http://www.example.org/my/bsl");
MetaModelRegistration.register();
} finally {
ResourceLoaderFactory.setCurrentThreadResourceLoader(cl);
}
}

public static final EPackage eINSTANCE = MetaModelRegistration
.getEPackage();

public EClassifier getEClassifier(String name) {
throw new UnsupportedOperationException("Method not implemented");
}

// remaining methods of EPackage
...
plugin.xml:
  <extension point="org.eclipse.emf.ecore.generated_package">
<package class="org.example.bsl.EPackageProxy" uri="http://www.example.org/my/bsl">
</package>
</extension>

Referencing an installed xtext language by nsURI

The xtext generator starts a new plain Java VM, and therefore does not have access to EPackages registered via extension points. That's why you have to explicitly register the referenced metamodel of bsl in the generator workflow of asl. Into the bargain, we have to register bsl's resource factory. Write a class

RegisterBslHelper:
package org.example.asl;
...
public class RegisterBslHelper {

public RegisterBslHelper() {
EPackage package1 = org.example.bsl.MetaModelRegistration.getEPackage();
package1.eResource().setURI(URI.createURI(package1.getNsURI()));
org.example.bsl.ResourceFactoryRegistration.register();
}
}
and call it in the generator workflow generator.oaw:
<workflow>
<property file="'generate.properties'/">
<bean class="org.example.asl.RegisterBslHelper">
<component file="'org/openarchitectureware/xtext/Generator.oaw'" inheritall="'true'/">
</component>
</workflow>
Also make sure, that the my.asl plug-in has a dependency on my.bsl and reexports that.

Monday, October 20, 2008

Started GMFTools project

I've worked with GMF for several years now, and I've built quite a bunch of graphical editors using it.

On my way, I've come along several issues, problems and annoyances of the GMF framework. Some of these may be a matter of personal taste, others are just reoccurring topics and tasks, which unfortunately have never been really focused within the GMF project. As these are sometimes hard to separate, I've decided to collect my ideas, extract reusable solutions and share them by making them open-source. This way, I hope to share knowledge with other GMF users, get feedback (maybe even by the committers), provide examples for beginners, and of course make my own life easier.

Have a look at it at http://code.google.com/p/gmftools/, and, if you like it, feel free to use it. But please don't expect me to provide extensive support. Main topics covered are
  • Sharing an editing domain among several editors
  • Make GMF's development process easier, e.g. by bypassing unreliable reconcilers and provide a very simple UI to the code generator.
  • Additional layouts, e.g. make labels fit into ellipses.
  • How to implement non- or semi-canonical diagrams.
Of course your comments are very welcome.

Maybe there are even more people around willing to share GMF solutions...

Thursday, July 3, 2008

Code Generation 2008 review

The Code Generation 2008 in Cambridge (UK) has been real fun. Karsten, Sven, Peter and me, we have met a lot of interesting people from the model-driven / DSL world, and have heard lots of interesting views and news on code generation.

The best thing in a conference on code generation is that the participants are already convinced of the benefits of modeling, so you don't have to explain every time from the very beginning why you think modeling is a good thing.

Last but not least, our workshop on openArchitectureWare was very successful and we has been rated top by the participants. It feels good to be assured that we are working on the right things.

Thursday, June 26, 2008

CodeGeneration 2008

I am currently attending the CodeGeneration 2008 conference at Cambridge (UK).

It is very inspiring to meet so many people involved in model-driven software development. Many of them come from the Microsoft DSL tools world which apparently has not evolved a lot in the recent past. People show a lot of interest in oAW and Eclipse Modeling techniques.

Yesterday we had a very vivid gold fish bowl discussion on the evolution of DSLs. Many of the emerging problems seem to be resolvable by better tooling. That just convinced me that we are working on the right topics in the current development of Xtext and oAW5.

Well, of course there are still a bunch of people around promoting MDA with all the UML and OMG stuff. It appears to me that simple things have a tendency to become rather complicated with that approach.

Looking forward to our hands on workshop on Eclipse Modeling tools tomorrow.

Tuesday, June 3, 2008

New Article on Textual DSLs with EMP

Peter, Sven and me, we have composed an Eclipse article on how to create your own textual DSL using tools from the Eclipse Modeling Project (EMP). It covers the definition of a grammar using Xtext, generating, running and customizing the DSL editor, adding constraints with Check and generating code with Xpand. You can find it here.

We are convinced that the described approach one of the most pragmatic ways of designing DSLs and implement code generators. If you have just a little bit of experience with the described technologies, creating your own external DSL becomes nearly as natural as writing Java code.

Tuesday, March 18, 2008

Tuning ELists

Just solved a serious performance problem. I programmtically constructed a rather big EMF model. It took ages so I started a profiler: Most of the time was spend in the BasicEList.contains(EObject) method. 

This is due to the fact that the corresponding EReferences have the unique flag set to true. EMF makes sure each element appears only once in the list of that reference. This is good, but performs poor for big growing lists.

As I construct the model from scratch I can make sure there will be no duplicates. So instead of
parent.getFeature().add(child);
I cast to BasicEList and call
((BasicEList<EObject>) parent.getFeature()).addUnique(child);

In my case, that reduced the execution time to a fifth !

Friday, March 7, 2008

Testing Trees

Working on parsers a lot recently, I have to write quite a bunch of tedious unit tests. Each of these tests analyses an EMF AST model which is the output of the parser. It checks if all nodes are at the right location and if all properties are set correctly. The tests look awful and debugging is a nightmare.

Using Xtext, it is quite easy to create a DSL for tree comparison. I can now describe expected tree results as

Extension {
name=Identifier(value='foo')
params=[
DeclaredParameter {
name=Identifier(value='this')
type=Identifier(value='Object')
},
DeclaredParameter {
name=Identifier(value='that')
type=Identifier(value='Object')
}]
}

where Extension, Identifier and DeclaredParameter are EClasses, name,params and type are EReferences and value is a attribute.

Writing such a DSL and an interpreter doesn't take you a day and will save you a lot of time and mental sanity in the future.

Friday, February 22, 2008

Converging Model Editors

Yesterday, Sven implemented an EMF Resource that serializes its content in Xtext format. We combined it with a graphical editor and the new EValidator adapter for oAW check. Generating everything, we finally got three synchronized editors all showing different representations of the same resource: Graphical, in Xtext and in an Ecore tree. Even complex changes in one editor were automatically transferred to all other editors on save and two of the editors even used the same checks for validation. 

That really rocked.

And it shows how great EMF and oAW really are. In the future, it should be easy to write DSLs with mixed representations, e.g. a graphical part for the element connections and a textual part for the details.

I am really looking forward to work on a closer integration of  oAW and EMF. There's so much potential. 

Wednesday, February 20, 2008

Advanced GMF

Having collected about two years of experience with Eclipse's Graphical Modeling Framework, I am now trying to summarize what could be improved or added to the framework. These are my favorites
  1. Support for a singleton editing domain (keep all semantic and diagram resources in the same resource set)
  2. Support for non-canonical diagrams (multiple diagrams for the same semantic model)
  3. Enable the OpenDiagramEditPolicy (linked diagrams)
Most of these issues can be implemented without touching GMF runtime code, i.e. by means of aspectual template changes and extensions. But as these are really fundamental and reoccurring topics, I'd rather see them as base functionality inside the original framework. Maybe I can push the GMF project in that direction?

Tuesday, February 19, 2008

Here it is...

Finally, web 2.0 has reached me. So here is my new blog.