Tag Archives: Eclipse

CFEngine workbench based on Eclipse and Xtext

Here’s a screencast showing a CFEngine-workbench that I built earlier this year.

CFEngine is a tool for system administrators that “has a powerful language and tools to define the desired state of your infrastructure”. The workbench is driven by the idea (some may think it’s crazy) of transfering the usability that software developers enjoy in IDEs into the usage scenarios for SAs .

Advertisements

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