Xtext End User / Domain Experts Cheat Sheet

The basic idea of domain specific languages is to provide domain experts with an easy to use language for their modeling needs. However, a domain specific language is always tied to a tool for editing the model. With Xtext, this is obviously Eclipse. Eclipse provides some rich editing features, especially for navigating in models.

Most existing cheat sheets refer to the Java IDE of Eclipse, which you cannot give to domain experts because it contains elements not relevant to them (debugging) or have a slightly different meaning.

So here is an attempt of a small cheat sheet for Xtext end users (domain experts):

 

Editing

ALT-Left and ALT-Right Back / forward Go back and forward in history of where you were in editors
CTRL-PgUp and CTRL-PgDown Cycle tabs  Cycle through tabs of open editors
CTRL-Up and CTRL-Down Scroll  Scroll line up and down
CTRL-M Maximize  Maximize / Restore current editor window
CTRL-W Close Close Current Editor
CTRL-D Delete Line Delete Current Line
CTRL-/ Toggle Comment Toggle Comment for line / selection
CTRL+SHIFT-F Format Auto format
ALT-UP / ALT-Down Move Move current line / selection one line up / down
CTRL-Q Last Edit Go to last edit location
CTRL-L Goto Go to line

Model Editing

Ctrl-Shift-G Find References Find all elements that refer to the current element
F3 or CTRL-MouseClick Follow Link Follow reference under cursor
Ctrl-O Pop up Outline Pops up an outline for easy navigation / filtering
CTRL-1 Quick Fix Quick Fix of Errors (where provided by DSL designer)
CTRL-SPACE Content Assist Get suggestions of possible values
ALT-SHIFT-R Rename Rename current element (will rename other occurrences as well.
CTRL-SHIFT-F3 Open Model element Locate a model element in your workspace (only exported elements are listed)
ALT-SHIFT-Up / Down Expand selection Expand selection to containing element

Xtext Global and Local Scoping – overview

Just recently I posted a small article with an overview on the Xtext scoping architecture. One of the things that took me a while to understand is the difference of global and local scoping. Several people I discussed this had their own ways to explain these. Here is my current way of explaining some types of scoping in Xtext.

Assume that we have a language that supports defining classes, much like in UML: A class can have a name, attributes and it can inherit from another class. And we want to support models that consist of several Xtext files.

Suppose we have the following two files:

A simple definition of two classes, with B inheriting from A. So, obviously we are having a reference from B to A (inheritance). In the grammar that could look like

Class: 'class' name=ID ('inherits' general=[Class|FQN])?

and Xtext supports us by providing all the automatic linking when it sees “inherits”. But how does it know what to link? If all our models were restricted to be contained in one single file / resource, it would be easy: Just get the current resource and traverse all the contained model elements to find one that matches “A” and set up the link.

Global Scoping

But now, with models split over several files, what do we have to do:

  1. First, find all the model files candidates that could be relevant for our search
  2. Define a strategy to decide if a model file is really considered for traversal
  3. Traverse the model file and find all the candidates that could match our reference to “A”

We wouldn’t want to to this manually. Luckily, Xtext does it for you – actually, it does it a little different, since the approach above would be inefficient – traversing all the model files for each reference would be slow.

So, every time a file changes, Xtext collects the objects and the names that they are known by and puts this information into the index. So instead of traversing all models in all candidate files, Xtext just has to have a look if there is a matching entry in the index. Assuming that the classes above would be contained in a package called “P”. The index could contain:

name Object
P Package “P”
P.A Class A
P.A.a Attribute b
P.B Class B
P.B.b Attribute b

But would we want to see all the possible candidate elements in our reference (types are automatically checked). In most cases no. So Xtext provides several mechanisms to “restrict” the search. Please the the Xtext documentation for details:

  • URI imports: You can have import statements, that actually reference the full URIs of the other files to be considered.
  • Namespace import: You can define a namespace import. If you than provide something like “import P.*” in your grammar, the search will be restricted to those elements whose fully qualified name starts with “P.”
  • Java class path based

There is additional ways to tweak and modify Xtext behavior and there is more data stored in the index (references) etc. But I hope this gives you the general idea. However, the story is not finished.

 Local Scoping

Now suppose we want to have a second grammar, where we define instances of the classes and values for their attributes, just like this:

Since the classes are in a separate file, it is obvious that the link from the instance to its defining class is done in the way described above. But also the attributes values are linked to the attribute definition in the class model, so how is this done?

Obviously, we could also just use the index. But we have to restrict the possible references as well, since in instance “a”, a reference to attribute “b” would not be valid. So what we could do is to get the list of possible references from the index, traverse the class hierarchy and filter out all attributes that are not valid.

But, for finding all valid attributes, we are traversing all attributes in the class hierarchy anyway. So why not forget about the index, and just build up the list of possible references while we traverse the model? This is done by local scoping, which you can easily customize to modify the list of reference candidates. See the Xtext documentation on how to do that.

So, then why do we need the attributes in the index? Simple, we don’t. The list of possible attribute values is calculated by us, so we don’t need them there. For our own Xtext grammars, we can override the strategy of what is put into the index and what not. So we decide to not put attributes in the index. Xtext per default cannot know what you want to put in the index, so it puts in everything from your model that has a “name” attribute. It might be worthwhile customizing this behavior, since it could save us a lot of CPU and memory.

 Summary

For me, it is useful to divide scoping in two different aspects:

  1. I can find out the possible candidates of a link by traversing references in my model. The traversal can easily span multiple resources/files, as long as the traversal can be done by standard EMF means.
  2. To find the possible candidates, I would have to think about a strategy on which model files to load etc. I cannot access these candidates by traversing the references that I already have, because I might not even reach those models –> global scoping.

 

 

My mental Xtext high-level model

While Xtext is a powerful tool, it is sometimes easy to loose the big picture of the linking, scoping, global scope etc. For my own mental relief, I have made a little diagram, which might be useful for others (no guarantee for correctness or level of detail). It applies only to a specific configuration (using Xbase and Imported Namespace Aware Scoping).

 

So basically what happens is:

  1. Parsing: The framework parses the model files (Xtext-files). Links between elements are not resolved yet.
  2. Index Building: The model is traversed, and basically everything reachable that has a name attribute is packed into an EObjectDescription and that is put into an index. What is put there can be customized. Caveat: EObjectDescription allows you to have some user data stored with your description in the index. Often the first thought is, to store e.g. some type information or, e.g. in case of class models, some inheritance information. However, references are not yet set up / linked. So you cannot put anything in the user data that would traverse link references!
  3. Lazy Linking / Scoping: This is where the actual linking is done. In our case (Xbase-based language), this scoping is based on XbaseScopeProvider. This actually delegates to some Guice-configured class, which in our case is an ImportedNamespaceAwareLocalScopeProvider. This looks for model elements with the attribute “importedNamespace” in your model and pulls the objects from the index, that match any of the importedNamespace values (you can specify wildcards in the imports).
    In addition, in these classes you can add your own scopes, the local scopes, which are derived from the existing model information.
  4. Content assist: Uses the scoping data for suggesting alternatives.

The index is transient in memory and is loaded from / stored to disk on start / stop of Eclipse. During run-time there is no up-to-date representation on disk. The org.eclipse.xtext.ui.shared.Access class can be used as a handle to index data.

 

Learning foreign software terminology with Anki

Despite English being the lingua franca of software engineering, there are still good reasons to learn to talk in foreign languages if you are doing international business. Locals will often communicate in their mother tongue and not all languages use so many English technical terms like German. France’s académie française makes sure that there are technical terms in French and the sheer amount of Chinese speakers and their language structure calls for chinese words.

So, if you are going abroad and want to learn a language, memorizing the vocabulary is one of the most important parts. But instead of writing vocab lists on sheets of paper or on cards, there is a very nice software that supports you in learning: It is called “Anki” and it is available for PC, Android, iPhone and others.

It is a software supporting a spaced repetition system (SRS), which essentially means that you’ll see those entries that you are not good at more often than those which you know well. And you can sync all your cards between PC, Android, iPhone comfortably. A large number of word lists are available for several languages and you can easily define your own deck of cards, e.g. with software terminology or sentence patterns.

And you are not limited to using Anki for learning languages. You can use it for all kinds of studying: physics formulas, law, business, etc.

Anki has become one of my favourite tools.

 

 

ReqIF and Word Import

About a week ago we’ve uploaded the initial code contribution to  Requirements Modeling Framework (RMF). In addition, we’ve been using the tool and created some additional (not published) utilities.

Word documents are one popular way to document requirements. We too have some requirements in Word format to be imported into ReqIF format. It takes about one page of source code to implement a tool that takes a Word document and converts it to ReqIF (although we are currently not handling text formatting).

ReqIF uses xhtml to store formatted text. So quite some functionality of a Word to ReqIF conversion would go into this transformation.

We have been asked for a PDF to ReqIF conversion as well. However, my experience with commercial pdf to word conversion tools does not make me too optimistic about the feasibility, because the information in the .pdf is probably too low-level.

It turns out that our framework is a powerful tool to provide tools and functionality around ReqIF.

Icon from: <A href=”http://www.vistaico.com”>VistaICO.com</A>

Links for the ReqIF Talk at Eclipse Con Europe 2011

If you attended my talk at Eclipse Con Europe on the RMF project, here are a few links that might be useful:

Additional Topics

Next Chance to see:

 

 

Debugging Graphiti Applications

Graphiti is one of the hyped young Eclipse projects. In its current phase, several features are not extensively documented, though the developer support on the Eclipse forums are very nice. One of the features that are too hidden is the nice debugging facility, that a colleague pointed me to.

Basically, in the Eclipse preferences there is a page with several settings for the editor.

Amongst others, there are setting to:

  • Show invisible rectangles: They will be drawn with a transparent background and a yellow border, making it easy to find out where they are.
  • See an outline of the diagram objects in the outline view, and
  • Have a debug entry in the context menu, which allows you to dump data to the console.

All in all a very nice set of features that I should have discovered earlier.

New AUTOSAR Open Source Initiative from Asia – TOPPERS

Relatively unnoticed by the Western industry, a lot of interesting activities in (automotive) software engineering are currently being launched in Asia.

During the China Automotive Forum, the Toppers team from Japan announced their plans to build an open source AUTOSAR basic software based on the Toppers OS. The chinese announcement can be found as a PDF here, titled “The current state of developing an AUTOSAR-compliant open-source OS”.

Basically, they currently have a OSEK/VDX operating system called “TOPPERS/ATK1″ that is reported to be used in several of Suzuki’s cars. It is described as MODISTARC and MISRA-C complient, supporting a CAN/LIN middleware and a FlexRay add-on.

The project goal is to “make public the source code” in 2012 under the label “TOPPERS/ATK2″. In the “basic phase” during 2008 until 2010, the project dealt with an AUTOSAR OS (AUTOSAR SC1 to SC3) and multi-core.

Listed participating parties are, amongst others: Toshiba, Renesas, Toyota, Fuji Soft and Denso . There seem to be around 12 technical personnel from the companies involved and about 8 professors and researches from Nagoya university.

The current research phase is from April 2011 until Mar 2012. Depending on the results of this phase, the continuation of the project will be determined. It seems that except for the verification suite, which will be only released to members, other projects results will be released as open source.

Mentioned problematic aspects are the vast size of the standard, which requires a lot of implementation effort, the new multicore aspects and the efforts required to get a grasp of the standard.

 

 

 

Compiling Xtext Expressions and Google Collections’ Function

In our small DSL for graphiti editors, you can specify simple code with Xtext’s Expressions. E.g., in the specification for a connection, the color should be green if the domain object has the attribute “positive” set, and red otherwise.

So in the editor, this can be specified by means of an XBlockExpression. The Xtend2 builder also provides support for compiling the expressions in your DSL to Java, however, the standard implementation compiles them to a method body. The result of the expression is always passed back by a return statement.

Since modifiying the compiler was too complex and generating an extra class for the calculation would clutter the class structure too much, a simple solution is to wrap the generated code with a google collection Function.

 

The generated code looks  like:

 

On a site note, be aware that you have to work with injections to set up the compile framework in your generator. In the generator class I have a statement

    @Inject AddConnectionFeatureGenerator addConnectionFeatureGenerator

and the generator is invoked by

addConnectionFeatureGenerator.generate(fsa,conn)

. On the contrary, a

new AddConnectionFeatureGenerator().generate(fsa,conn)

would not work.

 

A DSL for Graphiti Editors

Funded by the BMBF

Funded by the BMBF

For the public funded research projects IMES we are building graphical editors for functional nets and other systems. Since Graphiti is drawing a lot of interest, it is a good occasion for using the new technology. However, it turns out, that you have to write a lot of code. The Graphiti team seems to address this with a “Pattern Framework”, but it is hard to find documentation on this.

So what do you do to avoid writing boilerplate code? Of course, MDD with textual DSLs and M2T (i.e. code generation).

A textual DSL for Graphiti Editors

 

So the first draft of a language to specify editors was quickly implemented. Here are some core features as seen above:

  1. The DSL references the Ecore of the domain model, giving full content assist. This is used to e.g. generate the CreateFeature in Graphiti
  2. The “label” references an attribute in the ecore. This attribute is displayed as a label in the diagram. Moreover, the DirectEditingFeature and the Update Feature for the attribute is generated.
  3. In this example, a logical function can be at the root of the model, but it could also be a child of another logical function. So we have two contexts here. When the shape is created on / dragged to the diagram, the domain object is added to the functionNetworkProject.logicalFunction collection. On the other hand, if its container is another logical function, then the collection used is LogicalFunction.subFunction.
    This generates code for the Create and Add Feature. In addition, it also creates a move feature, that rewires the containment if the shape is dragged from one container to another. The default behavior of Graphiti is two disallow moving an object out of its container.
    With LogicalPorts, there is only the LogicalFunction context, so they cannot be placed on the diagram background, only within logical functions.
  4. Ports are usually placed on the border of the parent shape. In Graphiti, this requires a “MoveFeature”, that checks if the new position is valid. The “OnBorder” keyword creates such a feature that allows moving the ports on the border shape only.
  5. In the meta-model, a connection (Logical Channel) between to ports is not a reference, but a model element with references to the endpoints. The ObjectMapping specifies which element to create and which references to set for the endpoints.
  6. The channel is owned by the function that owns the functions connected by the channel (so this is two levels up). To allow for complex operations, the AddToModelFunc generates a stub that delegates the adding of the domain object to the model to a method that can be implemented manually.
  7. And finally, the connection has to know which elements / shapes it can connect.

And here is a screenshot of the generated editor:

 

The DSL/Generator are in an early phase and not designed to cover all use cases. But they will definitely reduce our implementation efforts for editors.

There is also another initiative to create a DSL for Graphiti editors, called “Spray”. However, no code has been published yet under “Spray” and since we could not wait for initial contributions, we just had to start anyway…