spray user guide - · pdf filespray user guide. 2 ... (implemented with xtext to describe...

81
Spray User Guide

Upload: leduong

Post on 09-Mar-2018

218 views

Category:

Documents


3 download

TRANSCRIPT

Page 1: Spray User Guide - · PDF fileSpray User Guide. 2 ... (implemented with Xtext to describe Visual DSL Editors ... initial plugin.xml is generated to the project root and is updated

Spray User Guide

Page 2: Spray User Guide - · PDF fileSpray User Guide. 2 ... (implemented with Xtext to describe Visual DSL Editors ... initial plugin.xml is generated to the project root and is updated

2

Spray – A quick way of creating Graphiti

User Guide

Authors: Jos Warmer, Karsten Thoms, Marko Boger, Fabio Filippelli, Michael Bauer, Joerg Reichert

Contents

1. Spray - A quick way of creating Graphiti2. Introduction3. Installation

1. Install Spray2. Uninstalling Spray

4. Getting Started1. 15-Minutes Tutorial

1. Create a new EMF project2. Create a new project3. Define Shape Model4. Define Spray Model5. Test the editor6. Create your first element

2. Extending the 15 Minute Tutorial1. Adding Connections to the Diagram2. Implement a Custom Behavior

3. Adding Style to Your Diagram1. busmod.style2. busmod.shape3. busmod.spray

5. Spray DSL1. A Spray based example language

1. The domain model (defined in Xcore)2. The spray file3. The shape file4. The style file

2. Diagram1. Imports2. Diagram

3. MetaClass1. Referencing Ecore Classes2. Ecore models the development workspace3. Create Behavior4. Class Icon

4. Layout1. Colors

5. Shapes

Page 3: Spray User Guide - · PDF fileSpray User Guide. 2 ... (implemented with Xtext to describe Visual DSL Editors ... initial plugin.xml is generated to the project root and is updated

3

6. Concept of a Model Driven Graphical Editor7. Style DSL Guide

1. An example for a style2. Style Key Facts3. Default Values4. Style Elements

1. Description2. Transparency3. Background4. Line5. Font6. Gradients

8. Shape DSL Guide1. An example for a shape2. Shape Key Facts3. Shape Visualisation4. Shape Elements

1. Anchor5. Shape Property Assignment6. Compartments7. Shape Default Values

1. Text2. Line3. Polyline4. 2D Shape5. Ellipse6. Rectangle7. RoundedRectangle8. Polygon

8. Practise Examples1. Curve - Example2. UML - Example3. BPMN - Example

9. Connections1. Placing2. ConnectionType

9. Additional Features1. Direct Editing2. Properties Sheet

10.Spray Extensions Guide1. Basic extensions: Generation Gap Pattern

1. Generation Gap Pattern for Java code2. Generation Gap Pattern for plugin.xml

2. Extending Spray's code generator1. Create plugin project2. Derive templates3. Guice Runtime Module4. Extension point5. Done!

11.Cookbook1. Features

1. Zest Layout12.Migration Notes

1. Renamed properties file2. (Re-)generation of plugin.xml

Page 4: Spray User Guide - · PDF fileSpray User Guide. 2 ... (implemented with Xtext to describe Visual DSL Editors ... initial plugin.xml is generated to the project root and is updated

4

13.Reference1. The Spray grammars

1. The Style grammar2. The Shape grammar3. The Spray grammar

Page 5: Spray User Guide - · PDF fileSpray User Guide. 2 ... (implemented with Xtext to describe Visual DSL Editors ... initial plugin.xml is generated to the project root and is updated

5

Introduction

The Graphiti framework is a new approach to create highly sophisticated visual editors on top of the GEFframework. Graphiti can easily be integrated with EMF as the domain modeling framework. The creation of visualeditors is done in Java, programming against the Graphiti framework API. It is fairly simple, but yet repetitive, whichmakes it a candidate to be supported by the means of model-driven development.

Spray aims to provide Domain Specific Languages (DSL) (implemented with Xtext to describe Visual DSL Editorsagainst the Graphiti runtime, and provide code generation (implemented with Xtend to create the boilerplate codefor realizing the implementation against the Graphiti framework. Potentially the Spray DSL can be used to generatecode for other graphical editor frameworks as well, although it is not the primary focus of the project now.

The generated code is structured in such a way that one can always extend/overwrite the generated code withhandwritten Java to add advanced Graphiti features that are not supported directly by the Spray DSL. ThereforeSpray makes use of the Generation Gap Pattern.

With the help of the tools created with Spray, Graphiti based diagram editors can be created much faster andreliable than doing it purely by hand.

A short introduction to Spray can be found in the Downloads section . The code is in early state and subject tochange.

Page 6: Spray User Guide - · PDF fileSpray User Guide. 2 ... (implemented with Xtext to describe Visual DSL Editors ... initial plugin.xml is generated to the project root and is updated

6

Installation

Install Spray

A very short introduction on how to install spray.

• Install Eclipse Kepler IDE (= Eclipse 4.3.x). Eclipse Classic or Eclipse Modeling Tools are appropriate Eclipsepackages.

• Start a new workspace• Open Help / Install New Software• Add the Spray 3rd party dependencies Update Site and press enter

• For the latest release: https://spray.ci.cloudbees.com/job/spray-ci-targetplatform/lastSuccessfulBuild/artifact/releng/org.eclipselabs.spray.repository/target/repository/

• For the latest stable build: https://spray.ci.cloudbees.com/job/spray-ci-targetplatform/lastSuccessfulBuild/artifact/releng/org.eclipselabs.spray.repository/target/repository/

• Note: you do not need to install anything from that 3rd party update site, the URL just have to be available inthe list of known update sites

• Add the Spray Update Site and press enter• For the latest release: http://spray.eclipselabs.org.codespot.com/git.distribution/releases

• For the latest stable build: https://spray.ci.cloudbees.com/job/spray-assembly-build/lastSuccessfulBuild/artifact/releng/org.eclipselabs.spray.updatesite/target/repository/

• Check Spray / Spray SDK Feature

Page 7: Spray User Guide - · PDF fileSpray User Guide. 2 ... (implemented with Xtext to describe Visual DSL Editors ... initial plugin.xml is generated to the project root and is updated

7

• If the Eclipse distribution does not include PDE (e.g. Eclipse for Java IDE), check also 3rd Party / Eclipse Plug-in Development Environment

The PDE version hosted at Spray requires Eclipse 4.3 to be installed.

• If the Eclipse distribution does not include the EMF SDK, check also 3rd Party / EMF – EMF ModelingFramework SDK (the EMF SDK is required to be able to create an EMF Generator Model)

• Update: For Snapshot version instead of adding the two update sites mentioned above you can now add thisupdate site, that aggregates these update sites into one:• https://spray.ci.cloudbees.com/job/spray-assembly-build/lastSuccessfulBuild/artifact/releng/org.eclipselabs.spray.updatesite/ - here only check the first node (Spray) toinstall

• Start installing the features• Restart Eclipse when asked

Uninstalling Spray

Spray can be uninstalled in Eclipse by choosing Eclipse / About Eclipse SDK / Installation Details. Select the SpraySDK Feature und press uninstall.

Page 8: Spray User Guide - · PDF fileSpray User Guide. 2 ... (implemented with Xtext to describe Visual DSL Editors ... initial plugin.xml is generated to the project root and is updated

8

Page 9: Spray User Guide - · PDF fileSpray User Guide. 2 ... (implemented with Xtext to describe Visual DSL Editors ... initial plugin.xml is generated to the project root and is updated

9

Getting Started

15-Minutes Tutorial

Create a new EMF project

First we have to create or reuse a meta model of a business domain that can be referenced by the diagram modelto be created in the second step.

• File -> New -> Other...

• Project name: org.mod4j.dsl.businessdomain.mm• Download BusinessDomainDsl.ecore and BusinessDomainDsl.genmodel• put the downloaded files in the model folder of the just created EMF project• Download plugin.xml and put it directly in the EMF project• Double click on the BusinessDomainDsl.genmodel and open the context menu at the root element

Page 10: Spray User Guide - · PDF fileSpray User Guide. 2 ... (implemented with Xtext to describe Visual DSL Editors ... initial plugin.xml is generated to the project root and is updated

10

• Add the model path to the build path --> Select model Folder, On the context menu Build Path / Use as SourceFolder

• Add Xtext nature to the project --> Select the project, On the context menu Configure / Add Xtext nature• Use the quick fix to solve the problems in the MANIFEST.MF (sets the singleton directive)

Create a new project

• Create a new Spray project by using the Spray Project Wizard. Open File / New / Project / Spray / SprayProject.

Page 11: Spray User Guide - · PDF fileSpray User Guide. 2 ... (implemented with Xtext to describe Visual DSL Editors ... initial plugin.xml is generated to the project root and is updated

11

• Enter the project name org.eclipselabs.spray.examples.busmod.• On the first page you will have to select a EMF metamodel to work with. Click the Browse Workspace button to

select an EMF Ecore file from your workspace.

Page 12: Spray User Guide - · PDF fileSpray User Guide. 2 ... (implemented with Xtext to describe Visual DSL Editors ... initial plugin.xml is generated to the project root and is updated

12

• Spray requires that it can find the corresponding genmodel for the EPackage. If it can be found next to theEcore file it will be added automatically.

• It must be specified which class will be the root for each diagram. Press Select Type and chooseBusinessDomainDsl.BusinessDomainModel.

• It can be chosen which file extension the models will have. By default it will be derived from the EPackagename, businessdomaindsl.

Page 13: Spray User Guide - · PDF fileSpray User Guide. 2 ... (implemented with Xtext to describe Visual DSL Editors ... initial plugin.xml is generated to the project root and is updated

13

• Press Next (or Finish to skip the next page)• The next page lets you modify some settings for Spray’s code generator, like package names to use. Leave the

defaults and press Finish for now.

Page 14: Spray User Guide - · PDF fileSpray User Guide. 2 ... (implemented with Xtext to describe Visual DSL Editors ... initial plugin.xml is generated to the project root and is updated

14

Define Shape Model

After finishing the project wizard open the file busmod.shape and paste the code below into the editor:

shape SimpleClassShape { rectangle { position(x=0, y=0) size(width=100, height=25) text { position(x=5, y=0) size(width=95, height=25) id = businessClassText } }}

(Gist: busmod.shape

Page 15: Spray User Guide - · PDF fileSpray User Guide. 2 ... (implemented with Xtext to describe Visual DSL Editors ... initial plugin.xml is generated to the project root and is updated

15

This defines a rectangle shape with an embedded text. Save this file.

Define Spray Model

Now open the file busmod.spray and paste this model into the file:

import BusinessDomainDsl.*

diagram busmod for BusinessDomainDsl.BusinessDomainModel

class BusinessClass { shape SimpleClassShape { name into businessClassText } behavior { create into types palette "Shapes" }}

(Gist: busmod.spray

This defines that the class BusinessClass from our domain (ecore) model is represented by theSimpleClassShape shape.

After saving the model the editor sources will be automatically generated to the src-gen folder of the project. Aninitial plugin.xml is generated to the project root and is updated after saving the project.

At this point your workspace should look like this:

Page 16: Spray User Guide - · PDF fileSpray User Guide. 2 ... (implemented with Xtext to describe Visual DSL Editors ... initial plugin.xml is generated to the project root and is updated

16

Test the editor

• Start a Runtime Eclipse instance with Run As / Eclipse Application. A new Eclipse instance starts with theplugins deployed.

• Create a new project. The type of project does not matter, but for simplicity choose new Java Project and nameit „BusmodTest”.

• Right-click on the src folder, choose File / New / Other -> Examples / Graphiti / Graphiti Diagram

• Choose the Diagram Type "busmod"

Page 17: Spray User Guide - · PDF fileSpray User Guide. 2 ... (implemented with Xtext to describe Visual DSL Editors ... initial plugin.xml is generated to the project root and is updated

17

• Your new diagram editor opens!

Page 18: Spray User Guide - · PDF fileSpray User Guide. 2 ... (implemented with Xtext to describe Visual DSL Editors ... initial plugin.xml is generated to the project root and is updated

18

As alternative you can create your diagram also this way:

• Right-click on the src folder, choose File / New / Other -> busmod / New busmod Diagram

Page 19: Spray User Guide - · PDF fileSpray User Guide. 2 ... (implemented with Xtext to describe Visual DSL Editors ... initial plugin.xml is generated to the project root and is updated

19

• Give it a name• in difference to the wizard used above there are now created two files

• newDiagram.businessdomaindsl: this hold the domain model• newDiagram.diagram: this hold the pure diagram related stuff and just references elements from the

newDiagram.businessdomaindsl

Create your first element

• Click on BusinessClassNameOnly in the palette to select that entry• Click somewhere in the diagram editor to create the element• You can now edit the name of the newly added class directly within the diagram• _Window -> Show View -> Other... -> General/Properties to open the properties view• Click on the just created element and you can see its attribute values in the properties view• Type Person in the name field• You will see the name being changed in the diagram immediately while you type

Extending the 15 Minute Tutorial

This section describes several tutorials to add more functionality to the editor. In these tutorials we assume youstart with the models created in the 5 Minute Tutorial. The tutorials in this section can be done individually.

Adding Connections to the Diagram

This section shows how to add an association between two business classes in the diagram. The first step is todefine a shape for the association. Do this by opening the busmod.shape file and add the following at the end:

// Shape for associations

Page 20: Spray User Guide - · PDF fileSpray User Guide. 2 ... (implemented with Xtext to describe Visual DSL Editors ... initial plugin.xml is generated to the project root and is updated

20

connection AssociationConnection { connection-type freeform placing { position (offset=0.5, radius=10, angle=90) text { size (width=60, height=20) id = assocText } }}

Save this file and open busmod.spray and add the following at the end:

// Associationclass Association { connection AssociationConnection { name into assocText } { from source; to target; } behavior { create into associations palette "Connections" }}

Save this file and copy the generated plugin.xml to the root of the project again. Now start a new runtime Eclipseas before. You will now find a new element in the palette labeled Asociation. Create two classes on the diagram.Then select the Association from the palette and drag a line from one business class to the other. Try selectingthe association line and changing its name in the properties view. You should see it change in the diagramimmediately.

Implement a Custom Behavior

Extend the busmod.spray model like this:

diagram busmod for BusinessDomainDsl.BusinessDomainModel

behavior actions { custom showInfoForBusinessClass "Show Information"}

class BusinessClass { ... behavior { create into types palette "Shapes"; group actions } ...

Find the BusmodCustomShowInfoForBusinessClassFeature.java in your workspace. It should be in thesrc-gen/**/feature folder

Page 21: Spray User Guide - · PDF fileSpray User Guide. 2 ... (implemented with Xtext to describe Visual DSL Editors ... initial plugin.xml is generated to the project root and is updated

21

Right-click on BusmodCustomShowInfoForBusinessClassFeature from the features package. SelectSpray -> Move to source folder for manual extension.

The file is moved from src-gen to src (in the same package) and opens in the editor.

Implement the execute() method to open a message dialog.

@Override public void execute(ICustomContext context, EObject object) { MessageDialog.openInformation(Display.getDefault().getActiveShell(), "Information", "Selected object of type "+object.eClass().getName()); }

After restarting you can invoke an action „Show Information” from the context menu of a BusinessClass shape.

Page 22: Spray User Guide - · PDF fileSpray User Guide. 2 ... (implemented with Xtext to describe Visual DSL Editors ... initial plugin.xml is generated to the project root and is updated

22

Adding Style to Your Diagram

In this section we will show you how to integrate the Spray and Shape DSLs with and Style DSL. This tutorial canbe applied after the 5-Minutes tutorial.

As you may have already noticed there are three files:

• busmod.style• busmod.shape• busmod.spray

We have already seen that shapes are defined in files with the file extension .shape and the editor is defined inthe file with the extension .spray. Styles are defined in files with the file extension .style. Style definition can beimported and used in the shapes.

In the following for the business model DSL this modularization is shown by example. For a full reference of thecapabilities of Shape and Style DSL see the later sections of this user guide.

busmod.style

There is already a predefined style BusmodDefaultStyle contained in the busmod.style file generated by the Spraywizard. You can reuse styles by extending them as done here for the BusinessClassStyle. This style will haveall the values of BusmodDefaultStyle, thus also use 12pt as font-siz but additional defines the backgroundcolor to be yellow.

Page 23: Spray User Guide - · PDF fileSpray User Guide. 2 ... (implemented with Xtext to describe Visual DSL Editors ... initial plugin.xml is generated to the project root and is updated

23

style BusmodDefaultStyle { description = "The default style of the bm diagram type." font-size = 12}

style BusinessClassStyle extends BusmodDefaultStyle { description = "The style for the business class." background-color = yellow}

busmod.shape

We have seen a very simple shape definition in the 5 minute tutorial, and this section will explain the details andshow how to create more complex shapes. A shape is constructed by graphical elements. The element’s positions/coordinates and dimensions are defined by absolute values (absolute within the shape container, not within thewhole diagram). In the shape file you can refer to styles defined in a style file.

The text element has a special property called id. The value businessClassText is assigned to id in the examplemodel. The value of businessClassText has to be bound in the usage context of the shape in the spray DSL. Wesee this in busmod.spay file where the name of the business class is assigned to businessClassText.

We add the style BusinessClassStyle to the shape as follows

shape SimpleClassShape { rectangle style BusinessClassStyle { position(x=0, y=0) size(width=100, height=25) text { position(x=5, y=0) size(width=95, height=25) id = businessClassText } }}

Save this file and start a new workspace. In the editor you will see that the background color of a class that is newlycreated will be yellow.

busmod.spray

As you can see a style definition may not only be used in the shape file but also directly in the spray file. Byreferencing the BusmodDefaultStyle at diagram level it will be applied to all shape and connection elements in thisdiagram.

In the class BusinessClass the shape is referenced and the parameter businessClassText is bound to the value ofthe domain model element BusinessClass' attribute name.

In contrast to the 5-Minutes tutorial we now use the askFor property. This will trigger an input dialog when youcreate a box or a connection in the diagram editor asking for the name of the box resp. connection. This value isthen assigned immediately to the name attribute in this case of BusinessClass resp. Association.

import BusinessDomainDsl.*

diagram busmod for BusinessDomainModel style BusmodDefaultStyle

class BusinessClass icon "ecore/EClass.gif" { shape BusinessClassShape {

Page 24: Spray User Guide - · PDF fileSpray User Guide. 2 ... (implemented with Xtext to describe Visual DSL Editors ... initial plugin.xml is generated to the project root and is updated

24

name into businessClassText } behavior { create into types palette "Shapes" askFor name; }}

class Association icon "connection16.gif" { connection AssociationConnection { name into assocText } { from source; to target; } behavior { create into associations palette "Connections" askFor name }}

Page 25: Spray User Guide - · PDF fileSpray User Guide. 2 ... (implemented with Xtext to describe Visual DSL Editors ... initial plugin.xml is generated to the project root and is updated

25

Spray DSL

A Spray based example language

The domain model (defined in Xcore)

@Ecore(nsPrefix="busmod", nsURI="http://www.mod4j.org/busmod")@GenModel(editDirectory="/org.mod4j.dsl.businessdomain.mm.edit/src", editorDirectory="/org.mod4j.dsl.businessdomain.mm.editor/src",importerID="org.eclipse.emf.importer.ecore", complianceLevel="5.0", interfaceNamePattern="{0}", classNamePattern="")package BusinessDomainDsl

class BusinessDomainModel extends ModelElement{ contains resolving AbstractType [] types opposite model contains resolving unordered Association [] associations opposite model}

class BusinessClass extends AbstractBusinessClass{ contains resolving AbstractBusinessRule [] businessRules opposite businessClass refers BusinessClass superclass refers Association [] associationsTo opposite source}

class StringProperty extends Property{ String regularExpression int minLength = "-1" int maxLength = "-1" String defaultValue}

class BusinessRule extends AbstractBusinessRule{}

class Association extends ModelElement{ refers BusinessClass [1] source opposite associationsTo refers AbstractBusinessClass [1] target opposite associationsFrom String sourceRoleName = "sourceRoleName" Multiplicity sourceMultiplicity = "One" String targetRoleName = "targetRoleName" Multiplicity targetMultiplicity = "1" boolean composite = "false" boolean [1] bidirectional = "false" boolean [1] ordered = "false" container resolving BusinessDomainModel model opposite associations}

abstract class ModelElement{ String name = ""

Page 26: Spray User Guide - · PDF fileSpray User Guide. 2 ... (implemented with Xtext to describe Visual DSL Editors ... initial plugin.xml is generated to the project root and is updated

26

String description = ""}

abstract class AbstractType extends ModelElement{ contains resolving Property [] properties opposite owningType container resolving BusinessDomainModel model opposite types}

abstract class AbstractBusinessClass extends AbstractType{ refers Association [] associationsFrom opposite target}

abstract class AbstractBusinessRule extends ModelElement{ container resolving BusinessClass businessClass opposite businessRules}

abstract class Property extends ModelElement{ String dataType boolean nullable boolean ^derived = "false" boolean writable = "false" PersistencyMode persistency = "ReadWrite" boolean hasDefault = "false" container resolving AbstractType owningType opposite properties}

enum Multiplicity{ ZeroMany One = 1 ZeroOne = 2 OneMany = 3}

enum PersistencyMode{ ReadWrite Read None}

The spray file

import BusinessDomainDsl.* diagram mod4j for BusinessDomainModel behavior Redraw { custom redraw "Redraw Diagram";

Page 27: Spray User Guide - · PDF fileSpray User Guide. 2 ... (implemented with Xtext to describe Visual DSL Editors ... initial plugin.xml is generated to the project root and is updated

27

}

class BusinessClass icon "ecore/EClass.gif" { shape ClassShape { name into classname reference properties into attributes reference businessRules into businessrules } references { superclass : connection } behavior { create into types palette "Shapes" askFor name; group Redraw custom menuItem "Menu item" }}

class StringProperty { shape TextShape { name into textId2 ( name + " : " + dataType ) } behavior { create palette "Properties" }}

class BusinessRule { shape TextShape { name into textId2 } behavior { create palette "Rules" }} class Association { connection AssociationConnection { name into assocText } { from source; to target; } behavior { create into associations palette "Connections" }}

The shape file

shape ClassShape style BusinessClassStyle { rectangle { compartment (

Page 28: Spray User Guide - · PDF fileSpray User Guide. 2 ... (implemented with Xtext to describe Visual DSL Editors ... initial plugin.xml is generated to the project root and is updated

28

layout = vertical ) position (x=0, y=0) size (width=100, height=80) text style FontStyle { position (x=0, y=0) size (width=100, height=20) id = classname } line { point (x=0, y=21) point (x=100, y=21) } rectangle { compartment ( layout = vertical stretching ( horizontal=true, vertical=true ) spacing=1 margin=5 invisible id = attributes ) position (x=0, y=22) size (width=100, height=26) } line { point (x=0, y=48) point (x=100, y=48) } rectangle { compartment ( layout = vertical spacing=10 margin=20 invisible id = businessrules ) position (x=0, y=48) size (width=100, height=26) } }}

shape TextShape { stretching (horizontal=false, vertical=false) text style FontStyle { position (x=0, y=0) size (width=80, height=25) id = textId2 }}

Page 29: Spray User Guide - · PDF fileSpray User Guide. 2 ... (implemented with Xtext to describe Visual DSL Editors ... initial plugin.xml is generated to the project root and is updated

29

connection AssociationConnection { connection-type freeform placing { position (offset=0.5, radius=10, angle=90) text style FontStyle { size (width=60, height=20) id = assocText } }}

The style file

style BusmodDefaultStyle { description = "The default style of the bm diagram type." font-size = 12}

style BusinessClassStyle extends BusmodDefaultStyle { description = "The style for the business class." background-color = yellow}

Diagram

Imports

Referenced Java types and EClasses can be imported with the import keyword. This allows to use simple nameslater in the Spray model. The imports section is at the beginning of a Spray file:

import BusinessDomainDsl.*// all the rest follows here...

Diagram

The beginning of a Spray model is introduced by the diagram keyword, followed by an identifier for the diagram.This is the name of the diagram type specified by the Spray model, and its name will be reflected in the generatedcode.

The diagram name is followed by the specification of a model root element, prefixed by the keyword for. This isthe name of the EClass that is the root element a diagram represents. All other elements on the diagram must beinsertable into containment references of the model root type.

import BusinessDomainDsl.*

diagram mod4j for BusinessDomainModel

MetaClass

Referencing Ecore Classes

The class keyword is followed by the (qualified) name of an EClass. You can either fully qualify the name of theEClass, or you can import the EClass with an import statement before and then just use its simple name.

Page 30: Spray User Guide - · PDF fileSpray User Guide. 2 ... (implemented with Xtext to describe Visual DSL Editors ... initial plugin.xml is generated to the project root and is updated

30

class BusinessDomainDsl.BusinessClass : // full qualified name

import BusinessDomainDsl.* // wildcard importimport BusinessDomainDsl.BusinessClass // single import...

class BusinessClass : // simple name

The content assist will propose the names of all known EClasses:

Ecore models the development workspace

In the likely case that you want to use a meta model whose .ecore file is in the development workspace, it isnecessary that you create an EMF Generator Model as well. Further it is required to generate the Java classes outof this GenModel so later the generated code derived from the Spray model can resolve those classes. Eventuallyyou have add the project to the dependencies of the Spray project (therefore it is required to convert the ecorecontaining project to a plug-in project, if it wasn’t created as such before).

Instead of defining ecore and genmodel you may also have a look at Xcore as a more usable alternative.

If you have followed the steps above you get auto completion of the EMF package in the import section of theSpray file and after having defined such import the content assist at the diagram node will offer you all EClassesfrom this imported package that contain containment references.

After having assigned an EClass to the diagram node you get proposals for EClasses from the imported packageat class and connection nodes that are assignable to one of the containment features of the diagram’s associatedEClass.

As it is a common use case to change and extend the domain meta model beside extending the diagram modelchanges inside the domain meta model project will be registered and propagated when the Spray file is changed.

Create Behavior

To allow the creation of new MetaClass instances, a Create Behavior must be specified for the class. This is donein the behavior section, starting with the create keyword. Followed by this, the containment reference of the

Page 31: Spray User Guide - · PDF fileSpray User Guide. 2 ... (implemented with Xtext to describe Visual DSL Editors ... initial plugin.xml is generated to the project root and is updated

31

containing EClass (currently always the model root element associated to the Diagram) must be specified. Thekeyword into is just for readability to specify that the instance will be inserted into the following containmentreference.

diagram mod4j for BusinessDomainModel

class BusinessClass { shape ... { ... } behavior { create into types "Business Class" palette "Shapes"; }}

This example above allows the creation of instances of type BusinessClass to be created. The containmentreference is named types, which is defined by the Diagram model root type BusinessDomainModel. The label inthe tool palette is „Business Class”, and the creation tool is inserted into the palette group named „Shapes”. Boththe label and palette are optional. If left out, the label is the EClass name, and the creation tool is inserted into ageneric palette group.

Class Icon

Following the referenced EClass name an icon representing the class can be defined with the icon keyword. Thepath to the icon is quoted as a string.

class BusinessClass icon "ecore/EClass.gif"

The specified path is relative to a folder named icons/ in your project. It is checked that the folder icons exists inyour project. If the specified relative path of the icon file does not exist, a warning will be raised.

The content assist can help you entering the known icon paths. It will also show the icons.

The icon folder must be added to the bin.includes property of the build.properties file.

Page 32: Spray User Guide - · PDF fileSpray User Guide. 2 ... (implemented with Xtext to describe Visual DSL Editors ... initial plugin.xml is generated to the project root and is updated

32

If you created the project with the Spray project wizard, the icon folder was already initially created and added tobuild.properties.

...bin.includes = META-INF/,\ .,\ plugin.xml,\ model/,\ plugin.properties,\ icons/

Layout

This section describes the configuration of Layouts for shapes.

Colors

<shape> (color=<Color>)

Implicit Colors

By default, Spray will allow to use the constants defined in org.eclipse.graphiti.util.IColorConstantas simple names with lower case. For example, IColorConstant::DARK_GREEN will be available asdark_green.

Example:

text (color=dark_green)

Explicit Colors

Colors can be referred to by qualified names of the static fields.

Example:

text (color=org.eclipse.graphiti.util.IColorConstant::BLACK)

With import of the contants type this can be shortened:

import org.eclipse.graphiti.util.IColorConstant

class <...> text (color=IColorConstant::BLACK)

RGB Color

Colors can be defined by their RGB values:

text (color=RGB(255,50,0))

If you invoke content assist it will offer you an option „Pick color...”, which will open the system’s colors dialog.

Page 33: Spray User Guide - · PDF fileSpray User Guide. 2 ... (implemented with Xtext to describe Visual DSL Editors ... initial plugin.xml is generated to the project root and is updated

33

Shapes

A metaclass can be mapped to a shape by referencing a Shape defined with the Shapes DSL.

A shape defined with the Shape DSL can be referred to by using the shape keyword.

For how to define shapes and how to pass parameters from Spray DSL to referenced shapes see the „Shape DSLGuide” later in this documentation.

class MyMetaclass { shape MyCustomShape { ... }}

Page 34: Spray User Guide - · PDF fileSpray User Guide. 2 ... (implemented with Xtext to describe Visual DSL Editors ... initial plugin.xml is generated to the project root and is updated

34

Concept of a Model Driven Graphical Editor

Spray is providing three different kinds of DSLs (Domain Specific Languages) - Spray Core, Shape and Style –as shown in the following graphic. The first is the core language which is responsible for the mapping betweenmeta model to shapes, styles and behavior. The second language (Shape DSL) is used to define more complexshapes and decorator of connection. All of them will be generated from a primitive set of figures like rectangles andellipses. It also handles complex properties as their placing, sizing policy and nesting of figures. The last DSL (StyleDSL) is focusing the color and format behavior of an shape. Therefore it is possible to define individual styles likeCSS relates to HTML.

If any of these model is changed the model generation process is executed and Java, XML and Properties will begenerated for the Graphiti Eclipse Plug-In.

Page 35: Spray User Guide - · PDF fileSpray User Guide. 2 ... (implemented with Xtext to describe Visual DSL Editors ... initial plugin.xml is generated to the project root and is updated

35

Style DSL Guide

This chapter describes how to define global Graphiti styles for an Spray Project.

A style describes the referenced figures generally. Attributes like background color and line style can be set andthey will finally be mapped with a name. Afterwards the styles can be referenced with their name. The reference willbe possible in one hand globally for the whole spray project and can be overwritten in the other hand from a class,a shape and/or a shape element (as ellipse, rectangle, ...). If no style at all will be referenced an DefaultSprayStylewill be taken.The style approach helps to generate a nice Graphiti Editor for a given color schema and supportsto adjust all element styles as your own necessity. Gradients are also supported for a style definition in order toenhance the visual layout of shape elements.

An example for a style

style BlackAndWhiteStyle { description = "A style for white background and black foreground." transparency = 0.95 background-color = white line-color = black line-style = solid line-width = 1 font-color = black font-name = "Tahoma" font-size = 10 font-italic = yes font-bold = no}

The appearance of shapes can be defined in an external style or can be changed internally in the shape definition.For this the style keyword is used and the style attributes are defined in round brackets. In this case one or moreattributes of the possible style attributes can be overridden. This takes effect on the corresponding element, butnot for the nested elements or other forms on the same layer. This is shown in the following figure. There the{background-color} is set to the blue color for the rectangle. Respectively this changes just the rectangle inthe picture to gain the blue color.

The second method makes it possible to inherit style classes for the whole shape. Here the style classis referenced by its name after the keyword style. The second part of the Figure uses the style classBlackAndYellowStyle for the whole shape. The complete shape will become a yellow background. If the sameapproach is used at the beginning of the rectangle, then the entire envelope would become yellow, but not thecircle.

As shown in the lower part of the figure these two methods can be mixed. The attributes defined inline for a shapewill always overwrite the attributes on the style class. In the example the whole shape becomes yellow apartfrom the rectangle, which overrides its color to blue. In our experience, this mixing is useful. Often the line-styleattributes are used inline to change the line appearance (e.g. dotted instead of solid) where as color, backgroundand text attributes are inherited.

Page 36: Spray User Guide - · PDF fileSpray User Guide. 2 ... (implemented with Xtext to describe Visual DSL Editors ... initial plugin.xml is generated to the project root and is updated

36

Style Key Facts

style BlackAndWhiteStyle

A style starts with the keyword style. After the keyword a unique id (name) for the style will be set. It is veryimportant, that this name is unique for the whole project scope. At the same time the style id will become the nameof the generated Java class as well.

public class BlackAndWhiteStyle extends DefaultSprayStyle implements ISprayStyle

For every defined style a Java class will be generated. The interface ISprayStyle provides two methods which willbe defined for every style. The inherited class DefaultSprayStyle is the super class of all styles and provides defaultattributes. The inheritance could be overwritten in the DSL.

public Style getStyle(Diagram diagram);public Color getFontColor(Diagram diagram);public Style newStyle(Diagram diagram)public AdaptedGradientColoredAreas getColorSchema();

The first method getStyle() returns a Style (org.eclipse.graphiti.mm.algorithms.styles.Style)of the graphiti meta model plugin. This style will have all attributes set which are defined in the DSL. The secondmethod (getFontColor()) becomes necessary because graphiti allows just one color for the foreground. Theforeground color could be a line color and a font color at the same time. This method helps the user to define afont-color that is different from the line color. The third method (newStyle) returns the new style and is the default

Page 37: Spray User Guide - · PDF fileSpray User Guide. 2 ... (implemented with Xtext to describe Visual DSL Editors ... initial plugin.xml is generated to the project root and is updated

37

style definition for Spray. The last method (getColorShema) which is overridden returns the color schema with thespecified gradient color area schemas.

Default Values

If the user doesn’t specify any value for one or more attribute the default values will be gained. The default valuesare.Attribute Type Range Default Value

transparency float 0.0 – 1.0 1.0

background color Color RGB (r,g,b), predefinedcolor or transparent

white

line color Color RGB (r,g,b), predefinedcolor or transparent

black

line width integer > 0 1

line style LineStyle solid, dot, dash, dash-dot,dash-dot-dot

solid

font name String - Arial

font color Color RGB (r,g,b) or predefinedcolor

black

font size integer >= 0 1

font italic boolean yes or no no

font bold boolean yes or no no

gradient orientation GradientAllignment vertical or horizontal vertical

There are predefined colors available. They are following

• white• very-light-gray• light-gray• gray• dark-gray• black• red• light-orange• orange• dark-orange• yellow• green• light-green• dark-green• cyan• light-blue• blue• dark-blue

Style Elements

Description

description = "A style for white background and black foreground."

The description should describe the style with a sentence. This attribute is required and have to be defined. It isrecommended to use a description of at least 20 characters.

Page 38: Spray User Guide - · PDF fileSpray User Guide. 2 ... (implemented with Xtext to describe Visual DSL Editors ... initial plugin.xml is generated to the project root and is updated

38

Transparency

transparency = 0.95

The transparency defines the visibility of the whole shape. The value is a floating value within the interval 0.00and 1.00. The value 1.00 defines that the shape is fully visible and 0.00 describes that the whole shape is invisible.All values between 0 and 1 can be used here to define the right transparency value.

Background

background-color = whitebackground-color = RGB (200,100,20)background-color = MyGradient

The background-color defines the background of the shapes. All shape elements will be of this color. Thereforepredefined color values can be used or if no predefined color applies to the wanted color then the RGB values canbe filled. Following text sequence should be used: RGB(RED,GREEN,BLUE). The values RED,GREEN,BLUE areinteger values between 0 and 255. Another possibility to assign the background-color is to reference a owngradient definition. The exact definition can be found the chapter gradients. Finally if a transparent background iswanted then the value transparent can be used.

Line

line-color = black

The line-color is mapped to the foreground color in Graphiti. It defines the foreground elements on the shapes. Theforeground elements are e.g. border of shapes, lines and font. Same as on the background-color predefinedcolor values can be used or if no predefined color applies to the wanted color then the RGB values can be filled.Following text sequence should be used: RGB(RED,GREEN,BLUE). The values RED,GREEN,BLUE are integervalues between 0 and 255. Finally if a transparent foreground is wanted then the value transparent can beused.

line-style = solid

The line style defines the style type of the line. There are possible values as solid, dot, dash, dash-dotand dash-dot-dot. All lines will be created with this style.

line-width = 1

The line width defines the width of foreground elements (e.g. lines and shape borders). Therefore a simpleinteger value of 0 or bigger (>= 0) can be used. If 0 is used then no lines and shape borders will be drawn.

Font

font-color = black

The font color is almost the same as the line-color but it doesn’t allow to set a transparent font-color. Thefont color is as the line color a foreground color. Therefore the generated Java class provides a own method forthis. This color will be finally used on all fonts. If no font-color is set, the line-color will be gained.

font-name = "Tahoma"

The font name is a simple String that defines the name of the font family on the computer. If the given String cannot be found on the machine a warning will be shown in the Eclipse UI Style Editor.

font-size = 10

The font size is a simple integer with a value of 1 or bigger (>= 1). This defines the font pixels of the font.

Page 39: Spray User Guide - · PDF fileSpray User Guide. 2 ... (implemented with Xtext to describe Visual DSL Editors ... initial plugin.xml is generated to the project root and is updated

39

font-italic = yesfont-bold = no

The font style italic and bold can be set with the attributes font-italic and font-bold. Therefore a yes orno boolean can be used. "yes" defines the the font will be drawn with this style, "no" defines that this style will notbe got.

Gradients

Spray provides a definition of gradients to support highlighting on elements. Every gradient definition starts withthe keyword gradient followed by a unique name. A gradient definition consists out of area attributes, whodefine the color and the offset of each section. The color can be defined like a font-color with predefinedcolors (blue) or the RGB structure (RGB(130,200,25)). The offset determines each gradient section with apercentage value. A gradient also can be defined as a background-color and could look like this.

Those gradient definition can now be used alternative in the style language with gradient-orientation andhighlighting options. The orientation can be vertical or horizontal to set the direction for the wholegradient. The reason why the orientation is assigned for all gradient definitions is that graphiti force it to implementit that way and to keep the orientation consistent. The highlighting option can be parametrised with selected,multiselected, allowed and unallowed where gradients for the behavior can be specified. An example couldlook like that.

Default Value – GradientsAttribute Type Range Default Value

highlightingselected ColorOrGradient RGB (r,g,b), predefined

color, gradient ortransparent

none

multiselected ColorOrGradient RGB (r,g,b), predefinedcolor, gradient ortransparent

none

allowed ColorOrGradient RGB (r,g,b), predefinedcolor, gradient ortransparent

none

unallowed ColorOrGradient RGB (r,g,b), predefinedcolor, gradient ortransparent

none

gradient attributesarea color Color RGB (r,g,b), predefined

colorwhite

Page 40: Spray User Guide - · PDF fileSpray User Guide. 2 ... (implemented with Xtext to describe Visual DSL Editors ... initial plugin.xml is generated to the project root and is updated

40

area offset float 0.0 – 1.0 0.0

Page 41: Spray User Guide - · PDF fileSpray User Guide. 2 ... (implemented with Xtext to describe Visual DSL Editors ... initial plugin.xml is generated to the project root and is updated

41

Shape DSL Guide

This chapter describes how to define global Graphiti shapes for a Spray project.

The Shape DSL is a geometric description for the visual representation of a figure. A figure mostly consists of atleast one or more geometric forms which are implemented in the Graphiti framework. If a more complex figure isneeded basic forms can be nested together.

An example for a shape

shape Usecase style org.eclipselabs.spray.styles.NoTransparency { size-min(width=100, height=100) size-max(width=200, height=200) stretching(horizontal=true, vertical=true) ellipse { size(width=200, heigth=100) position(x=5,y=5) style(background-color=blue line-color=red) text { align(horizontal=center,vertical=bottom) style(font-color=black) id = TextId } }}

Shape Key Facts

shape Usecase

A shape definition starts with the keyword „shape” for every figure. After the keyword a unique name (id) will be set,which identify the shape for the whole project. Shapes with the same name are not valid and will be displayed aserror. The name of a figure will be the name for the generated java class.

public class Usecase implements ISprayShape

For every defined shape a Java class will be generated. The interface ISprayShape provides one method which willbe defined for every shape class.

public ContainerShape getShape(Diagram diagram);

The method getShape returns a ContainerShape(org.eclipse.graphiti.mm.pictograms.ContainerShape) this container comprises all elements of thedefined shape.

Shape Visualisation

shape Usecase style BlackAndWhiteStyle

Every shape definition can reference a custom style for their visual behavior. The style will be inherited by thenested shape elements.If a custom style on a nested shape is needed a separate style can be referenced by the nested shape.

shape Usecase style BlackAndWhiteStyle { ellipse { style(background-color=blue line-color=red) } }

Page 42: Spray User Guide - · PDF fileSpray User Guide. 2 ... (implemented with Xtext to describe Visual DSL Editors ... initial plugin.xml is generated to the project root and is updated

42

The nested style only affects the referenced shape without inheritance. If element values are not set, the Graphitidefault value will be set.

Shape Elements

A complex figure could have multiple levels for its visualization. The brackets „{ }” represent a separator for eachlevel of a figure.

shape Usecase { ellipse {} }

If elements are at the same level like an ellipse and a text they will be defined amongst each other, so multipleshapes can be nested at the same level.

shape Usecase { ellipse {} text {} }

Every figure has the attributes size-min, size-max, stretching and proportional that can be set foreach definition. The size-min / size-max is the minimum/maximum bound of a figure to assure to display themcorrectly. The attributes streching and proportional affects the resize abilities of a shape. streching hasan attribute for horizontal and vertical stretching of the figure. proportional handles whether the resizeproportion between height and width is kept or not.

shape Usecase { size-min(width=100, height=100) size-max(width=200, height=200) stretching(horizontal=true, vertical=true)}

Anchor

Every shape has the ability to place different types of anchors with the keyword anchor. An anchor is specifiedat the first level of an shape and give the shape the possibility place a connection. There are four options to placean anchor. The first 2 options are dynamic and can be set with a keyword anchor = center or anchor =corners. Does not matter what kind of shape is chosen the anchor will be placed in the center or at the cornerswhere the shape is drawn onto. If an ellipse is defined, this shape will be drawn on a invisible rectangle so thecorners of the anchor are the one from the rectangle.There are two more options to define an anchor a relative and fix one. A relative anchor type can look like this.

anchor { position(xoffset=0.1,yoffset=0.0) position(xoffset=0.8,yoffset=1.0)}

Every position entry represent a anchor point for a connection.In this case the anchor got an attribute positionwith two values xoffset and yoffset. The xoffset/ yoffset is the distance from the upper left corner togiven value.

anchor { position(x=5, y=10) position(x=50, y=100)}

Page 43: Spray User Guide - · PDF fileSpray User Guide. 2 ... (implemented with Xtext to describe Visual DSL Editors ... initial plugin.xml is generated to the project root and is updated

43

This example defines a fixed anchor, where the coordinates for the position are with a fixed value.

Shape Property Assignment

A common use case is to display values from the domain model inside the shape. Thus the Shape DSL offers thepossibility to declare place holders inside the text shape. In the following example boxName is the id of the placeholder for the text to be displayed in the shape.

shape Box { rectangle { position (x=0, y=0) size (width=100, height=100) text { position (x=5, y=5) size (width=90, height=90) align (horizontal=center, vertical=middle) id = boxName } }}

When referencing the shape inside the Spray DSL you can bind String properties of the meta class to the placeholders defined inside the shape. In the example below name is String property of the class MyClass that is boundto the place holder boxName in the shape definition. This makes shape definitions reusable for different domainclasses and it is also useful for complex shapes that consists of multiple texts.

Page 44: Spray User Guide - · PDF fileSpray User Guide. 2 ... (implemented with Xtext to describe Visual DSL Editors ... initial plugin.xml is generated to the project root and is updated

44

class MyClass { shape Box { name into boxName } ... }

Beside the direct mapping of properties to place holders it is also possible to use expressions for the mapping.

class MyClass { shape Box { name into boxName ("name: " + name) } ... }

So for an instance of MyClass with name value „classOne” the shape will display „name: classOne”. Using thedirect editing feature at the shape offers you to alter the value of name only. When you change it to „classTwo” thevalue of MyClass's name feature will be updated and the shape will display now „name: classTwo”.

The Spray DSL allows to pass String constants as well:

class MyClass { shape Box { constant "fixName" into boxName } ... }

Btw. the following syntax would lead to the same display String as above, although direct editing for name isworking here.

class MyClass { shape Box { name into boxName ("fixName") } ... }

The example below seems to be identical to expressions example above, but now direct editing would not changethe display string. Only changing the name feature in the properties view (or directly in the domain model file andthe using update in the diagram) will alter the display string.

Page 45: Spray User Guide - · PDF fileSpray User Guide. 2 ... (implemented with Xtext to describe Visual DSL Editors ... initial plugin.xml is generated to the project root and is updated

45

class MyClass { shape Box { constant "name: " + name into boxName } ... }

Passing properties to connection shapes works analogous:

connection Association { connection-type freeform placing { position(offset=0.0, radius=10, angle=0) text { position (x=0, y=0) size (width=100,height=50) id = Left } } placing { position(offset=0.4, radius=10, angle=0) text { position (x=0, y=0) size (width=100,height=50) id = Middle } } placing { position(offset=0.8, radius=10, angle=0) text { position (x=0, y=0) size (width=100,height=50) id = Right } }}

For explanation of the connection definition syntax see later this documentation.

class MyConnection { connection Association { constant source.name into Left name into Middle constant target.name into Right } { from source; to target; } ...

Page 46: Spray User Guide - · PDF fileSpray User Guide. 2 ... (implemented with Xtext to describe Visual DSL Editors ... initial plugin.xml is generated to the project root and is updated

46

}

As you can see in the example the names of the connected objects are used at the connection line endings and thename of the association object is used as name decorator of the connection line placed in the center.

Compartments

A compartment is a shape in which other shapes may be placed through the palette or by drag and drop within thediagram.A compartment is specified by the compartment property:

shape SimpleClassShape { rectangle { compartment{ layout=vertical spacing = 5 margin = 5 id = simpleAttributes ) position (x=0, y=0) size (width=100, height=320) }}

A compartment has a layout, which can be vertical, horizontal or fixed. In a fixed compartment theshapes in the compartment are placed by the user, and can be moved around free. In a vertical compartment,the shapes inside the compartment will be layout vertically below each other. These shapes cannot be placed ormoved by the user. A vertical compartment behaves similar, but the shapes are layout in a horizontal way.

Only a rectangle, a ellipse or a roundedrectangle may be marked as compartments.

For a vertical or horizontal compartment the property spacing specifies the space between the childshapes, and the property margin specifies the space around all the child shapes.

The id property behaves similar to the id property of the text shape. The main Spray DSL may refer to such anid and specify what type of object are allowed inside the compartment. based on the above example, the a Spraymodel might look like:

class BusinessClass { shape SimpleClassShape { reference properties into simpleAttributes } behavior { create into types palette "Shapes"; }}

The properties is a reference from BusinessClass in the domain (ecore) model and specifies that associatedobjects may be placed inside the simpleAttributes compartment.This will automatically allow all attributes for which a shape is defined in the Spray DSL to be placed inside thecompartment.An StringProperty could be specified as

Page 47: Spray User Guide - · PDF fileSpray User Guide. 2 ... (implemented with Xtext to describe Visual DSL Editors ... initial plugin.xml is generated to the project root and is updated

47

shape TextShape style org.eclipselabs.spray.runtime.graphiti.styles.DefaultSprayStyle { text style org.eclipselabs.spray.runtime.graphiti.styles.DefaultSprayStyle { position (x=0, y=0) size (width=80, height=25) id = textId2 }}

class StringProperty { shape TextShape { name into textId2 } behavior { create palette "Properties" }}

class BoolProperty { shape TextShape { name into textId2 } behavior { create palette "Properties" }}

I this example both a StringProperty and a BoolProperty can be placed inside the compartment.They are both subtypes of Property , which is the type of the property reference from BusinessClass.

Shape Default Values

If the user doesn’t specify any value for one or more attribute the default values will be gained. The default valuesare.Attribute Type Range Default Value

stretching - vertical boolean yes or no true (yes)

stretching - horizontal boolean yes or no true (yes)

size-min - width integer >= 0 0

size-max - width integer >= 0 0

size-min - height integer >= 0 0

size-max - height integer >= 0 0

Text

The keyword text represents a shape element which

text { }

A text field has four different attributes that can be set. The first two attributes position and size are comefrom the CommonLayoutDefinition. This layout definition is also used for ellipse, rectangle and rounded-rectangle. The position defines the start position of the element with the corresponding x and y value. For thespecific size of the element the with and height can be set. For the alignment the keyword align is used andseparated in horizontal and vertical. For both values are enumeration values referenced. The First value

Page 48: Spray User Guide - · PDF fileSpray User Guide. 2 ... (implemented with Xtext to describe Visual DSL Editors ... initial plugin.xml is generated to the project root and is updated

48

can be left,right or center and the second one top, middle or bottom. The last attribute id is responsiblefor the text value which is used to reference the value for directediting and updating.

text { position (x=0, y=5) size (width=50, height=20) align (horizontal=center, vertical=middle) id = shapeName}

Attribute Type Range Default Value

Default Value – Text/Wrapped-Textsize - width integer >= 0 0

size - height integer >= 0 0

position - x integer >= 0 0

position - y integer >= 0 0

id String - ""

Line

The keyword line represents a line shape element

line { }

This shape needs a pair of point which define the startpoint and an endpoint of a line. Each point has their x=/ y=coordinates.

line { point(x=25,y=20) point(x=25,y=20)}

Attribute Type Range Default Value

Default Value – Linepoint - x integer >= 0 0

point - y integer >= 0 0

Polyline

The keyword polyline represents a polyline shape element

polyline { }

A polyline definition required a set of point to specify every start and end of a route. Each point has their x=/ y=coordinates.

polyline { point(x=50,y=0) point(x=50,y=10) point(x=60,y=10)}

Attribute Type Range Default Value

Default Value – Polyline

Page 49: Spray User Guide - · PDF fileSpray User Guide. 2 ... (implemented with Xtext to describe Visual DSL Editors ... initial plugin.xml is generated to the project root and is updated

49

point - x integer >= 0 0

point - y integer >= 0 0

2D Shape

All 2d shape definitions have two obligatory attributes size and position. The size defines the width andheight of a 2d shape. The position defines the x and y coordinate where the figure is displayed.

Ellipse

The keyword ellipse represents a ellipse shape element.

ellipse { }

An ellipse element is able to represent every kind of ellipses and also circles, when the with and height attributegot the same value.

ellipse { size(width=200, height=100) position(x=5,y=5)}

Attribute Type Range Default Value

Default Value – Ellipsesize - width integer >= 0 0

size - height integer >= 0 0

position - x integer >= 0 0

position - y integer >= 0 0

Rectangle

The keyword rectangle represents a rectangle shape element.

rectangle { }

The rectangle can present all types of rectangles and also squares, when the with and height attribute got thesame value.

rectangle { size(width=100, height=100) position(x=0,y=0)}

Attribute Type Range Default Value

Default Value – Rectanglesize - width integer >= 0 0

size - height integer >= 0 0

position - x integer >= 0 0

position - y integer >= 0 0

RoundedRectangle

The keyword rounded-rectangle represents a rounded rectangle shape element.

Page 50: Spray User Guide - · PDF fileSpray User Guide. 2 ... (implemented with Xtext to describe Visual DSL Editors ... initial plugin.xml is generated to the project root and is updated

50

rounded-rectangle {

The rounded-rectangle definition is similar to the rectangle definition. There is just one optional attributenamed curve which set the curve of the corners.

rounded-rectangle { size(width=100, height=100) position(x=0,y=0) curve(width=30, height=30)}

Attribute Type Range Default Value

Default Value – RoundedRectanglesize - width integer >= 0 0

size - height integer >= 0 0

position - x integer >= 0 0

position - y integer >= 0 0

curve - width integer >= 0 0

curve - height integer >= 0 0

Polygon

The keyword polygon represents a polygon shape element.

polygon { }

A polygon is shape with n-sides. This figure is bounded by a closed path, this mean the startpoint is connected tothe end point. Every side is defines by two point with there x and y coordinates.

polygon { point(x=50,y=0) point(x=50,y=10) point(x=60,y=10) }

Attribute Type Range Default Value

Default Value – Polygonpoint - x integer >= 0 0

point - y integer >= 0 0

Practise Examples

In this chapter some examples will be explained and described in detail.

Curve – Example

The rounding options are used for the distance on the line before and after the point begins. In our example wedefined, that 40 pixels before the bottom-right point the rounding starts and 20 pixels after the bottom-right point therounding ends.

polygon { point(x=50,y=0) point(x=0,y=50, curveBefore=40, curveAfter=20)

Page 51: Spray User Guide - · PDF fileSpray User Guide. 2 ... (implemented with Xtext to describe Visual DSL Editors ... initial plugin.xml is generated to the project root and is updated

51

point(x=100,y=50, curveBefore=40, curveAfter=20) }

This rounding options only be specified for Shapes (Polygons and Polylines).

Complex Example

To get more experience in defining some complex figures, we set up some examples figures from UML (UnifiedModeling Language) and BPMN (Business Process Model and Notation).

UML – Example

This example shows how to create an actor with the shape dsl. At first we need to define a shape with the nameUML_UC_Actor. After that we will define the geometric from of this figure and add an ellipse. This ellipse isa circle, because the value for width and height are the same. The circle represents the head of the actor and isdisplayed at top of the shape.

shape UML_UC_Actor { ellipse { // Head position(x=0,y=0) size(width=50,height=50) }}

Then we add two line-shapes for the body and the hands of the actor. The coordinates starts from left uppercorner (x=0/ y=0) to the right bottom corner. We want to place the body below the head so we need to set 50(length of the head) for the y values and 25 (middle of the head) for first x value. The length of the body part willbe decided by the distance between the both y-point values which is 50. The second line defines the hands of theactor which is displayed 20 beneath the body starts. The length of the hands are equal to the size of the head.

shape UML_UC_Actor {

Page 52: Spray User Guide - · PDF fileSpray User Guide. 2 ... (implemented with Xtext to describe Visual DSL Editors ... initial plugin.xml is generated to the project root and is updated

52

ellipse { // Head position(x=0,y=0) size(width=50,height=50) } line {point(x=25,y=50) point(x=25,y=100)} // Body line {point(x=0,y=70) point(x=50,y=70)} // Hands}

The last step will complete our actor. Therefore we need to define a polyline for the feet. We also want to place thefeet below the body so we need to add the y-values first. This mid point has 100 (y-head + y-body) as y-value and25 (middle of head) as x-value which is the boundary point between the body and feet. The two other points of thepolyline are connected to boundary point and decide the length of the feet which is the square root of 50. The startand the end of the polyline is based on the headsize in this example from x=0 to x=50.

shape UML_UC_Actor { ellipse { // Head position(x=0,y=0) size(width=50,height=50) } line {point(x=25,y=50) point(x=25,y=100)} // Body line {point(x=0,y=70) point(x=50,y=70)} // Hands line {point(x=50,y=70) point(x=100,y=70)} // Hands polyline {point(x=0,y=150) point(x=25,y=100) point(x=50,y=150)} // Feet}

Page 53: Spray User Guide - · PDF fileSpray User Guide. 2 ... (implemented with Xtext to describe Visual DSL Editors ... initial plugin.xml is generated to the project root and is updated

53

BPMN – Example

This example shows how to create an envelope with the shape dsl. The hole figure is inside a circle so our customshape starts with an ellipse where width and height got the same value. After that we specify the edge of theenvelope with a rectangle. The position of the rectangle is slightly indented to display it in the center of theellipse. Now we need to add a triangle shape to complete the envelope. For this case we need a polygon thatconsist out of three point. The triangle is equal-sided that mean that two points got the same y. The differencebetween those both x values define the length of upper edge. The third point is connected to the other two and antriangle is created. There are more than one way to specify a custom shape e.g this shape could also be realizedwith line instead of polygon.

shape BPMN_EventMail { ellipse { size(width=50, height=50) position(x=0, y=0) rectangle { size(width=30, height=20) position(x=10, y=15) polygon { point(x=0,y=0) point(x=15,y=10) point(x=30,y=0) } } }}

Page 54: Spray User Guide - · PDF fileSpray User Guide. 2 ... (implemented with Xtext to describe Visual DSL Editors ... initial plugin.xml is generated to the project root and is updated

54

Connections

A connection is an element to connect two or more shapes which each other. Every definition starts with thekeyword connection followed by a unique name. An element definition could look like that.

connection BPMN_DefaultFlow { placing { position(offset=1.0,radius=0,angle=0) polygon { point(x=-10,y=10) point(x=0,y=0) point(x=-10,y=-10) style(background-color=black) } } placing { position(offset=0.05,radius=0,angle=0) line{ point(x=0,y=-10) point(x=5,y=10) } }}

Placing

If a custom visual behavior around the connection element is needed, a placing could be used. Eachplacing describes the content that is placed arround of a connection. Every placing requires an elementnamed position where the value for the alignment will be set.

position(offset=1.0,radius=0,angle=0)

A position attribute got four diffrent values offset, radius and angle. The offset is the position valueamong the line from left(offset=0.0) to right(offset=1.0), the radius is the gap with a specified anglebetween the connection and the element which is placed. The angle can be specified in degree from 0 to 360.Imagine a circle with 4 quadrants, then the first quadrant is from 0 to 90 degree, the second is from 90 to 180 andso on.

Page 55: Spray User Guide - · PDF fileSpray User Guide. 2 ... (implemented with Xtext to describe Visual DSL Editors ... initial plugin.xml is generated to the project root and is updated

55

Visual attributes are shown in the following figure for a better imagination.

ConnectionType

The type of the connection can be set with the attribute connection-type. There are two diffrent typesconnection-type=manhattan and connection-type=freeform which are available.

Page 56: Spray User Guide - · PDF fileSpray User Guide. 2 ... (implemented with Xtext to describe Visual DSL Editors ... initial plugin.xml is generated to the project root and is updated

56

Additional Features

The the following chapter some additional are described. These features will support the user in handing andusage with the graphical editor.

Direct Editing

The Direct Edit feature is the possibility to change value directly in the editor. This functionality reacts when the useclick on the pictogram element and an editor box is shown. Therefore the user is able to change the value of theelement. If a text is already set, it will be selected and replaced with the new value.

Properties Sheet

Another possibility for the user to change the properties of a shape or a connection is via the property sheet. Thecontribution of the property sheet is specified by the eclipse platform.

Page 57: Spray User Guide - · PDF fileSpray User Guide. 2 ... (implemented with Xtext to describe Visual DSL Editors ... initial plugin.xml is generated to the project root and is updated

57

Spray Extensions Guide

Basic extensions: Generation Gap Pattern

Generation Gap Pattern for Java code

The code generated by Spray can be extended (and even fully overwritten) by the developer. For this, Sprayuses the Generation Gap Pattern. More specifically we use Conditional Generation 1 (with one gen folder), asdescribed in Generation Gap Pattern by Heiko Behrens. In short, the concrete, empty, subclasses that are meantas extension points are generated in the src-gen/ folder. When you want to extend them, you need to move thefile to the src/ folder. The generator will recognize whether an extension point file is in the src folder and in thatcase not generate it again. Read Heiko’s blog for a more elaborate explanation. The classes that can be extendedderivefrom classes with the same name with suffix Base.

The files generated to the src-gen/ folder are furthermore marked as derived within Eclipse. Thus, if youaccidently try to edit them, a warning dialog pops up.

The Spray UI facilitates this repeating task by adding a context menu action on extension point files. For example,right click on the Feature Provider class:

Page 58: Spray User Guide - · PDF fileSpray User Guide. 2 ... (implemented with Xtext to describe Visual DSL Editors ... initial plugin.xml is generated to the project root and is updated

58

Now choose from the context menu Spray / Move to source folder for manual extension:

Page 59: Spray User Guide - · PDF fileSpray User Guide. 2 ... (implemented with Xtext to describe Visual DSL Editors ... initial plugin.xml is generated to the project root and is updated

59

After doing this the class is moved to the src/ folder. The derived flag is removed and you can extend the classnow.

If you accidently moved the file to the src/ folder and want to let it be generated again, just remove it. With thenext generator run it will appear again in the src-gen/ folder.

Generation Gap Pattern for plugin.xml

An initial plugin.xml is created into the project root when the Spray project is setup using the Spray project wizard.

Partial regeneration

The generated plugin.xml includes comments like <!-- DIAGRAM TYPE AUTOGEN START --> and <!--DIAGRAM TYPE AUTOGEN END --> that mark regions as generated. After each save of the *.spray file theseregions will be updated. All contents in the plugin.xml that are placed outside those marked regions will stayuntouched.

Avoid regeneration

So if you want to use manually written content in favor of the generated one you have to rename (or delete) themarker comments. Its recommended to rename instead of delete the comment as this leaves the option to renamethe comment back to be a generation marker comment that will enable over generation again.

Complete regeneration

If you want the plugin.xml to be completely regenerated you can always delete the plugin.xml in the project root.Then the plugin.xml from the src-gen folder be copied to the project root. You have to perform a refresh on theproject to see the copied plugin.xml.

Extending Spray’s code generator

Spray’s code generator produces a good basis for Graphiti editors. However, it cannot be complete againstuser requirements and may contain also bugs. The appliance of the Generation Gap Pattern allows to modifythe produced classes and change whatever required. But when the changes need to be applied to all producedclasses, it would be more efficient to change the generator’s production rules. The naive way to do this would beto change the generator’s source directly. This will lead to problems, since Spray’s generator implementation willevolve and you would need to merge your changes later and may get lost what actually your changes were.

Page 60: Spray User Guide - · PDF fileSpray User Guide. 2 ... (implemented with Xtext to describe Visual DSL Editors ... initial plugin.xml is generated to the project root and is updated

60

Spray provides a far more better way to change the generator. Instead of changing the source directly it is possibleto derive the existing templates and make Spray use the overridden templates instead of the original ones. Sprayuses Xtend, which directly compiles to Java, so the templates themselves can be concerned as just Java classeswhich you could derive from.

Create plugin project

To extend the generator you basically need a plugin project. Create one and add the following dependencies:

Require-Bundle: org.eclipse.core.runtime, org.eclipselabs.spray.generator.graphiti;bundle-version="0.5.0", org.eclipselabs.spray.mm;bundle-version="0.5.0", org.eclipselabs.spray.runtime.xtext;bundle-version="0.5.0", org.eclipselabs.spray.generator.graphiti.uiImport-Package: org.eclipse.xtend2.lib, org.eclipse.xtext.xbase.lib

Derive templates

The templates are inside of the plugin org.eclipselabs.spray.generator.graphiti, and you will need toknow which template(s) you actually need to override. The header comment in the generated code will name thetemplate from which it origins. You likely have to look at the original template source to make good additions.

Derive the template, e.g.

import org.eclipselabs.spray.generator.graphiti.templates.diagram.FeatureProviderimport org.eclipselabs.spray.mm.spray.Diagram

class FeatureProviderExt extends FeatureProvider { override generate_additionalMethods(Diagram context) ''' // this has been added by a derived template from org.eclipselabs.spray.generator.graphiti.extension ''' }

Most templates (those that generate Java classes) are defining two hook template methodsgenerate_additionalFields(T) and generate_additionalMethods(T) (T is the parameter type, sincethe templates are parametrized). By default, they are empty, and as their name states, by overriding these methodsone could produce additional fields or methods for the generated base class.

Guice Runtime Module

To actually use your derived template class instead of the original one you have to provide a Guice module thatbinds your class. This looks like follows:

public class GeneratorExtensionRuntimeModule extends AbstractGenericModule { public Class<? extends FeatureProvider> bindFeatureProviderTemplate() { return FeatureProviderExt.class; }}

Extension point

Now open the Manifest editor and go to the Extensions section. Add an extension for extension pointorg.eclipselabs.spray.runtime.xtext.overridingGuiceModule. This extension point requires you toprovide the class name (property class) of your

Page 61: Spray User Guide - · PDF fileSpray User Guide. 2 ... (implemented with Xtext to describe Visual DSL Editors ... initial plugin.xml is generated to the project root and is updated

61

new Guice module and the class name of the module that you want to override (property overrides), which isorg.eclipselabs.spray.generator.graphiti.GraphitiGeneratorModule.

Done!

If you deploy your plugin now (it does not work if the plugin is just in the workspace of the diagram plugin that youare developing, of course) Spray will now recognize your module and override configurations that come from itsbase implementation. Without touching Spray’s sources you are now able to customize the generator templates!

public abstract class MyDiagramFeatureProviderBase extends DefaultFeatureProvider { ... // this has been added by a derived template from org.eclipselabs.spray.generator.graphiti.extension}

Page 62: Spray User Guide - · PDF fileSpray User Guide. 2 ... (implemented with Xtext to describe Visual DSL Editors ... initial plugin.xml is generated to the project root and is updated

62

Cookbook

This chapter collects samples how to use and extend Spray based editors.

Features

Zest Layout

The ZestLayoutDiagramFeature custom feature class allows to layout the diagram with a layout algorithmfrom the Zest Visualization Toolkit.

• Add org.eclipselabs.spray.runtime.graphiti.zest to the required bundles in MANIFEST.MF• Extend the FeatureProvider class and override getCustomFeatures()

@Override public ICustomFeature[] getCustomFeatures(ICustomContext context) { List<ICustomFeature> features = new ArrayList<ICustomFeature>(Arrays.asList(super.getCustomFeatures(context)));

ZestLayoutDiagramFeature zestLayoutFeature = new ZestLayoutDiagramFeature(this); if (zestLayoutFeature.canExecute(context)) { features.add(zestLayoutFeature); } ... return Iterables.toArray(features, ICustomFeature.class); }

Your diagram will now have a context action „Layout with Zest”:

When choosing this action a selection dialog pops up that lets you select an Layout Algorithm:

Page 63: Spray User Guide - · PDF fileSpray User Guide. 2 ... (implemented with Xtext to describe Visual DSL Editors ... initial plugin.xml is generated to the project root and is updated

63

The diagram will be layouted, e.g. like this:

Page 64: Spray User Guide - · PDF fileSpray User Guide. 2 ... (implemented with Xtext to describe Visual DSL Editors ... initial plugin.xml is generated to the project root and is updated

64

Page 65: Spray User Guide - · PDF fileSpray User Guide. 2 ... (implemented with Xtext to describe Visual DSL Editors ... initial plugin.xml is generated to the project root and is updated

65

Migration Notes

As development of Spray is ongoing there are changes from time to time that won’t be visible to existing Sprayprojects. So this section lists those changes so you can decide whether to recreate the Spray project and copy thecontent of your old project into the new one or to apply the changes manually to your existing old project.

Renamed properties file

The configuration is now expected to be in a file named spray.properties. Before this properties file was nameddifferently. So please rename the old properties file in spray.properties. If you forget to do this renaming generationwill produce some unexpected results (e.g. code is generated in the last listed project in workspace instead of thecurrent project, see issue 240.

(Re-)generation of plugin.xml

In old Spray versions it was your task to copy the plugin.xml from src-gen into the project root. Projects created bythe current version of the Spray project wizard will be configured with an ANT builder that invokes the ant-update-plugin-xml.xml (also generated by the new wizard). This builder will update parts of the plugin.xml after eachchange in the project. The parts are marked by generation marker comments. To force a complete regenerationyou can delete the plugin.xml file.

Page 66: Spray User Guide - · PDF fileSpray User Guide. 2 ... (implemented with Xtext to describe Visual DSL Editors ... initial plugin.xml is generated to the project root and is updated

66

Reference

The Spray grammars

The Style grammar

Page 67: Spray User Guide - · PDF fileSpray User Guide. 2 ... (implemented with Xtext to describe Visual DSL Editors ... initial plugin.xml is generated to the project root and is updated

67

grammar org.eclipselabs.spray.styles.Style with org.eclipse.xtext.xbase.Xbase

import "http://www.eclipse.org/emf/2002/Ecore" as ecoreimport "http://www.eclipselabs.org/spray/styles/Style"

StyleContainer: styleContainerElement+=StyleContainerElement*;

StyleContainerElement: Style | Gradient;

Style: {Style} "style" name=ID ("extends" ( ('JAVA' superStyle=JvmTypeReference) | (superStyleFromDsl=[Style]) ) )? "{" ("description" "=" description=STRING)? layout=StyleLayout "}";

Gradient: {Gradient} "gradient" name=ID "{" ("description" "=" description=STRING)? layout = GradientLayout "}";

StyleLayout: {StyleLayout} ( ("transparency" "=" transparency=DOUBLE)? & ("background-color" "=" background=ColorOrGradient)? & ("gradient-orientation" "=" gradient_orientation=GradientAllignment)? & ("highlighting" highlighting=HighlightingValues)? & ("line-color" "=" lineColor=ColorWithTransparency)? & ("line-width" "=" lineWidth=INT)? & ("line-style" "=" lineStyle=LineStyle)? & ("font-name" "=" fontName=STRING)? & ("font-color" "=" fontColor=Color)? & ("font-size" "=" fontSize=INT)? & ("font-italic" "=" fontItalic=YesNoBool)? & ("font-bold" "=" fontBold=YesNoBool)? );GradientLayout: {GradientLayout} ( ("area" area+=GradientColorArea)* );

HighlightingValues: {HighlightingValues} "(" ( "selected" "=" selected=(ColorOrGradient))? ( "multiselected" "=" multiselected=(ColorOrGradient))?

Page 68: Spray User Guide - · PDF fileSpray User Guide. 2 ... (implemented with Xtext to describe Visual DSL Editors ... initial plugin.xml is generated to the project root and is updated

68

( "allowed" "=" allowed=(ColorOrGradient))? ( "unallowed" "=" unallowed=(ColorOrGradient))? ")";

GradientColorArea: {GradientColorArea}"(" "color" "=" color=Color "," "offset" "=" offset=DOUBLE ")"+;ColorOrGradient: Color | Transparent | GradientRef;ColorWithTransparency: Color | Transparent;Color: RGBColor | ColorConstantRef;RGBColor: "RGB" "(" red=INT "," green=INT "," blue=INT ")";GradientRef: {GradientRef} ( ('JAVA' gradientRef=JvmTypeReference) | (gradientRefFromDsl=[Gradient]));ColorConstantRef: value=ColorConstants;Transparent: transparent?="transparent";enum ColorConstants: WHITE="white" | LIGHT_LIGHT_GRAY="very-light-gray" | LIGHT_GRAY="light-gray" | GRAY="gray" | DARK_GRAY="dark-gray" | BLACK="black" | RED="red" | LIGHT_ORANGE="light-orange" | ORANGE="orange" | DARK_ORANGE="dark-orange" | YELLOW="yellow" | GREEN="green" | LIGHT_GREEN="light-green" | DARK_GREEN="dark-green" | CYAN="cyan" | LIGHT_BLUE="light-blue" | BLUE="blue" | DARK_BLUE="dark-blue";

enum LineStyle: SOLID="solid" | DOT="dot" | DASH="dash" | DASHDOT="dash-dot" | DASHDOTDOT="dash-dot-dot";

enum YesNoBool: YES="yes" | NO="no";

enum GradientAllignment: HORIZONTAL="horizontal" | VERTICAL="vertical";

DOUBLE returns ecore::EDouble: INT "." INT;

Page 69: Spray User Guide - · PDF fileSpray User Guide. 2 ... (implemented with Xtext to describe Visual DSL Editors ... initial plugin.xml is generated to the project root and is updated

69

The Shape grammar

Page 70: Spray User Guide - · PDF fileSpray User Guide. 2 ... (implemented with Xtext to describe Visual DSL Editors ... initial plugin.xml is generated to the project root and is updated

70

grammar org.eclipselabs.spray.shapes.Shape with org.eclipselabs.spray.styles.Styleimport 'http://www.eclipse.org/emf/2002/Ecore' as ecoreimport "http://www.eclipse.org/xtext/common/JavaVMTypes" as typesimport "http://www.eclipselabs.org/spray/styles/Style" as stylesimport 'http://www.eclipselabs.org/spray/shapes/Shape'

ShapeContainer: imports+=Import* shapeContainerElement+=ShapeContainerElement*;

Import: 'import' importedNamespace=QualifiedNameWithWildCard;

QualifiedNameWithWildCard returns ecore::EString: QualifiedName ('.' '*')?;

ShapeContainerElement: ShapeDefinition | ConnectionDefinition;

ConnectionDefinition: 'connection' name=ID (style=ShapeStyleRef)? '{' ('connection-type' connectionStyle=ConnectionStyle)? layout=ShapestyleLayout? placing+=PlacingDefinition* '}';

ShapeDefinition: 'shape' name=ID (style=ShapeStyleRef)? '{' shapeLayout=ShapeLayout shape+=Shape+ description=Description? anchor=Anchor? '}';

PlacingDefinition: 'placing' '{' 'position' '(' 'offset' '=' offset=DOUBLE ( ',' 'radius' '=' distance=INT ',' 'angle' '=' angle=INT )? ')' shapeCon=ShapeConnection '}';

Anchor: 'anchor' type=AnchorType;

AnchorType: AnchorPredefinied | AnchorManual;

AnchorPredefinied: value=AnchorPredefiniedEnum;

Page 71: Spray User Guide - · PDF fileSpray User Guide. 2 ... (implemented with Xtext to describe Visual DSL Editors ... initial plugin.xml is generated to the project root and is updated

71

AnchorManual: '{' position+=AnchorPosition+ '}';

AnchorPosition: 'position' '(' pos=AnchorPositionPos ')';

AnchorPositionPos: AnchorRelativePosition | AnchorFixPointPosition;

AnchorRelativePosition: 'xoffset' '=' xoffset=DOUBLE ',' 'yoffset' '=' yoffset=DOUBLE;

AnchorFixPointPosition: 'x' '=' xcor=INT ',' 'y' '=' ycor=INT;

Shape: Line | Polyline | Rectangle | RoundedRectangle | Polygon | Ellipse | Text;

ShapeConnection: CDLine | CDPolyline | CDRectangle | CDRoundedRectangle | CDPolygon | CDEllipse | CDText;

CDLine: {CDLine} 'line' (style=ShapeStyleRef)? ( '{' layout=LineLayout '}' );

CDPolyline: {CDPolyline} 'polyline' (style=ShapeStyleRef)? ( '{' layout=PolyLineLayout '}' );

CDRectangle: {CDRectangle} 'rectangle' (style=ShapeStyleRef)? ( '{' layout=RectangleEllipseLayout '}' );

CDRoundedRectangle: {CDRoundedRectangle} 'rounded-rectangle' (style=ShapeStyleRef)? ( '{' layout=RoundedRectangleLayout '}' );

Page 72: Spray User Guide - · PDF fileSpray User Guide. 2 ... (implemented with Xtext to describe Visual DSL Editors ... initial plugin.xml is generated to the project root and is updated

72

CDPolygon: {CDPolygon} 'polygon' (style=ShapeStyleRef)? ( '{' layout=PolyLineLayout '}' );

CDEllipse: {CDEllipse} 'ellipse' (style=ShapeStyleRef)? ( '{' layout=RectangleEllipseLayout '}' );

CDText: {CDText} texttype=TextType (style=ShapeStyleRef)? ( '{' layout=TextLayout body=TextBody '}' );

Line: {Line} 'line' (style=ShapeStyleRef)? ( '{' layout=LineLayout '}' );

Polyline: {Polyline} 'polyline' (style=ShapeStyleRef)? ( '{' layout=PolyLineLayout '}' );

Rectangle: {Rectangle} 'rectangle' (style=ShapeStyleRef)? ( '{' (compartmentInfo = CompartmentInfo)? layout=RectangleEllipseLayout shape+=Shape* '}' );

RoundedRectangle: {RoundedRectangle} 'rounded-rectangle' (style=ShapeStyleRef)? ( '{' layout=RoundedRectangleLayout

Page 73: Spray User Guide - · PDF fileSpray User Guide. 2 ... (implemented with Xtext to describe Visual DSL Editors ... initial plugin.xml is generated to the project root and is updated

73

shape+=Shape* '}' );

Polygon: {Polygon} 'polygon' (style=ShapeStyleRef)? ( '{' layout=PolyLineLayout shape+=Shape* '}' );

Ellipse: {Ellipse} 'ellipse' (style=ShapeStyleRef)? ( '{' (compartmentInfo = CompartmentInfo)? layout=RectangleEllipseLayout shape+=Shape* '}' );

Text: {Text} texttype=TextType (style=ShapeStyleRef)? ( '{' layout=TextLayout body=TextBody '}' );

CompartmentInfo:( 'compartment' '(' ( ('layout' '=' compartmentLayout = CompartmentLayout) & ( 'stretching' '(' 'horizontal' '=' stretchH=Boolean ',' 'vertical' '=' stretchV=Boolean ')' )? & ('spacing' '=' spacing = INT)? & ('margin' '=' margin = INT)? & (invisible ?= 'invisible')? & (id = TextBody )? ) ')');

enum CompartmentLayout: FIXED = 'fixed' | VERTICAL = 'vertical' | HORIZONTAL = 'horizontal';

Compartment: {Compartment} 'compartment'

Page 74: Spray User Guide - · PDF fileSpray User Guide. 2 ... (implemented with Xtext to describe Visual DSL Editors ... initial plugin.xml is generated to the project root and is updated

74

(compartmentLayout = CompartmentLayout)? shape = CompartmentShape;

CompartmentShape: CompartmentEllipse | CompartmentRectangle ;

CompartmentRectangle: {CompartmentRectangle} 'rectangle' ( '{' layout=RectangleEllipseLayout id = TextBody '}' );

CompartmentRoundedRectangle: {CompartmentRoundedRectangle} 'rounded-rectangle' ( '{' layout=RoundedRectangleLayout id = TextBody '}' );

CompartmentPolygon: {CompartmentPolygon} 'polygon' ( '{' layout=PolyLineLayout id = TextBody '}' );

CompartmentEllipse: {CompartmentEllipse} 'ellipse' ( '{' layout=RectangleEllipseLayout id = TextBody '}' );

Description: {Description} ( 'description' (style=ShapeStyleRef)? '{' ( 'align' '(' ( 'horizontal' '=' hAlign=HAlign ',' 'vertical' '=' vAlign=VAlign )? ')'

Page 75: Spray User Guide - · PDF fileSpray User Guide. 2 ... (implemented with Xtext to describe Visual DSL Editors ... initial plugin.xml is generated to the project root and is updated

75

)? body=TextBody '}');

ShapeLayout: {ShapeLayout} ( ( 'size-min' '(' 'width' '=' minwidth=INT ',' 'height' '=' minheight=INT ')' )? & ( 'size-max' '(' 'width' '=' maxwidth=INT ',' 'height' '=' maxheight=INT ')' )? & ( 'stretching' '(' 'horizontal' '=' stretchH=Boolean ',' 'vertical' '=' stretchV=Boolean ')' )? & ('proportional' '=' proportional=Boolean)?);

RectangleEllipseLayout: {RectangleEllipseLayout} ( (common=CommonLayout) & (layout=ShapestyleLayout)?);

LineLayout: {LineLayout} ( (point+=Point) (point+=Point) (layout=ShapestyleLayout)?);

PolyLineLayout: {PolyLineLayout} ( (point+=Point) (point+=Point+) (layout=ShapestyleLayout)?);

RoundedRectangleLayout: {RoundedRectangleLayout} ( (common=CommonLayout) & ('curve' '(' 'width' '=' curveWidth=INT ',' 'height' '=' curveHeight=INT ')')

Page 76: Spray User Guide - · PDF fileSpray User Guide. 2 ... (implemented with Xtext to describe Visual DSL Editors ... initial plugin.xml is generated to the project root and is updated

76

& (layout=ShapestyleLayout)?);

TextLayout: {TextLayout}( (common=CommonLayout) & ('align' '(' ( 'horizontal' '=' hAlign=HAlign ',' 'vertical' '=' vAlign=VAlign )? ')' )? & (layout=ShapestyleLayout)?);

ShapestyleLayout: {ShapestyleLayout} ( 'style' '(' layout=StyleLayout ')');

ShapeStyleRef: 'style' ( ('JAVA' javaStyle=JvmTypeReference) | (dslStyle = [styles::Style] ) );

CommonLayout: {CommonLayout} ( ( 'position' '(' 'x' '=' xcor=N_INT ',' 'y' '=' ycor=N_INT ')' )? & ( 'size' '(' 'width' '=' width=INT ',' 'height' '=' heigth=INT ')' ));

TextBody: {TextBody} "id" "=" value=ID;

Point: {Point} ( 'point' '(' 'x' '=' xcor=N_INT ',' 'y' '=' ycor=N_INT ( ',' 'curveBefore' '=' curveBefore=INT ',' 'curveAfter' '=' curveAfter=INT )?

Page 77: Spray User Guide - · PDF fileSpray User Guide. 2 ... (implemented with Xtext to describe Visual DSL Editors ... initial plugin.xml is generated to the project root and is updated

77

')');

Boolean returns ecore::EBooleanObject: 'true' | 'false';

enum HAlign: LEFT='left' | CENTER='center' | RIGHT='right';

enum VAlign: TOP='top' | MIDDLE='middle' | BOTTOM='bottom';

enum ConnectionStyle: freeform='freeform' | manhatten='manhatten';

enum AnchorPredefiniedEnum: center='center' | corners='corners';

enum TextType: default="text" | multiline="wrapped-text";

N_INT returns ecore::EInt: ('-')? INT;

Page 78: Spray User Guide - · PDF fileSpray User Guide. 2 ... (implemented with Xtext to describe Visual DSL Editors ... initial plugin.xml is generated to the project root and is updated

78

The Spray grammar

grammar org.eclipselabs.spray.xtext.Spray with org.eclipse.xtext.xbase.Xbase

import 'http://www.eclipse.org/emf/2002/Ecore' as ecoreimport "http://www.eclipse.org/xtext/common/JavaVMTypes" as typesimport "http://www.eclipselabs.org/spray/styles/Style" as stylesimport 'http://www.eclipselabs.org/spray/shapes/Shape' as shapesimport 'http://code.google.com/a/eclipselabs.org/p/spray'

Page 79: Spray User Guide - · PDF fileSpray User Guide. 2 ... (implemented with Xtext to describe Visual DSL Editors ... initial plugin.xml is generated to the project root and is updated

79

Diagram: imports+=Import* 'diagram' name=ID 'for' modelType=[ecore::EClass|QualifiedName] (style=SprayStyleRef)? (behaviourGroups += BehaviorGroup)* (metaClasses += MetaClass)*;

Import: 'import' importedNamespace=QualifiedNameWithWildCard;

QualifiedNameWithWildCard returns ecore::EString : QualifiedName ('.' '*')?;

MetaClass: 'class' type=[ecore::EClass|QualifiedName] ('alias' alias=ID)? ('icon' icon=STRING)? (style=SprayStyleRef)? '{' ( representedBy=ShapeInSpray ) ('references' '{' (references += MetaReference2 ';'?)* '}')? ('behavior' '{' (('group' behaviorGroups += [BehaviorGroup] ';'? ) | (behaviors += Behavior ';'? ))* '}')? '}';

MetaReference2 returns MetaReference: target=[ecore::EReference] ':' representedBy=ConnectionInSpray; BehaviorGroup: 'behavior' name=ID '{' (behaviors += Behavior ';'?)+ '}';

Behavior: CreateBehavior | CustomBehavior;

CreateBehavior: {CreateBehavior} 'create' ('into' containmentReference=[ecore::EReference] (label = STRING)? )? ('palette' paletteCompartment = STRING)? ('askFor' askFor=[ecore::EAttribute])?;

CustomBehavior: 'custom' (name = ID | 'ref' realizedBy=JvmTypeReference) (label = STRING);

ShapeInSpray: (ConnectionInSpray | ShapeFromDsl );

ShapeFromDsl : {ShapeFromDsl} 'shape' (

Page 80: Spray User Guide - · PDF fileSpray User Guide. 2 ... (implemented with Xtext to describe Visual DSL Editors ... initial plugin.xml is generated to the project root and is updated

80

shape = ShapeReference ) ('{' properties+=ShapePropertyAssignment* references += ShapeCompartmentAssignment* '}')?;

ShapeReference : ('JAVA' jvmShape = JvmTypeReference) | (dslShape = [shapes::ShapeDefinition]);

ConnectionReference : ('JAVA' jvmConnection = JvmTypeReference) | (dslConnection = [shapes::ConnectionDefinition]);

SprayStyleRef: 'style' ( ('JAVA' javaStyle=JvmTypeReference) | (dslStyle = [styles::Style] ) );

ShapePropertyAssignment: (attribute=[ecore::EAttribute] 'into' key = ShapeDslKey ('(' value=XExpression ')')?) | ('constant' value=XExpression 'into' key = ShapeDslKey);

ShapeDslKey : ( 'JAVA' jvmKey=[types::JvmEnumerationLiteral|QualifiedName] ) | ( dslKey = ID ) ;ShapeCompartmentAssignment: 'reference' reference=[ecore::EReference] 'into' shapeDslKey = ShapeDslKey ('(' value=XExpression ')')?;

ConnectionInSpray returns ConnectionInSpray : {ConnectionInSpray} 'connection' (connection = ConnectionReference ( '{' properties+=ShapePropertyAssignment+ '}')? )? ('alias' alias=ID)? ( '{' 'from' from=[ecore::EReference] ';'? 'to' to =[ecore::EReference] ';'? '}'

Page 81: Spray User Guide - · PDF fileSpray User Guide. 2 ... (implemented with Xtext to describe Visual DSL Editors ... initial plugin.xml is generated to the project root and is updated

81

)?;