Visualize Xtext models with PlantUML


In this post I show how (ab)use PlantUML to visualize Xtext models. Warning: This is about diagrams, not about UML.

PlantUML Intro

PlantUML is an “Open Source tool .. to draw UML using a simple and intuitive language”.
Let me just draw an example class diagram to demonstrate how it feels:
This PlantUML specification

@startuml
abstract class Superclass << general >>;
abstract AbstractCreator{
  {abstract} create() : Superclass
}
Superclass <|-- Subclass
note left of Superclass : Instantiation not possible 
ConcreteCreator-up-|> AbstractCreator 
ConcreteCreator : create() : Superclass
ConcreteCreator .> Subclass
@enduml

results in this diagram:
plantumlex1

PlantUML also provides an Eclipse plugin which dynamically visualizes the “current active diagram, i.e. the diagram where the text cursor is located”. Better than that, this plugin provides an extension which lets you contribute a diagramTextProvider for a given editor. This means you can specify custom visualizations (limited by the PlantUML’s “UML”-capabilities) for any editor input. And the best of it: It works dynamically, i.e. while typing.

Prereq: Adjust PlantUML plugin

The above mentioned diagramTextProvider – extension requires the specification of a providerClass, i.e. a class which creates the plantuml diagram spec for a given editor input. This class has to implement net.sourceforge.plantuml.eclipse.utils.DiagramTextProvider. For some reason, the plugin does not export this package, so you may want to add something like

Export-Package: net.sourceforge.plantuml.eclipse.utils

to the plugin’s manifest.

Update: The PlantUML guys adjusted the manifest already, so you can skip this step with the latest PlantUML-Version (see comment below)

Create Xtext Project

Create a new Xtext Project (accept all defaults).  Adjust the grammar to make it look like this

// dont adjust grammar header
Model: greetings+=Greeting*;
Greeting: from=ID 'says' message=STRING 'to' to=ID;

and run the GenerateMyDsl.mwe2-worklow.

Create diagramTextProvider

Navigate to the ui project of your language. Add a dependency to the PlantUML-plugin to the MANIFEST.MF:

Require-Bundle: ...,net.sourceforge.plantuml.eclipse;

In the plugin.xml, add the following extension point:

   <extension point="net.sourceforge.plantuml.eclipse.diagramTextProvider">
      <diagramTextProvider 
      fileExtensions="mydsl" 
           providerClass="org.xtext.example.mydsl.ui.plantuml.MyDiagramTextProvider">
      </diagramTextProvider>
   </extension>   

Implement MyDiagramTextProvider as follows:

class MyDiagramTextProvider extends AbstractDiagramTextProvider {
	
	def DomainmodelDiagramTextProvider() {
		fileExtensions = "mydsl";
		editorType = typeof(XtextEditor)
	}
	
	override String getDiagramText(IEditorPart editorPart, IEditorInput editorInput) {
		// Retrieve the "semantic" EMF from XtextEditor
		val document = (editorPart as XtextEditor).getDocumentProvider().getDocument(editorInput) as XtextDocument;
		val Model model = document.readOnly[
			return contents.head as Model
		]
		
		// Collect names specified in textual model into Set
		val allNames = new HashSet 
		model.greetings.forEach[if(from!=null) allNames.add(from); if(to!=null) allNames.add(to)]
		
		// draw some actors and labelled arrows
		'''
			actor «FOR n:allNames»:«n»: as «n»
			«ENDFOR»
			«FOR it:model.greetings.filter[from!=null && to!=null && message!=null]»
				«from»->«to»:«message»
			«ENDFOR»
		'''
	}
}

Some notes on this implementation:

Try it

Run the Xtext/PlantUML plugins. It looks like (note: the editor is dirty … it really works dynamically):
xtextGraphviz

Advertisements

8 responses

  1. We have modified the Eclipse Plugin (starting with V7988) : you do not have to patch the plugin manifest anymore!

    1. Wow, that was fast. Thank you, guys. In turn, I added an update to my post.

  2. Hello . I’m very interested in this work. Can you tell me where I’m supposed to store the DiagramTextProvider ? Thank very much in adance

    1. Michel,

      you need to create an Eclipse plugin project and adjust the manifest as described in the text. There you specify the location of MyDiagramTextProvider (in the example the full qualified path to that class is org.xtext.example.mydsl.ui.plantuml.MyDiagramTextProvider)
      You may want to implement you DiagramTextProvider as a Java class or – as I did – as an Xtend class (which the get’s compiled to Java by the Xtend framework).

      Does that help?

      BR,
      Boris

  3. Hi, i followed your steps and i am stuck at implementing MyDiagramTextProvider. I copied the same code into my Xtend class but it shows a couple error which is shown below:

    1. Error at line “class MyDiagramTextProvider extends AbstractDiagramTextProvider {”

    The class MyDiagramTextProvider must be defined abstract because it does not implement its inherited abstract methods.
    – getDiagramText (IEditorPart editorPart, IEditorInput editorInput)
    -supportsSelection(ISelection)

    2. Error at line “override String getDiagramText(IEditorPart editorPart, IEditorInput editorInput) {”

    Multiple markers at this line
    – The Method getDiagramText(IEditorPart editorPart, IEditorInput editorInput) of type MyDiagramTextProvider must override a superclass method.
    – IeditorInput cannot be resolved to a type
    – IeditorPart cannot be resolved to a type

    Please help and thanks in advance. Your blogpost is really helpful in my project of implementing PlantUml into my Xtext DSL. 🙂

    1. Thank you for you comment.
      I actually missed the ‘organize imports’ step in my description,
      so hitting CTRL+SHIFT+O in the Xtend editor should remove the compile errors
      (I just re-tried it with Xtext/Xtend 2.7.3 and PlantUml Plug-in 1.1.8. For some strange reason Xtend doesn’t offer a context menu item for the imports, but the shortcut works).

      To be fail safe, here are my imports:

      import java.util.HashSet
      import net.sourceforge.plantuml.eclipse.utils.AbstractDiagramTextProvider
      import org.eclipse.ui.IEditorInput
      import org.eclipse.ui.IEditorPart
      import org.eclipse.xtext.ui.editor.XtextEditor
      import org.eclipse.xtext.ui.editor.model.XtextDocument
      import org.xtext.example.mydsl.myDsl.Model

      BR,
      Boris

      1. Thanks for the reply. 😀

        I found out that the imports for your AbstractDiagramTextProvider is different with mine.

        Previously, i import by using: “import net.sourceforge.plantuml.text.AbstractDiagramTextProvider”

        If i use “import net.sourceforge.plantuml.eclipse.utils.AbstractDiagramTextProvider”,
        it will shows error “net.sourceforge.plantuml.eclipse.utils.AbstractDiagramTextProvider cannot resolved to a type”

        Is it because of the plugin dependencies of the plantuml?

        Another thing is when i add the extension point, it will show a warning sign “Illegal attribute “FileExtensions”. Is this normal?

        (FYI, i am using Xtext/Xtend 2.9.2 and PlantUml Plug-in 1.1.8 with Eclipse version 4.5.1)

      2. It is okay. I already solved that problem. And everything is up and working perfectly!! Thanks again for the wonderful blogpost! 😀

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: