Important
|
|
This 3 hours tutorial on Eclipse Sirius Web has been designed for EclipseCon 2023.
You can also do it by yourself by following the steps below.
By the end of this tutorial, you should be able to create your own Sirius Web-based application with your own business domain and diagrams, ready to run and/or deploy on a server.
The structure of the tutorial is as follows:
-
if you have not done so already beforehand, you will need to install the required development tools and the sample application we prepared.
-
after a short general presentation of Sirius Web, you will launch the sample application on your machine, and experiment as an end-user the example studio it provides.
-
then you will switch to the studio maker role, and learn how to use Sirius Web to define your own studio directly from your browser. This is the main part of the tutorial where we will spend the most time.
-
finally you will see how more advanced features and use cases can be implemented by extending the Java-based backend.
There will be 2 10-minutes coffee/tea breaks.
Note
|
In this section you will:
|
Important
|
|
First, download the Spring Tools 4 for Eclipse specially designed for this tutorial. Choose the bundle according to your OS:
-
Windows x86_64: download Windows bundle on Obeo Network
-
Linux x86_64: download Linux bundle on Obeo Network
-
macOS x86_64/arm_64: download macOS bundle on Obeo Network
It contains an embedded Java Runtime Environment, Maven and all the maven dependencies you will need for this tutorial.
Once unzipped, just launch it:
-
Windows: run script
run.ps1
(run with PowerShell)
Before executing the .ps1
script, please execute your PowerShell with administrator rights and run the following command: Set-ExecutionPolicy Unrestricted
.
-
Linux: run script
run.sh
(run with your favorite terminal) -
macOS: run script
run.ksh
(run with your favorite terminal)
The run
shell script allows to configure the Spring Tools 4 for Eclipse to the maven local repository contained in the bundle and then launch it.
Once launched, you need to clone (Clone repository) or add (Add existing repository) the git repository (Sirius-Web-Tutorial) of the tutorial.
The repository contains:
-
the source code of the sample application we will be using;
-
the complete script of the tutorial itself;
-
snapshots of the expected result at the end of each section in case you get stuck.
If you don’t have already cloned the Sirius-Web-Tutorial git repository on your machine before, you just have to clone it from your Eclipse environment (If you already have, please go to Add existing repository section).
For that, please go to Window > Perspective > Open Perspective > Other… menu and then select Git. From the Git perspective, in the Git Repositories view, click on Clone a Git repository button:
Then, add https://github.com/ObeoNetwork/Sirius-Web-Tutorial
in the URI
field, and click on Next > button:
Then, click on Next > button:
Then, choose the local folder that will contain the git repository and click on Finish button:
Go to Import & run sample application section for the next step.
If you have already cloned the Sirius-Web-Tutorial git repository on your machine before, you just have to add it to your Eclipse environment.
For that, please go to Window > Perspective > Open Perspective > Other… menu and then select Git. From the Git perspective, in the Git Repositories view, click on Add an existing local Git repository button:
Browse on your OS the git repository of the tutorial. Select it and click on Add.
Now, you should see the git repository (Sirius-Web-Tutorial
) on the Git Repositories view.
Now you git repository is visible from your Eclipse environment, import the only project (sirius-web-family-application
) contained in the local git repository.
Just right-click on the Sirius-Web-Tutorial
repository in the Git Repositories view, then click on Import Projects… menu.
Now your project has been imported, please do a "Maven update" on it. Just right-click on your project and click on Maven > Update Project… menu item.
Then, check the Force Update of Snapshots/Releases and uncheck the Update project configuration from pom.xml checkboxes. Click on OK.
The last step is to create an Eclipse launch configuration to run our Sirius Web application. Go to Run > Run Configurations… menu and then double-click on Spring Boot App. Set the name, project, and main type as below:
Click on Run. Your Sirius Web application is ready!
You should see the Spring Tools Suite console display the following text (starting with Sirius Web Tutorial ASCII art):
Go to http://localhost:8080 on your favorite web browser for the next part of the tutorial!
Please check in the Spring Tools Suite console you don’t have any error message. In particular, please check that your console does not look like this (console text starting with Spring ASCII art):
In this case, please do a "Maven update" of your project. Just right-click on your project and click on Maven > Update Project… menu item.
Then, check the Force Update of Snapshots/Releases and uncheck the Update project configuration from pom.xml checkboxes. Click on OK.
Then retry to launch your Eclipse launch configuration.
-
You may encounter issues (e.g. very long time to unzip, path too long error) while unzipping the bundle. Please do not use native zip software (prefer 7-zip or other).
-
Before executing the
.ps1
script, please execute your PowerShell with administrator rights and run the following command:Set-ExecutionPolicy Unrestricted
.
Important
|
|
Sirius Web allows to easily create and deploy graphical studios to the web.
It is an open-source low-code platform to define custom web applications supporting your specific visual languages.
For more details and contents (videos, online documentation, private instance to experiment all Sirius Web’s features), please visit the Sirius Web website.
For more details about the source code, please visit the Sirius Web github repository.
Note
|
In this section you will use the studio already configured in the application to create sample data and manipulate it through a diagram representation. |
Important
|
|
The sample application provided comes with a studio to model data flows between parts of an electronic system. Your goal is to create a simple instance of this model and visualize/edit it through the (provided) graphical representation. You should obtain something like this:
You will need to create a project to store your data, create the model, edit it, and create a diagram on it to visualize and further edit the model.
The home page of Sirius Web shows the list of project templates (Blank Studio, Flow, Studio, Blank project, …) and the list of already existing projects.
Create a Flow project by clicking on the Flow card. You should now see the dedicated project page:
Flow contains an example model and a diagram representation based on the already packaged Flow metamodel.
The Explorer view allows to see all the models contained in your project. From this view, you can create, edit and delete models, objects and representations.
To create an object, just select any object or model, and click on the menu icon associated (the three vertical dots), then click on the New object menu item.
Select the type of model object you want to create and click on the CREATE button.
The new object is visible in the Explorer view.
To rename an object, select it in the explorer, and click on the menu icon associated (the three vertical dots), then click on the Rename menu item.
The selected tree item is now editable, you can set a new value.
The Details view on the right shows all properties of the currently selected object.
It is updated from the selection in the Explorer view or the active representation (diagram, form, …).
From there, you can edit each property of the selected object. Changes are applied immediately.
The representations area shows all open representations (diagrams, forms, …).
To create a representation, select any object in the Explorer view, and click on the menu icon associated (the three vertical dots), then click on the New representation menu item.
Select the representation type you want to create, set a name and click on the CREATE button.
Note
|
Not all representations are available on every type of element. |
The new representation is visible in the Explorer view and automatically open in the representations area.
In this part of the tutorial, we are manipulating a diagram, which is one kind of representation.
To create objects inside a diagram, click on the diagram background, or any other object from the diagram. A palette will show the available tools from this place.
Click on the type of object you want to create.
To delete an object from the diagram, select it and the choose the Delete tool on the palette (represented by the trashcan icon).
To rename an object from the diagram just select it. A palette will show the available tools from this place. Then you just have to click on the Edit tool (the pen icon).
The selected object’s label is now editable, you can set a new value.
You can also just start typing the new value after the selection of the object, it will move to the editable mode.
If you have finished the steps above before the time and you feel confortable enough, you can try the following bonus exercise (no solution given) or experiment yourself.
Exercise: Create a separate project, and try to reproduce the following diagram and model structure:
Hints:
-
on this screenshot, the Back_Camera element is an instance of the DataSource type;
-
it gets its special icon representing a camera because it’s name contains the string "camera";
-
see if you can find out how to create edges by yourself.
-
to go back to the homepage, click on the Sirius icon located in the top left.
Note
|
For the rest of the tutorial you will switch roles from end-user of an already existing studio to studio maker to create your own. The first step is to tell Sirius Web about the structure of the business domain for your studio, which is the goal of this section. We’ll see how to configure graphical representations (e.g. diagrams) specifically designed for this domain in the next one. |
Important
|
|
In Sirius Web, one of the key features is the ability to define your own domain and the associated representations (e.g. diagrams) to view and edit it. Together, the domain and accompanying representations are called a studio.
As a studio maker you will create your studio definition entirely through the web browser, using the same UI as you used in the previous part of the tutorial.
Once your studio has been defined, it can be used by other users, who can:
-
create concrete instances of the concepts described in the new domains;
-
visualize and manipulate these instances through the representations defined in the studio.
In this part of the tutorial, as a studio maker, we will create a new studio, and then use is as an end-user.
In Sirius Web, a Domain is composed with Entities and Relations objects. An Entity may have Attributes, Entities and Relations. A Relation is a connection between two Entities. An Attribute is either a Text, Boolean or a Number.
In this section, your goal is to create a very simple Family domain with the following structure:
To Sirius, a domain is a model (almost) like any other, so you will be using the same mechanisms as above when creating the Flow example.
Note
|
If you do not want to specify yourself a new domain, you can upload the files we prepared:
|
First, from the home page, click on the Blank Studio template.
Important
|
Make sure to create a Blank Studio and not a plain Blank Project. |
Then, create a Domain model, in the Create a new model section.
It creates a new document named Domain containing an object named Domain. It will initially have a randomly chosen name. Using the Details view, rename this object from Domain to tutorial.
Then, create a Domain diagram on this tutorial domain object. While not strictly necessary, it will make it easier to create and modify our domain specific language than using just the Explorer and Details views. To create this diagram, select the tutorial object in the Explorer view, and click on the menu icon associated (the three vertical dots), then click on the New representation menu item.
Select the representation type you want to create (Domain), set a name and click on the CREATE button.
The new representation is visible in the Explorer view and automatically open in the representations area. It will be empty initially, as our new domain does not currently define any concept.
Let’s create the concepts we will manipulate later.
From the diagram background, create an Entity named Family and another named Person.
Let’s link our two Entities with a Relation.
From the Family object, click on the Connector tool (the first one in the Palette), and then click on the Person object.
Three options are displayed on the screen, Relation, Containment and Supertype. Select Containment option. Indeed, a Family will contains a set of Person.
You should now see a Relation between the Entities.
In the Details view, just rename the link form persons to members.
Almost done! We finish this first specification part by adding a name attribute to Family and Person.
In the diagram, click on the Family object and select the Text attribute tool.
Set its name to name. Do the same for Person. You should now have a domain looking like this:
Just one last thing! You can go back to the home page (through the Sirius icon on the top left corner) and then rename your project from Blank Studio to Family-Studio. Click on the menu icon associated (the three horizontal dots) to Blank Studio, then click on the Rename menu item.
To test our studio, we need to create a new project with instances of the concepts we defined.
Note
|
If you do not want to create the domain instance yourself, you can upload the files we prepared.
. Go back to the main page with the projects list (you can click on the Sirius logo in the top-left).
. Click on the "Upload project" card.
. Click on the "Click here to select a file" link, then select the Note that this requires that the corresponding domain has been correctly defined as above. |
From the home page, click on the Blank project template.
Name this new project Family-Instance.
Then, create an Others… model, in the Create a new model section.
From this new Others… model, click on the menu icon associated (the three vertical dots), then click on the New object menu item.
Make sure the Domain selected is the one we defined above, domain://tutorial
.
Select the type of model object you want to create (here a Family) and click on the CREATE button.
Name the Family (from the Details view or with the Rename menu item). Then, create one or two Person and rename them.
Select the type of model object you want to create (here a Person) and click on the CREATE button.
Your instance model should look like this:
Note
|
We now have defined our custom domain, however simple (the basic structure of a Family). We can create and edit concrete instances (the concrete family), but currently only through the Explorer view (the instance’s structure) and Details (the properties of each specific element). The power of Sirius Web is that for each domain you (as a studio maker) can define custom representations (typically diagrams or forms, but it can be almost anything) adapted to the domain for end-users. In this section you will create a simple diagram representation for families. |
Now we have a domain, we want to be able to manipulate it graphically. In the Studio, this part is called View. A View allows to define the description of representations (diagrams, forms, …). A Diagram Description contains a set of Node Descriptions and Edges Descriptions. A Node Description contains the information needed to display an Entity on a diagram. An Edge Description contains the information needed to display a Relation (or an Entity) on a diagram.
Note
|
If you do not want to specify yourself a new view, please upload in Sirius Web the projects we already prepared (see the previous sections for how to upload a project from a zip).
|
First, create a View model, in the Create a new model section.
It creates a new document named View containing a view named View, and a diagram description named New Diagram Description and a Color Palette with some predefined colors.
From the Details view:
-
Rename this object from New Diagram Description to Family Diagram Description.
-
Set the domain type (the type of object on which we want to create this type of diagram) to
tutorial::Family
. -
Set the Title Expression to
Family Representation
.
This is enough to be able to create diagrams on Family instances, but they would be blank. Let’s tell Sirius Web what kind of elements (nodes) to display on these diagrams.
From the Family Diagram Description, create a new Node Description by clicking on the menu icon associated (the three vertical dots), then click on the New object menu item.
Select the Node Description object type and click on the CREATE button.
A new Node Description is visible in the Explorer view.
After selecting the Node Description in the Explorer view, let’s change its properties in the Details view:
-
Set the name to Person Node
-
Set the domain type to
tutorial::Person
: each of these nodes will represent an instance of the Person type. -
Set the semantic candidates expression to
aql:self.members
: we want to get one node for each member of the family. -
Set the label expression to
aql:self.name
: the node will display the name of the Person it represents.
Note
|
if you want more details about the meaning of all elements and properties of the Studio, please go to https://docs.obeostudio.com/ |
Note
|
if you want more details about AQL, the model query language, please go to https://eclipse.dev/acceleo/documentation/ |
Inside this Color Palette (available int he Explorer just below the View element), let’s create 3 custom colors:
-
person_background_color with value
#f7e6f0
-
person_border_color with value
#242055
-
person_label_color with value
#242055
From the Color Palette object, create a new Color by clicking on the menu icon associated (the three vertical dots), then click on the New object menu item.
Select the Fixed Color object type and click on the CREATE button.
The colors have been created. Let’s use those colors for the Person Node object. In the Explorer view, click on the RectangularNodeStyleDescription under the Person Node object. Set its properties:
-
Width Expression to
100
-
Width Expression to
70
-
Label Color to
person_label_color
-
Color to
person_background_color
-
Border Color to
person_border_color
Finally, let’s create a tool allowing to create a Person inside the diagram. For this we need to setup the palette of tools that will be displayed when the user clicks on the diagram’s background.
From the Family Diagram Description object, create a new Palette by clicking on the menu icon associated (the three vertical dots), then click on the New object menu item.
Select the Palette object type and click on the CREATE button.
From the the DiagramPalette object, create a new Node Tool by clicking on the menu icon associated (the three vertical dots), then click on the New object menu item.
Select the Node Tool object type and click on the CREATE button.
From the Details view, rename this Node Tool to Person.
From the the Node Tool object, create a new Create Instance by clicking on the menu icon associated (the three vertical dots), then click on the New object menu item.
Select the Create Instance object type and click on the CREATE button.
From the Details view, set the properties of the Create Instance object:
-
Type Name to
tutorial::Person
-
Reference Name to
members
-
Variable Name to
newPerson
At this stage, our creation tool should work. But would it be better if a new Person created from this tool was created with a default name? Let’s do that.
From the the Create Instance object, create a new Change Context by clicking on the menu icon associated (the three vertical dots), then click on the New object menu item.
Select the Change Context object type and click on the CREATE button.
From the Details view, set the properties of the Change Context object:
-
Expression to
aql:newPerson
From the the Change Context object, create a new Set Value by clicking on the menu icon associated (the three vertical dots), then click on the New object menu item.
Select the Set Value object type and click on the CREATE button.
From the Details view, set the properties of the Set Value object:
-
Feature Name to
name
-
Value Expression to
new Person
Now test this second part as an end-user!
From the home page, click on the Family-Instance project.
From the Explorer view, select your Family object and create a new Family Diagram Description by clicking on the menu icon associated (the three vertical dots), then click on the New representation menu item.
Select the representation type you want to create (a Family Diagram Description), set a name and click on the CREATE button.
The new representation is visible in the Explorer view and automatically open in the representations area.
Click on the background of the diagram, then click on the Person tool.
There you go! The new Person is visible in the diagram and the Explorer view.
If you have finished the steps above before the time and you feel confortable enough, you can try the following bonus exercice (no solution given) or experiment yourself:
-
Update the diagram definition to display the full names of the persons (e.g. "Gomez Adams" instead of just "Gomez"). Hint: The reference documentation for AQL, which is used for computed expressions, is here.
In this third part of the experiment, we will add a new Relation named children to our Family domain and also display it graphically in the associated View.
Note
|
If you don’t want to specify yourself this part, please upload in Sirius Web the projects we already prepared (see the previous sections for how to upload a project from a zip).
|
From the home page, click on the Family-Studio project. In the Family-Studio project, open the Domain diagram. Then in the diagram, click on the Person object, select the Connector tool (the first one). Click on the Person again (indeed the children will start from a Person an will target others Persons) and select Relation (the first choice in the list).
Select this new Relation to children and set its properties:
-
Name to
children
-
Optional to
true
-
Many to
true
-
Containment to
false
-
Target Type to
Entity Person
Then, in the View model, from the Family Diagram Description object, create an Edge Description and set its properties:
-
Name to
Children Edge
-
Domain Type to
tutorial::Person
-
Semantic Candidates Expression to empty value
-
Precondition Expression to empty value
-
Synchronization Policy to
SYNCHRONIZED
-
Label Expression to empty value
-
Begin Label Expression to empty value
-
End Label Expression to empty value
-
Is Domain Based Edge to
false
-
Source Node Descriptions to
Person Node
-
Target Node Descriptions to
Person Node
-
Source Node Expression to
aql:self
-
Target Node Expression to
aql:self.children
You can also set the color of the edge by clicking on the EdgeStyle object inside the Children Edge object.
Then change the Color properties in the Details view to person_border_color
.
From the home page, click on the Family-Instance project.
From the Explorer view, open your Family Representation diagram.
Then click on a Person in the diagram. In the Details view you should see a new property named Children. From this property, set the Persons you want as children of the selected Person.
You should see your diagram updated instantaneously with new edges:
In this fourth part of the experiment, we will create sub-types to Person (StarWarsFan and StarTrekFan), and add a new Conditional Styles to our Person Node in the View.
Note
|
If you don’t want to specify yourself this part, please upload in Sirius Web the projects we already prepared (see the previous sections for how to upload a project from a zip).
|
From the home page, click on the Family-Studio project. In the Family-Studio project, open the Domain diagram. Then in the diagram, click on the diagram background, select the Entity tool (the first one). Name this Entity: StarTrekFan and do the same for StarWarsFan.
Select the StarTrekFan Entity and from the Details view, select Person as Super Types. Do the same for StarWarsFan. Finally, make Person abstract from the Details view.
Your domain should look like this:
Lets' add some Conditional styles to our View.
From the the Person Node object, create a new Conditional Node Style by clicking on the menu icon associated (the three vertical dots), then click on the New object menu item.
Select the Conditional Node Style object type and click on the CREATE button.
Select this new Conditional Node Style and set its properties:
-
Condition to
aql:self.oclIsKindOf(tutorial::StarTrekFan)
From the the Conditional Node Style object, create a new Image Node Style Description by clicking on the menu icon associated (the three vertical dots), then click on the New object menu item.
Select the Image Node Style Description object type and click on the CREATE button.
Select this new Image Node Style Description and set its properties:
-
Shape to
star-trek-1
orstar-trek-2
-
Width Expression to
70
-
Height Expression to
70
-
Show Icon to
false
-
Label Color to
person_label_color
-
Border Radius to
3
-
Border Size to
0
Now add a new Conditional Node Style but this time for StarWarsFan.
Finally, update the DiagramPalette: add new creation tools for StarTrekFan and StarWarsFan. It is the same than the existing creation tool for Person but with adapted values. After that, you can remove the Person creation tool cause it is now useless. Indeed, Person is now an abstract Entity and cannot be instantiated anymore.
At the end, your View should look like this:
Warning
|
The evolution we have made to our domain makes the existing model in Family-Instance obsolete. You must delete the Family-Instance project from the home page. |
From the home page, click on the Blank project template.
Name this new project Family-Instance.
Then, create an Others… model, in the Create a new model section.
From this new Others… model, click on the menu icon associated (the three vertical dots), then click on the New object menu item.
Select the type of model object you want to create (here a Family) and click on the CREATE button.
Name the Family (from the Details view or with the Rename menu item).
From the Explorer view, create Family Representation diagram from the Family object.
Click on the background of the diagram, and select the StarTrekFan tool. Do the same for the StarWarsFan tool.
Then click on a Person (a StarTrekFan or a StarWarsFan) in the diagram. In the Details view you should see a new property named Children. From this property, set the Persons you want as children of the selected Person.
You should see your diagram updated instantaneously with new edges:
Diagrams are not the only kind of representation provided by default by Sirius Web. Forms are also a great tool to display data to the users.
Note
|
If you want to benefit from this part of the tutorial, please upload in Sirius Web the projects solutions/Family-Studio-Step5.zip and then solutions/Family-Instance-Step5.zip. Do not forget to delete existing projects from previous steps before. |
Here is an example of what can be done from the studio maker side:
Here is the result from the end-user side:
To develop more advanced features for your studios, which can not (yet) be implemented directly through the web UI, you can also do a lot of things programmatically (Java services, project templates, custom validation rules, representations descriptions…).
Let’s implement some of them!
So far in the studio definition we have used AQL expressions to navigate inside our models and to compute some values (for example labels). Sometimes you need to perform more complex computations that what can be (easily) expressed in AQL. Fortunately, Sirius Web makes it pretty easy to call into custom Java code directly from AQL using what’s called Java Services.
You can checkout the branch FAMILY_SERVICES
from your Sirius Web local git repository to retrieve the result of the demonstration done by Obeo and test it by yourself.
The actual Java services:
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
public class FamilyServices {
// aql:self.name + ' ' + self.eContainer().name
public String fullName(EObject person) {
EObject parent = person.eContainer();
if (this.isInstance(parent, "tutorial", "Family")) {
String familyName = (String) this.getAttribute(parent, "name");
String ownName = (String) this.getAttribute(person, "name");
return ownName + " " + familyName;
}
return "";
}
private Object getAttribute(EObject object, String attributeName) {
return object.eGet(object.eClass().getEStructuralFeature(attributeName));
}
private boolean isInstance(EObject object, String domain, String typeName) {
if (object != null) {
EClass klass = object.eClass();
return klass.getName().equals(typeName) && klass.getEPackage().getName().equals(domain);
} else {
return false;
}
}
}
Simpler version, but with no checks at all:
public class FamilyServices {
// aql:self.name + ' ' + self.eContainer().name
public String fullName(EObject person) {
return this.getName(person.eContainer()) + " " + this.getName(person);
}
private String getName(EObject object) {
return (String) object.eGet(object.eClass().getEStructuralFeature("name"));
}
}
We also need to tell Sirius Web about this new class, but is should only be available in our Family studio.
This is done by registering an IJavaServiceProvider
Spring bean:
import java.util.List;
import org.eclipse.sirius.components.view.View;
import org.eclipse.sirius.components.view.diagram.DiagramDescription;
import org.eclipse.sirius.components.view.emf.IJavaServiceProvider;
import org.eclipse.sirius.web.sample.services.FamilyServices;
import org.springframework.stereotype.Service;
@Service
public class FamilyServicesProvider implements IJavaServiceProvider {
@Override
public List<Class<?>> getServiceClasses(View view) {
boolean isTestView = view.getDescriptions().stream()
.filter(DiagramDescription.class::isInstance)
.map(DiagramDescription.class::cast)
.anyMatch(diagramDescription -> diagramDescription.getDomainType().equals("tutorial::Family"));
if (isTestView) {
return List.of(FamilyServices.class);
}
return List.of();
}
}
Once this is done and the backend has restarted, we can now use our new service method (fullName
) from AQL expressions in our Family Studio.
In the Family Diagram Description, change the Label Expression for Person Node to: aql:self.fullName()
.
Re-open the diagram.
From the homepage of Sirius Web, you can see some project templates. In Sirius Web, a template is a project initializer and accelerator.
Please checkout the branch FAMILY_TEMPLATE
from your Sirius Web local git repository to retrieve the result of the demonstration done by Obeo and test it by yourself.
There are two interfaces to implement to provide a new template in Sirius Web:
-
an
IProjectTemplateProvider
-
an
IProjectTemplateInitializer
For the IProjectTemplateProvider
, the code look like this:
import java.util.List;
import org.eclipse.sirius.web.services.api.projects.IProjectTemplateProvider;
import org.eclipse.sirius.web.services.api.projects.ProjectTemplate;
import org.springframework.context.annotation.Configuration;
@Configuration
public class FamilyProjectTemplatesProvider implements IProjectTemplateProvider {
public static final String FAMILY_TEMPLATE_ID = "family-template";
@Override
public List<ProjectTemplate> getProjectTemplates() {
var flowTemplate = ProjectTemplate.newProjectTemplate(FAMILY_TEMPLATE_ID)
.label("Family")
.imageURL("/images/Family-Template.svg")
.natures(List.of())
.build();
return List.of(flowTemplate);
}
}
For the IProjectTemplateInitializer
, the code look like this:
import org.eclipse.sirius.web.services.api.projects.IProjectTemplateInitializer;
import org.springframework.context.annotation.Configuration;
@Configuration
public class FamilyProjectTemplatesInitializer implements IProjectTemplateInitializer {
@Override
public boolean canHandle(String templateId) {
return FamilyProjectTemplatesProvider.FAMILY_TEMPLATE_ID.equals(templateId); //(1)
}
@Override
public Optional<RepresentationMetadata> handle(String templateId, IEditingContext editingContext) {
if (FamilyProjectTemplatesProvider.FAMILY_TEMPLATE_ID.equals(templateId)) {
return this.initializeFamilyProject(editingContext); //(2)
}
return Optional.empty();
}
}
-
this template initializer only applies when the
FamilyProjectTemplatesProvider
is called. -
the content of
initializeFamilyProject
is described below.
private Optional<RepresentationMetadata> initializeFamilyProject(IEditingContext editingContext) {
Optional<RepresentationMetadata> result = Optional.empty();
Optional<AdapterFactoryEditingDomain> optionalEditingDomain = Optional.of(editingContext)
.filter(EditingContext.class::isInstance)
.map(EditingContext.class::cast)
.map(EditingContext::getDomain);
Optional<UUID> editingContextUUID = new IDParser().parse(editingContext.getId());
if (optionalEditingDomain.isPresent() && editingContextUUID.isPresent()) {
AdapterFactoryEditingDomain adapterFactoryEditingDomain = optionalEditingDomain.get();
ResourceSet resourceSet = adapterFactoryEditingDomain.getResourceSet();
EPackage familyEPackage = this.getTutorialEPackage(editingContext.getId());
//(1)
var optionalDocumentEntity = this.projectRepository.findById(editingContextUUID.get()).map(projectEntity -> {
DocumentEntity documentEntity = new DocumentEntity();
documentEntity.setProject(projectEntity);
documentEntity.setName(DOCUMENT_TITLE);
documentEntity.setContent(this.getNewFamilyContent(familyEPackage));
documentEntity = this.documentRepository.save(documentEntity);
return documentEntity;
});
if (optionalDocumentEntity.isPresent()) {
DocumentEntity documentEntity = optionalDocumentEntity.get();
//(2)
JSONResourceFactory jsonResourceFactory = new JSONResourceFactory();
JsonResource resource = jsonResourceFactory.createResourceFromPath(documentEntity.getId().toString());
resourceSet.getResources().add(resource);
resource.eAdapters().add(new ResourceMetadataAdapter(DOCUMENT_TITLE));
try (var inputStream = new ByteArrayInputStream(documentEntity.getContent().getBytes())) {
resource.load(inputStream, null);
//(3)
var optionalFamilyDiagram = this.findDiagramDescription(editingContext, "Family Diagram Description");
if (optionalFamilyDiagram.isPresent()) {
DiagramDescription familyDiagram = optionalFamilyDiagram.get();
Object semanticTarget = resource.getContents().get(0);
Diagram diagram = this.diagramCreationService.create(familyDiagram.getLabel(), semanticTarget, familyDiagram, editingContext);
this.representationPersistenceService.save(editingContext, diagram);
result = Optional.of(new RepresentationMetadata(diagram.getId(), diagram.getKind(), diagram.getLabel(), diagram.getDescriptionId()));
}
} catch (IOException exception) {
this.logger.warn(exception.getMessage(), exception);
}
}
}
return result;
}
-
First step is to create a document that will contains our family model
-
Second step it load this document
-
Third step is to create a diagram instance based on the Diagram Description named
Family Diagram Description
You can now restart your application and see the result!
Please checkout the branch FLOW_VALIDATION_RULES
from your Sirius Web local git repository to retrieve the result of the demonstration done by Obeo and test it by yourself.
In Sirius Web its is possible to add validation rules for EMF Ecore metamodels.
Once a project open, the Validation view (on the left of the application) shows the rules that are not valid.
Let’s try to add a validation rule for the Flow metamodel.
The first step is to declare a spring Configuration class that will register our validator in the EMF validator registry.
import fr.obeo.dsl.designer.sample.flow.FlowPackage;
import java.util.Objects;
import org.eclipse.emf.ecore.EValidator;
import org.springframework.context.annotation.Configuration;
import jakarta.annotation.PostConstruct;
@Configuration
public class SampleEMFValidation {
private final EValidator.Registry eValidatorRegistry;
public SampleEMFValidation(EValidator.Registry eValidatorRegistry) {
this.eValidatorRegistry = Objects.requireNonNull(eValidatorRegistry);
}
@PostConstruct
public void registerFamilyValidator() {
this.eValidatorRegistry.put(FlowPackage.eINSTANCE, new FlowValidator());
}
}
Then, implement an EValidator
for Flow:
import fr.obeo.dsl.designer.sample.flow.FlowPackage;
import fr.obeo.dsl.designer.sample.flow.Named;
import java.util.Map;
import org.eclipse.emf.common.util.BasicDiagnostic;
import org.eclipse.emf.common.util.Diagnostic;
import org.eclipse.emf.common.util.DiagnosticChain;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EDataType;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EValidator;
import org.eclipse.emf.ecore.util.EcoreValidator;
public class FlowValidator implements EValidator {
public static final String INVALID_NAME_ERROR_MESSAGE = "The name %1$s is not well-formed.";
@Override
public boolean validate(EObject eObject, DiagnosticChain diagnostics, Map<Object, Object> context) {
return true;
}
@Override
public boolean validate(EDataType eDataType, Object value, DiagnosticChain diagnostics, Map<Object, Object> context) {
return true;
}
@Override
public boolean validate(EClass eClass, EObject eObject, DiagnosticChain diagnostics, Map<Object, Object> context) {
boolean isValid = true;
if (eObject instanceof Named flowNamedElement) {
isValid = this.nameIsWellFormedValidate(flowNamedElement, diagnostics) && isValid;
}
return isValid;
}
private boolean nameIsWellFormedValidate(Named flowNamedElement, DiagnosticChain diagnostics) {
boolean isValid = EcoreValidator.isWellFormedJavaIdentifier(flowNamedElement.getName());
if (!isValid && diagnostics != null) {
// @formatter:off
BasicDiagnostic basicDiagnostic = new BasicDiagnostic(Diagnostic.WARNING,
"sirius-web-family-application",
0,
String.format(INVALID_NAME_ERROR_MESSAGE, flowNamedElement.getName()),
new Object [] {
flowNamedElement,
FlowPackage.Literals.NAMED__NAME,
});
// @formatter:on
diagnostics.add(basicDiagnostic);
}
return isValid;
}
}
Restart your application and see the result on a Flow project:
You can observe that the warning message is displayed on the Validation view, but also directly under the appropriate attribute in the Details view.
In this part, the Obeo team will demonstrate live the modification of the frontend of Sirius Web.
-
Show Papaya; it’s also an example of a more complex (less "toy") studio fully defined with the same tools the attendees used.
-
Add the
PapayaOperationActivityLabelDetailToolContribution
(registration code in EditProjectView removed from the supplied version).
Lets' package our Sirius Web application as a single jar file.
The first and only step is to create an Eclipse launch configuration to build and package our Sirius Web application. Go to Run > Run Configurations… menu and then double-click on Maven Build.
Set the base directory (${workspace_loc:/sirius-web-family-application}), goals (package), user settings (/PATH_TO_YOUR_sirius-web-tutorial-pack-XXX-x.y.z/resources/settings.xml) and parameters (skip tests enabled) as below:
Click on Run. Your Sirius Web application is packaged!
Go back to your Eclipse environment, refresh your spring project and then you should see a file named sirius-web-family-application-2023.8.4-econ.jar
in the target
folder.
This jar file contains your application all the dependencies needed to run properly!
You can test it by launching the jar manually on your machine (if you have Java 17 minimum) with the following command:
java -jar sirius-web-family-application-2023.8.4-econ.jar
In this part, the Obeo team will demonstrate live the usage of view-builder API.
This API allows to easily create Diagram and Forms Description from View, but programmatically.
Please checkout VIEW-BUILDER-API
branch from your Sirius Web local git repository to retrieve the result of the demonstration done by Obeo and test it by yourself.
Thanks for attending this Sirius Web tutorial! We hope it will make you want to go further with it.
Useful links:
-
Sirius Web website: https://eclipse.dev/sirius/sirius-web.html
-
more details about the usage of Sirius Web or the usage the Studio: https://docs.obeostudio.com/
-
more details about AQL, the model query language: https://eclipse.dev/acceleo/documentation/
-
Sirius Web source code: https://github.com/eclipse-sirius/sirius-web