diff --git a/examples/org.eclipse.epsilon.examples.picto.xtext.domainmodel.example/.project b/examples/org.eclipse.epsilon.examples.picto.xtext.domainmodel.example/.project
new file mode 100644
index 0000000000..83e20eface
--- /dev/null
+++ b/examples/org.eclipse.epsilon.examples.picto.xtext.domainmodel.example/.project
@@ -0,0 +1,17 @@
+
+
+ org.eclipse.epsilon.examples.picto.xtext.domainmodel.example
+
+
+
+
+
+ org.eclipse.xtext.ui.shared.xtextBuilder
+
+
+
+
+
+ org.eclipse.xtext.ui.shared.xtextNature
+
+
diff --git a/examples/org.eclipse.epsilon.examples.picto.xtext.domainmodel.example/blog.dmodel b/examples/org.eclipse.epsilon.examples.picto.xtext.domainmodel.example/blog.dmodel
new file mode 100644
index 0000000000..cf570ea0cf
--- /dev/null
+++ b/examples/org.eclipse.epsilon.examples.picto.xtext.domainmodel.example/blog.dmodel
@@ -0,0 +1,27 @@
+datatype String
+
+entity Blog {
+ "Main entity. A blog is composed of posts"
+
+ title: String
+ many posts: Post
+}
+
+entity HasAuthor {
+ author: String
+}
+
+entity Post extends HasAuthor {
+ "Starting message of each blog entry"
+
+ title: String
+ content: String
+ many comments: Comment
+}
+
+entity Comment extends HasAuthor {
+ "Messages that capture the discussion around a post"
+
+ content: String
+ many responses: Comment
+}
diff --git a/examples/org.eclipse.epsilon.examples.picto.xtext.domainmodel.example/readme.md b/examples/org.eclipse.epsilon.examples.picto.xtext.domainmodel.example/readme.md
new file mode 100644
index 0000000000..8e037f537e
--- /dev/null
+++ b/examples/org.eclipse.epsilon.examples.picto.xtext.domainmodel.example/readme.md
@@ -0,0 +1,13 @@
+# Blog domain model report
+
+## Element stats
+
+
+
+## Types usage
+
+
+
+## Core Entities
+
+
\ No newline at end of file
diff --git a/examples/org.eclipse.epsilon.examples.picto.xtext.domainmodel.example/standaloneVisualisation.dmodel.picto b/examples/org.eclipse.epsilon.examples.picto.xtext.domainmodel.example/standaloneVisualisation.dmodel.picto
new file mode 100644
index 0000000000..b191f2ccb6
--- /dev/null
+++ b/examples/org.eclipse.epsilon.examples.picto.xtext.domainmodel.example/standaloneVisualisation.dmodel.picto
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/org.eclipse.epsilon.examples.picto.xtext.domainmodel.ide/xtend-gen/.gitignore b/examples/org.eclipse.epsilon.examples.picto.xtext.domainmodel.ide/xtend-gen/.gitignore
new file mode 100644
index 0000000000..070c2141ef
--- /dev/null
+++ b/examples/org.eclipse.epsilon.examples.picto.xtext.domainmodel.ide/xtend-gen/.gitignore
@@ -0,0 +1,3 @@
+src
+src-gen
+plugin.xml
\ No newline at end of file
diff --git a/examples/org.eclipse.epsilon.examples.picto.xtext.domainmodel.picto/blog.dmodel b/examples/org.eclipse.epsilon.examples.picto.xtext.domainmodel.picto/blog.dmodel
index 37b5eef6a7..8b25061cb2 100644
--- a/examples/org.eclipse.epsilon.examples.picto.xtext.domainmodel.picto/blog.dmodel
+++ b/examples/org.eclipse.epsilon.examples.picto.xtext.domainmodel.picto/blog.dmodel
@@ -1,6 +1,8 @@
datatype String
entity Blog {
+ "Main entity. A blog is composed of posts"
+
title: String
many posts: Post
}
@@ -10,12 +12,16 @@ entity HasAuthor {
}
entity Post extends HasAuthor {
+ "Starting message of each blog entry"
+
title: String
content: String
many comments: Comment
}
entity Comment extends HasAuthor {
+ "Messages that capture the discussion around a post"
+
content: String
many responses: Comment
}
diff --git a/examples/org.eclipse.epsilon.examples.picto.xtext.domainmodel.picto/dmodel.egx b/examples/org.eclipse.epsilon.examples.picto.xtext.domainmodel.picto/dmodel.egx
deleted file mode 100644
index 0d95cede99..0000000000
--- a/examples/org.eclipse.epsilon.examples.picto.xtext.domainmodel.picto/dmodel.egx
+++ /dev/null
@@ -1,12 +0,0 @@
-rule Entity2Graphviz
- transform e : Entity {
-
- template : "entity2graphviz.egl"
-
- parameters : Map{
- "path" = Sequence{"Model", e.name},
- "icon" = "diagram-ffffff",
- "format" = "graphviz-dot"
- }
-
-}
\ No newline at end of file
diff --git a/examples/org.eclipse.epsilon.examples.picto.xtext.domainmodel.picto/picto/barchart.egl b/examples/org.eclipse.epsilon.examples.picto.xtext.domainmodel.picto/picto/barchart.egl
new file mode 100644
index 0000000000..d585d328a7
--- /dev/null
+++ b/examples/org.eclipse.epsilon.examples.picto.xtext.domainmodel.picto/picto/barchart.egl
@@ -0,0 +1,77 @@
+[%
+// TODO: make a list of colours big enough to reuse this barchart with ease
+var labels = Sequence{"Data types",
+ "Entities",
+ "Features"};
+
+var values = Sequence{DataType.all.size(),
+ Entity.all.size(),
+ Feature.all.size()};
+%]
+
+
+
+
+
+
+
+
+
+
+
+
+
+[%
+operation Sequence quote() {
+ return self.collect(elem | '"' + elem + '"')
+ .concat(", ");
+}
+%]
diff --git a/examples/org.eclipse.epsilon.examples.picto.xtext.domainmodel.picto/picto/dmodel.egx b/examples/org.eclipse.epsilon.examples.picto.xtext.domainmodel.picto/picto/dmodel.egx
new file mode 100644
index 0000000000..bfff6abd3d
--- /dev/null
+++ b/examples/org.eclipse.epsilon.examples.picto.xtext.domainmodel.picto/picto/dmodel.egx
@@ -0,0 +1,90 @@
+rule StatsChart {
+ template : "barchart.egl"
+
+ parameters : Map {
+ "position" = "1",
+ "path" = List{"Stats"},
+ "icon" = "barchart",
+ "format" = "html"
+ }
+}
+
+rule TypesTable {
+ template : "typeStats.pinset"
+
+ parameters : Map {
+ "position" = "2",
+ "path" = Sequence{"Types"},
+ "icon" = "table",
+ "format" = "csv"
+ }
+}
+
+rule AllEntities {
+
+ template : "entity2plantuml.egl"
+
+ parameters : Map{
+ "position" = "3",
+ "path" = Sequence{"All Entities"},
+ "icon" = "diagram-ffffff",
+ "format" = "plantuml",
+ "inputEntities" = Entity.all.name,
+ "layers" = Sequence {
+ Map {"id"="documentation", "title"="Documentation", "active"=false},
+ Map {"id"="supertype", "title"="Supertype"},
+ Map {"id"="inlineReferences", "title"="Inline references"},
+ Map {"id"="referenceLabels", "title"="Reference labels", "active"=false}
+ }
+ }
+}
+
+rule Entity2PlantUML
+ transform e : Entity {
+
+ template : "entity2plantuml.egl"
+
+ parameters : Map {
+ "position" = "4",
+ "path" = Sequence{"Entities", e.name},
+ "icon" = "diagram-ffffff",
+ "format" = "plantuml",
+ "layers" = Sequence {
+ Map {"id"="documentation", "title"="Documentation"},
+ Map {"id"="supertype", "title"="Supertype"},
+ Map {"id"="subtypes", "title"="Subtypes"},
+ Map {"id"="inlineReferences", "title"="Inline references"},
+ Map {"id"="referenceLabels", "title"="Reference labels"}
+ }
+ }
+}
+
+rule Entity2Graphviz
+ transform e : Entity {
+
+ template : "entity2graphviz.egl"
+
+ parameters : Map{
+ "path" = Sequence{"Entities-Graphviz", e.name},
+ "icon" = "diagram-ffffff",
+ "format" = "graphviz-dot"
+ }
+
+}
+
+@lazy
+rule Entities2PlantUML {
+
+ template : "entity2plantuml.egl"
+
+ parameters : Map {
+ // requires "inputEntities" to work
+ "format" = "plantuml",
+ "layers" = Sequence {
+ Map {"id"="documentation", "title"="Documentation"},
+ Map {"id"="supertype", "title"="Supertype", "active"=false},
+ Map {"id"="inlineReferences", "title"="Inline references", "active"=false},
+ Map {"id"="referenceLabels", "title"="Reference labels"}
+ }
+ }
+}
diff --git a/examples/org.eclipse.epsilon.examples.picto.xtext.domainmodel.picto/entity2graphviz.egl b/examples/org.eclipse.epsilon.examples.picto.xtext.domainmodel.picto/picto/entity2graphviz.egl
similarity index 97%
rename from examples/org.eclipse.epsilon.examples.picto.xtext.domainmodel.picto/entity2graphviz.egl
rename to examples/org.eclipse.epsilon.examples.picto.xtext.domainmodel.picto/picto/entity2graphviz.egl
index 7e81ff9535..e3ef17a2ba 100644
--- a/examples/org.eclipse.epsilon.examples.picto.xtext.domainmodel.picto/entity2graphviz.egl
+++ b/examples/org.eclipse.epsilon.examples.picto.xtext.domainmodel.picto/picto/entity2graphviz.egl
@@ -26,7 +26,7 @@ digraph G {
[%
operation Entity getLabel() {
- var onClick = "top.showView(['Model','" + self.name + "'])";
+ var onClick = "top.showView(['Entities-Graphviz','" + self.name + "'])";
if (self == e) {
onClick = "top.showElement('" + self.id + "', '" + self.eResource.uri + "')";
@@ -54,6 +54,7 @@ operation Entity getLabel() {
}
label += "";
+
return label;
}
diff --git a/examples/org.eclipse.epsilon.examples.picto.xtext.domainmodel.picto/picto/entity2plantuml.egl b/examples/org.eclipse.epsilon.examples.picto.xtext.domainmodel.picto/picto/entity2plantuml.egl
new file mode 100644
index 0000000000..f2626c0864
--- /dev/null
+++ b/examples/org.eclipse.epsilon.examples.picto.xtext.domainmodel.picto/picto/entity2plantuml.egl
@@ -0,0 +1,139 @@
+[%
+// Enable javascript links (disabled by default for security reasons)
+Native("java.lang.System").setProperty("PLANTUML_ALLOW_JAVASCRIPT_IN_LINK", "true");
+%]
+
+@startuml
+hide empty methods
+hide circle
+skinparam classBorderThickness 1
+!pragma layout smetana
+skinparam classFontName system-ui
+
+[%
+var mainEntity = getMainEntity();
+var entities = getVisibleEntities();
+%]
+
+[%for (ent in entities){%]
+ [% if (isLayerActive("documentation") and ent.doc != null) {%]
+ note "[%=ent.doc%]" as nn_[%=ent.name%] #f0ffff
+ nn_[%=ent.name%] .. [%=ent.name%]
+ [%}%]
+ class [%=ent.name%] [[javascript:top.[%=ent.getLink()%]]] [%=ent.getColour()%] {
+
+ [%for (f in ent.features){%]
+ [% if (not f.type.isTypeOf(Entity) or isLayerActive("inlineReferences")) {%]
+ [%=f.name%] : [%=f.type.name%][%=(f.many ? " ["+"*"+"]" : "")%]
+ [%}%]
+ [%}%]
+ }
+[%}%]
+
+
+[%if (mainEntity <> null) {%]
+
+ [%for (f in mainEntity.features.select(f|f.type.isTypeOf(Entity))){%]
+ [%=mainEntity.name%]-->[%=f.type.name%][%=f.getReferenceLabel()%]
+ [%}%]
+
+ [%if (isLayerActive("supertype") and mainEntity.superType.isDefined()) {%]
+ [%=mainEntity.superType.Name%]<|--[%=mainEntity.name%]
+ [%}%]
+
+ [%if (isLayerActive("subtypes")) {
+ for (subType in mainEntity.getSubTypes()) {%]
+ [%=mainEntity.name%]<|--[%=subType.name%]
+ [%}%]
+ [%}%]
+[%} else {%]
+ [%for (ent in entities){%]
+ [%for (f in ent.features.select(f|f.type.isTypeOf(Entity) and entities.includes(f.type))){%]
+ [%=ent.name%]-->[%=f.type.name%][%=f.getReferenceLabel()%]
+ [%}%]
+
+ [%if (isLayerActive("supertype") and entities.includes(ent.superType)) {%]
+ [%=ent.superType.Name%]<|--[%=ent.name%]
+ [%}%]
+[%}%]
+
+[%}%]
+@enduml
+[%
+//out.toString().println();
+%]
+[%
+
+operation getMainEntity() {
+ return e.isDefined() ? e : null;
+}
+
+operation getVisibleEntities() {
+ var visibleEntities : Set;
+
+ if (mainEntity <> null) {
+ visibleEntities.add(mainEntity);
+
+ // entity features
+ visibleEntities.addAll(
+ mainEntity.features.select(f|f.type.isTypeOf(Entity)).collect(f|f.type));
+
+ // supertype
+ if (isLayerActive("supertype") and mainEntity.superType.isDefined()) {
+ visibleEntities.add(e.superType);
+ }
+
+ // subtypes
+ if (isLayerActive("subtypes")) {
+ visibleEntities.addAll(mainEntity.getSubTypes());
+ }
+ }
+ else if (inputEntities.isDefined()) {
+ visibleEntities.addAll(Entity.all.select(en | inputEntities.includes(en.name)));
+ }
+
+ return visibleEntities;
+}
+
+@cached
+operation Entity getSubTypes() {
+ return Entity.all.select(ent | ent.superType = self);
+}
+
+operation Entity getColour() {
+ if (self == mainEntity) return "#DDFADC";
+ else return "#lemonchiffon";
+}
+
+// cannot use brackets (even encoded ones) in plantuml links, swapped with a string split
+operation getPath(path : Sequence) {
+ var separator = "@@";
+ return "'" + path.concat(separator) + "'" + ".split('" + separator + "')";
+}
+
+operation Entity getLink() {
+ if (self == mainEntity) {
+ return "showElement('" + self.id + "','" + self.eResource.uri + "')";
+ }
+ return "showView(" + getPath(Sequence{"Entities", self.name})% + ")";
+}
+
+operation Feature getReferenceLabel() {
+ var label = "";
+ if (isLayerActive("referenceLabels")) {
+ // the initial " : " comes from PlantUML's syntax to add a label
+ label = " : " + self.name + (self.many ? " ["+"*"+"]" : "");
+ }
+ return label;
+}
+
+operation isLayerActive(id : String) {
+ var layer = layers.selectOne(l|l.id = id);
+ if (layer.isDefined()) {
+ return layer.active;
+ }
+ else {
+ return true;
+ }
+}
+%]
diff --git a/examples/org.eclipse.epsilon.examples.picto.xtext.domainmodel.picto/icons/attribute.gif b/examples/org.eclipse.epsilon.examples.picto.xtext.domainmodel.picto/picto/icons/attribute.gif
similarity index 100%
rename from examples/org.eclipse.epsilon.examples.picto.xtext.domainmodel.picto/icons/attribute.gif
rename to examples/org.eclipse.epsilon.examples.picto.xtext.domainmodel.picto/picto/icons/attribute.gif
diff --git a/examples/org.eclipse.epsilon.examples.picto.xtext.domainmodel.picto/icons/entity.gif b/examples/org.eclipse.epsilon.examples.picto.xtext.domainmodel.picto/picto/icons/entity.gif
similarity index 100%
rename from examples/org.eclipse.epsilon.examples.picto.xtext.domainmodel.picto/icons/entity.gif
rename to examples/org.eclipse.epsilon.examples.picto.xtext.domainmodel.picto/picto/icons/entity.gif
diff --git a/examples/org.eclipse.epsilon.examples.picto.xtext.domainmodel.picto/picto/typeStats.pinset b/examples/org.eclipse.epsilon.examples.picto.xtext.domainmodel.picto/picto/typeStats.pinset
new file mode 100644
index 0000000000..6c4b3be7c3
--- /dev/null
+++ b/examples/org.eclipse.epsilon.examples.picto.xtext.domainmodel.picto/picto/typeStats.pinset
@@ -0,0 +1,5 @@
+dataset typeStats over t : Type {
+ properties[name as Name]
+ column Type : t.isTypeOf(Entity) ? "Entity" : "DataType"
+ column Usages : Feature.all.select(f | f.type == t).size()
+}
diff --git a/examples/org.eclipse.epsilon.examples.picto.xtext.domainmodel.picto/src/org/eclipse/epsilon/examples/picto/xtext/domainmodel/picto/DmodelPictoSource.java b/examples/org.eclipse.epsilon.examples.picto.xtext.domainmodel.picto/src/org/eclipse/epsilon/examples/picto/xtext/domainmodel/picto/DmodelPictoSource.java
index 396ab08574..dcfe5e0b07 100644
--- a/examples/org.eclipse.epsilon.examples.picto.xtext.domainmodel.picto/src/org/eclipse/epsilon/examples/picto/xtext/domainmodel/picto/DmodelPictoSource.java
+++ b/examples/org.eclipse.epsilon.examples.picto.xtext.domainmodel.picto/src/org/eclipse/epsilon/examples/picto/xtext/domainmodel/picto/DmodelPictoSource.java
@@ -17,12 +17,13 @@
import org.eclipse.xtext.ui.workspace.WorkspaceLockAccess.Result;
import org.eclipse.xtext.util.concurrent.IUnitOfWork;
+@SuppressWarnings("restriction")
public class DmodelPictoSource extends EglPictoSource {
@Override
protected Picto getRenderingMetadata(IEditorPart editorPart) {
Picto metadata = PictoFactory.eINSTANCE.createPicto();
- metadata.setTransformation("platform:/plugin/org.eclipse.epsilon.examples.picto.xtext.domainmodel.picto/dmodel.egx");
+ metadata.setTransformation("platform:/plugin/org.eclipse.epsilon.examples.picto.xtext.domainmodel.picto/picto/dmodel.egx");
return metadata;
}
@@ -34,7 +35,7 @@ protected Resource getResource(IEditorPart editorPart) {
public Result exec(XtextResource state) throws Exception {
holder.setResource(state);
return null;
- };
+ }
});
return holder.getResource();
diff --git a/examples/org.eclipse.epsilon.examples.picto.xtext.domainmodel.picto/test.dmodel.picto b/examples/org.eclipse.epsilon.examples.picto.xtext.domainmodel.picto/standaloneTest.dmodel.picto
similarity index 63%
rename from examples/org.eclipse.epsilon.examples.picto.xtext.domainmodel.picto/test.dmodel.picto
rename to examples/org.eclipse.epsilon.examples.picto.xtext.domainmodel.picto/standaloneTest.dmodel.picto
index 895297b291..7d0b12e8ac 100644
--- a/examples/org.eclipse.epsilon.examples.picto.xtext.domainmodel.picto/test.dmodel.picto
+++ b/examples/org.eclipse.epsilon.examples.picto.xtext.domainmodel.picto/standaloneTest.dmodel.picto
@@ -1,8 +1,8 @@
-
+
-
+
diff --git a/examples/org.eclipse.epsilon.examples.picto.xtext.domainmodel.ui/xtend-gen/.gitignore b/examples/org.eclipse.epsilon.examples.picto.xtext.domainmodel.ui/xtend-gen/.gitignore
new file mode 100644
index 0000000000..e407b8bf08
--- /dev/null
+++ b/examples/org.eclipse.epsilon.examples.picto.xtext.domainmodel.ui/xtend-gen/.gitignore
@@ -0,0 +1,4 @@
+# Ignore everything
+*
+# But this .gitignore file
+!.gitignore
\ No newline at end of file
diff --git a/examples/org.eclipse.epsilon.examples.picto.xtext.domainmodel/src/org/eclipse/epsilon/examples/picto/xtext/domainmodel/Domainmodel.xtext b/examples/org.eclipse.epsilon.examples.picto.xtext.domainmodel/src/org/eclipse/epsilon/examples/picto/xtext/domainmodel/Domainmodel.xtext
index 95027483b9..c947f2c599 100644
--- a/examples/org.eclipse.epsilon.examples.picto.xtext.domainmodel/src/org/eclipse/epsilon/examples/picto/xtext/domainmodel/Domainmodel.xtext
+++ b/examples/org.eclipse.epsilon.examples.picto.xtext.domainmodel/src/org/eclipse/epsilon/examples/picto/xtext/domainmodel/Domainmodel.xtext
@@ -29,6 +29,7 @@ DataType:
Entity:
'entity' name=ID ('extends' superType=[Entity|QualifiedName])? '{'
+ (doc=STRING)?
(features+=Feature)*
'}';