spray user guide
DESCRIPTION
user guideTRANSCRIPT
Spray User Guide
2
Spray – A quick way of creating Graphiti
User Guide
Authors: Jos Warmer, Karsten Thoms, Joerg Reichert
Contents
1. Spray - A quick way of creating Graphiti2. Introduction3. Installation
1. Install Spray2. Upgrade from CI build to release3. Uninstalling Spray
4. Getting Started1. 5-Minutes Tutorial
1. Create a new project2. Define Spray Model3. Test the editor
2. 15-Minutes Tutorial1. Implement a custom behavior
5. Spray DSL1. A Spray based example language2. Diagram
1. Imports2. Diagram3. Referencing Ecore Classes4. Ecore models the development workspace5. Create Behavior6. Class Icon Following the referenced EClass name an icon representing the class can be defined with the
@icon@ keyword. The path to the icon is quoted as a string.3. Layout
1. Colors4. Shapes
1. Container2. Text3. Line
6. Style DSL Guide1. An example for a style2. Style Key Facts3. Default Values4. Style Elements
1. Description2. Transparency
3
3. Background4. Line5. Font
7. Shape DSL Guide1. An example for a shape2. Shape Key Facts3. Shape Visualisation4. Shape Elements
1. Anchor5. Shape Default Values
1. Text2. Line3. Polyline4. 2D Shape5. Ellipse6. Rectangle7. RoundedRectangle8. Polygon
6. Practise Examples1. UML - Example2. BPMN - Example
7. Connections1. Placing2. ConnectionType
8. Spray Extensions Guide1. Basic extensions: Generation Gap Pattern
9. Cookbook1. Features
1. Zest Layout2. The Spray Grammar
4
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.
This project aims to provide one or more Domain Specific Languages (DSL) (for example with Xtext) to describeVisual DSL Editors against the Graphiti runtime, and provide code generation (for example with Xtend2) to createthe boilerplate code for realizing the implementation against the Graphiti framework. Potentially the Spray DSL canbe used to generate code for other frameworks as well.
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.
With the help of the tools created in this project 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.
5
Installation
Install Spray
A very short introduction on how to install spray.
• Install Eclipse Indigo IDE. Eclipse Classic or Eclipse Modeling Tools are appropriate Eclipse packages.• Start a new workspace• Open Help / Install New Software• 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-ci-build/lastSuccessfulBuild/artifact/
releng/org.eclipselabs.spray.repository/target/repository/• Check Spray / Spray SDK Feature
6
• 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 3.7.1 to be installed.
• Start installing the features• Restart Eclipse when asked
Upgrade from CI build to release
For release versions, the additional timestamp qualifier is removed from the feature and plugin version strings. Thisway it is clear whether you have installed a release or integration build version of Spray.
Unfortunately Eclipse recognizes the release version to be older than integration build versions. As aconsequence, if you want to upgrade from a CI build to the release build of the same version prefix (e.g. CI version0.3.0.201111010020 to release 0.3.0), you need to uninstall the Spray SDK before installing the feature again fromthe Spray Release repository.
Uninstalling Spray
Spray can be uninstalled in Eclipse by choosing Eclipse / About Eclipse SDK / Installation Details. Select the SpraySDK Feature und press uninstall.
7
8
Getting Started
5-Minutes Tutorial
Create a new project
• Create a new Spray project by using the Spray Project Wizard. Open File / New / Project / Spray / SprayProject.
• 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 Registered Packages
button to see the EPackages registered in your platform. Choose http://www.mod4j.org/busmod
9
• Spray requires that it can find the corresponding genmodel for the EPackage. If it can be found in the registry itwill be added automatically.
10
• 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.
11
Define Spray Model
After finishing the project wizard the Spray model editor opens. Paste this model into file busmod.spray:
diagram busmod
import BusinessDomainDsl.*
class BusinessClass: container ( fill=RGB(217,228,255) ) { text ( ) { "<<"+eClass.name+">> " + name}; line ( color=black width=2); reference properties attribute dataType; line (width=1 color=blue); reference businessRules; // will use name property by default
12
line (width=1 color=blue); text () "::" + description; } references { superclass : connection(); } behavior { create palette "Shapes"; } class Association: connection () { from source; to target; toText text() targetMultiplicity.name; } behavior { create palette "Connections" ; }
After saving the model the editor sources will be automatically generated to the src-gen folder of the project.
Replace the plugin.xml in the project root with the plugin.xml from src-gen.
Test the editor
• Start a Runtime Eclipse instance with Run As / Eclipse Application. A new Eclipse instance starts with theplugins deployed.
13
• 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"
14
• Your new diagram editor opens!
15-Minutes Tutorial
In this section we will extend the example from the 5-Minutes Tutorial further. Follow the steps mentioned abovefirst.
Implement a custom behavior
Extend the busmod.spray model like this:
class BusinessClass:
15
... behavior { create palette "Shapes"; // add custom behavior showInfoForBusinessClass "Show Information"; } ...
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 and opens in theeditor.
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.
16
17
Spray DSL
A Spray based example language
import BusinessDomainDsl.*import org.eclipse.graphiti.util.IColorConstant
diagram mod4j for BusinessDomainModel
behavior samen { doit "Do it"} class BusinessClass { container ( fill=dark_green ) { text ( ) { "<<"+eClass.name+">> " + name} line ( color=black width=2) reference properties attribute dataType line (width=2 color=RGB(255,138,141)) reference businessRules // will use name property by default line (width=2 color=IColorConstant::DARK_BLUE) // attribute description text () "::" + description line (width=1 ) } references { superclass : connection() } behavior { create into types palette "Shapes" doWithBusinessClass "Do It With" group samen }} class Association (icon "connection16.gif") { connection () { from source to target fromText text() "source " + source.name connectionText text() targetMultiplicity.name toText text() name } behavior { create into associations palette "Connections" group samen }}
18
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.*import org.eclipse.graphiti.util.IColorConstant// 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 a containment reference of the model root type.
import BusinessDomainDsl.*
diagram mod4j for BusinessDomainModel
h2. 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.
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:
19
Ecore models the development workspace
In the likely case that you want to use a metamodel whose .ecore file is in the development workspace, it isnecessary that Xtext indexes the Ecore file and its content. To enable indexing of Ecore files from the workspace,the project containing the .ecore file must have the Xtext nature enabled. If it does not have it yet (the project wouldhave an „X” overlay image), you can configure the nature by right-clicking on the project and choose Configure /Add Xtext Nature.
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 thecontaining 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: container () { ... } 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 definedwith the icon keyword. The path to the icon is quoted as a string.
class BusinessClass icon "ecore/EClass.gif"
20
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.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 inorg.eclipse.graphiti.util.IColorConstant as simple names with lower case. For example,IColorConstant::DARK_GREEN will be available as dark_green.
Example:
text (color=dark_green)
Explicit Colors Colors can be referred to by qualified names of the static fields.
Example:
21
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.
Shapes
Container
A Container Shape is a container for other shapes.
Text
A shape that displays a computed text.
text [alias <aliasname>] ([layout]) <expression>;
The displayed text is an Xbase expression, in the simplest case a static string.
text () "Foo";
text () "element "+this.name;
22
Line
Displays a line.
line (); // width 1 pixel, black line (width=2); line (color=blue width=2);
h3. Alias names
Each shape allows to specify an alias name. The alias name is reflected in generated code and will be used forvariable and method names when referring to a specific shape. If not specified, the shape name will be computedfrom the containment hierarchy and types of used shapes.
class MyEClass : container alias rootContainer () { line alias line1 (); }
23
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 be finally mapped with a name. Afterwards the styles can be referenced with their name. The referencewill be possible in one hand globally for the whole spray project and can be overwritten in the other hand from aclass, a shape and/or a shape element (as ellipse, rectangle, ...). If the style will not be referenced at all the defaultspray style will be taken. The style helps to generate a nice graphiti editor for a given color schema and supports toadjust all element styles as your own necessity.
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}
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);
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.
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
24
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
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.
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 = white
25
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. Finally if a transparent background is wanted then the value transparent canbe 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.
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.
26
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 graphiti the graphiti framework. If a more complexfigure is needed basic forms can be nested together.
An example for a shape
shape Usecase (java.lang.String textline) style org.eclipselabs.spray.styles.NoTransparency { size-min(width=100, height=100) size-max(width=200, height=200) stretching(horizontal=true, vertical=true) proportional=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) "Paul" } }}
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 ever defined shape a Java class will be generated. The interface ISprayShape provide one methodwhich will be define for every class.
public ContainerShape getShape(Diagram diagram);
The implemented method getShape returns a ContainerShape(org.eclipse.graphiti.mm.pictograms.ContainerShape) this container comprised all elements of thedefined figure/shape.
Shape Visualisation
shape Usecase style BlackAndWhiteStyle
Every shape definition can reference a custom style for their visual behavior. The style will be inherited to thenested shape elements. If a custom style on a nested shape is needed a separate style can be referenced too.
shape Usecase style BlackAndWhiteStyle {
27
ellipse { style(background-color=blue line-color=red) } }
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 level for their visualisation. The brackets „{ }” represents a separator for eachlevel of a figure.
shape Usecase { ellipse {} }
If elements are at the same level like a ellipse and a text there will be defined among each other, so shapes can bemultiple nested.
shape Usecase { ellipse {} text {} }
Every figure got the attributes size-min, size-max, stretching and proportional that can be set for eachdefinition. 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 got anattribute for horizinal and vertical stretching of the figure. proportional handles if the resize proportionbetween height and width is kept or not.
shape Usecase (java.lang.String textline) { size-min(width=100, height=100) size-max(width=200, height=200) stretching(horizontal=true, vertical=true) proportional=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) }
This example defines a fixed anchor, where the coordinates for the position are with a fixed value.
28
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
proportional boolean yes or no false (no)
stretching - vertical boolean yes or no true (yes)
stretching - horizontal boolean yes or no true (yes)
size-min - width integer >= 0 ???
size-max - width integer >= 0 ???
size-min - height integer >= 0 ???
size-max - height integer >= 0 ???
textfieldalign - horizontal boolean yes or no false (no)
align - vertical boolean yes or no true (yes)
(textvalue) String - ""
line/polyline/polygonpoint - x integer >= 0 0
point - y integer >= 0 0
2d shapessize - width integer >= 0 0
size - height integer >= 0 0
position - x integer >= 0 0
position - y integer >= 0 0
RoundedRectanglcurve - width integer >= 0 0
curve - height integer >= 0 0
Text
The keyword text represents a shape element which
text {
A text field has one obligatory and one optional attribute. The first attribute is the alignment(align) separatedin horizontal and vertical. For both values are enumeration values referenced. The First value can beleft,right or center and the second one top, middle or bottom. The optional attribute can set the "text"value of the shape.
text { align(horizontal=center,vertical=bottom) "text"
Line
The keyword line represents a line shape element
line {
29
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)
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)
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)
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)
RoundedRectangle
The keyword roundedrectangle represents a roundedrectangle shape element
roundedrectangle {
The roundedrectangle definition is similar to the rectangle definition. There is just one optional attribute namedcurve which set the curve of the corners
30
roundedrectangle { size(width=100, height=100) position(x=0,y=0) curve(width=30, height=30
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 { size(width=100, height=100) position(x=0,y=0) point(x=50,y=0) point(x=50,y=10) point(x=60,y=10) }
Practise Examples
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 { 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 and
31
25 (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 polyline {point(x=0,y=150) point(x=25,y=100) point(x=50,y=150)} // Feet}
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) } } }}
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,distance=0,angle=0,active=false) polygon { point(x=-10,y=10) point(x=0,y=0) point(x=-10,y=-10) style(background-color=black) } } placing {
32
position(offset=0.05,distance=0,angle=0,active=false) 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,distance=0,angle=0,active=false)
A position attribute got four diffrent values offset, distance, angle and active. The offset is the positionvalue among the line from left(offset=0.0) to right(offset=1.0), the distance is the gap with a specifiedangle between the connection and the element which is placed. The angle can be specified in degree from 0to 360. Imagine a circle with 4 quadrants, then the first quadrant is from 0 to 90 degree, the second is from 90 to180 and so on. The last value of the position is the active which is a boolean value. If the active is true theplacing element can be move belatedly, if not the position is fixed.
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.
33
Spray Extensions Guide
Basic extensions: Generation Gap Pattern
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:
34
Now choose from the context menu Spray / Move to source folder for manual extension:
35
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 removed it. With thenext generator run it will appear again in the src-gen/ folder.
36
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:
37
The diagram will be layouted, e.g. like this:
38
h1. Reference
39
The Spray Grammar
40
grammar org.eclipselabs.spray.xtext.Spray with org.eclipse.xtext.xbase.Xbase
import "platform:/resource/org.eclipselabs.spray.mm/model/spray.ecore" import "http://www.eclipse.org/emf/2002/Ecore" as ecoreimport "platform:/resource/org.eclipse.xtext.common.types/model/JavaVMTypes.ecore" as types
Diagram : 'diagram' name = ID imports+=Import* ( behaviourGroups += BehaviourGroup )* ( metaClasses += MetaClass )* ;
Import: 'import' importedNamespace=QualifiedNameWithWildCard;
SprayElement : Shape | MetaReferenceAsShape | MetaAttributeAsShape;
MetaClass : 'class' type=[ecore::EClass|QualifiedName] ('alias' alias=ID)? ('icon' icon=STRING)? ":" representedBy=Shape ( "references" "[" (references += MetaReference2 ";")* "]" )? ( "behavior" "[" ( ("group" behaviourGroups += [BehaviourGroup] ";" ) | (behaviours += Behaviour ";" ) )* "]" )? ;
MetaReference : "reference" reference=[ecore::EReference] ":" representedBy=Connection ;
MetaReference2 returns MetaReference: reference=[ecore::EReference] ":" representedBy=Connection
41
;
MetaAttribute : (pathsegments+=[ecore::EReference] '.')* attribute=[ecore::EAttribute];
MetaReferenceAsShape returns MetaReference : 'reference' reference=[ecore::EReference] ("attribute" labelProperty = [ecore::EAttribute] )? ; MetaAttributeAsShape returns MetaAttribute : 'attribute' attribute=[ecore::EAttribute];
BehaviourGroup: "behaviour" name=ID "[" (behaviours += Behaviour ";")+ "]";
Behaviour : StandardBehaviour | CustomBehaviour;
StandardBehaviour : type=BehaviourType (label = STRING)? ('palette' paletteCompartment = STRING)?;
CustomBehaviour : name = ID (label = STRING); enum BehaviourType : CREATE_BEHAVIOUR = 'create' ; Shape : (Rectangle | Text | Container | Connection | Line) ;
Layout : { Layout } '(' ( ( 'width' '=' lineWidth = INT )? & ( 'color' '=' lineColor = Color)? & ( 'fill' '=' fillColor = Color)? & ( 'figure' '=' figure = STRING)? & ( bold ?= 'bold' )? & ( italic ?= 'italic' )? ) ')'
;
EString returns ecore::EString: STRING | ID;
42
Rectangle returns Rectangle: {Rectangle} "rectangle" layout = Layout // name=EString;
Connection returns Connection : {Connection} 'connection' layout = Layout ( '[' 'from' from=[ecore::EReference] ";" 'to' to =[ecore::EReference] ";" ( ('fromText' fromLabel = Text ";")? & ('connectionText' connectionLabel = Text ";")? & ('toText' toLabel = Text ";")? ) ']' )?;
Color: ColorConstantRef | RGBColor;ColorConstantRef: (type=JvmTypeReference '::')? field=[types::JvmField|ValidID];
RGBColor: 'RGB' '(' red=INT ',' green=INT ',' blue=INT ')';
Text returns Text: {Text} 'text' layout = Layout value = XExpression ;
QualifiedNameWithWildCard returns ecore::EString : QualifiedName ('.' '*')?; Line returns Line : {Line} 'line' layout = Layout;
Container returns Container: { Container } 'container' layout = Layout '[' (parts+=SprayElement ";" )* ']';
43
StaticFieldQualifier: QualifiedName '::' ValidID;