| [% |
| import "ecore2dot.eol"; |
| |
| // If the root EPackage has a @constraints(file="foo.evl") |
| // annotation, parse the constraints into an EVL module |
| var module = getValidationModule(); |
| |
| // Compute the set of classes to be shown in this diagram |
| var classes = OrderedSet{c}; // The root class |
| classes.addAll(c.getVisibleEReferences().eType); // The types of its references |
| if (isLayerActive("supertypes")) classes.addAll(c.eSuperTypes); // All its supertypes |
| if (isLayerActive("subtypes")) classes.addAll(EClass.all.select(o|o.eSuperTypes.includes(c))); // All its subtypes |
| %] |
| digraph G { |
| graph[splines=ortho, nodesep=0.5] |
| node[fontname=Tahoma, fontsize=10, shape=record] |
| edge[fontname=Tahoma, fontsize=10, dir=back, arrowtail=empty] |
| |
| [%var main=c;%] |
| [%for (c in classes) { %]
|
| [** Create a node for the class **] |
| [%=c.name%][shape=none, margin=0, label = <[%=c.getLabel()%]>] |
| |
| |
| [%if (main == c){%] |
| |
| [** Create nodes for all the constraints of the main class*] |
| [%if (isLayerActive("constraints")){%] |
| [%for (constraint in module.constraintContexts.select(ctx|ctx.typeName=c.name).collect(ctx|ctx.constraints).flatten()){%] |
| [%=c.name+constraint.name%][label="[%=constraint.getConstraintLabel()%]", style="filled", fillcolor="[%=constraint.getConstraintColour()%]"] |
| [%=c.name%]->[%=c.name+constraint.name%][arrowtail=none, style=dashed] |
| [%}%] |
| [%}%] |
| |
| [** Create node for all the documentation of the main class*] |
| [%if (isLayerActive("documentation")){%] |
| [%var documentation = c.getAnnotationValue("http://www.eclipse.org/emf/2002/GenModel", "documentation");%] |
| [%if (documentation.isDefined()){%] |
| [%=c.name%]_Documentation[shape="note", label="[%=documentation.toMultiline()%]", style="filled", fillcolor="azure"] |
| [%=c.name%]_Documentation->[%=c.name%][arrowtail=none, style=dashed]; |
| [%}%] |
| [%}%] |
| [%}%] |
| |
| [%}%] |
| |
| [** Create edges for the supertypes of the main class **] |
| [%if (isLayerActive("supertypes")){%] |
| [%for (s in main.eSuperTypes){%] |
| [%=s.name%]->[%=main.name%] |
| [%}%] |
| [%}%] |
| |
| [** ... and for its subtypes **] |
| [%if (isLayerActive("subtypes")){%] |
| [%for (s in classes.select(c|c.eSuperTypes.includes(main))){%] |
| [%=main.name%]->[%=s.name%] |
| [%}%] |
| [%}%] |
| [* ... and for its references *] |
| [%for (r in main.getVisibleEReferences().select(r|r.eType <> main)) {%] |
| [%=main.name%]->[%=r.eType.name%][arrowtail=[%=r.getArrowTail()%],tooltip="[%=r.name%]"]; |
| [%if (not r.isContainment()){%]{rank=same; [%=main.name%]; [%=r.eType.name%]}[%}%] |
| [%}%] |
| |
| } |
| |
| [% |
| |
| operation EClass getLabel() { |
| var fillcolor = "fffcdc"; if (self==main) fillcolor="c8f0a1"; |
| var label = "<table cellspacing='0' cellborder='0' cellpadding='1' bgcolor='#" + fillcolor + "'>"; |
| var features = self.eAllStructuralFeatures; |
| |
| if (not isLayerActive("inherited") and self == main) features = self.eStructuralFeatures; |
| if (not isLayerActive("derived")) features = features.reject(f|f.isDerived); |
| |
| if (self.eSuperTypes.includes(main)) features = features.excludingAll(main.eAllStructuralFeatures); |
| |
| var javascript = "javascript:top.showView('/Model/Classes/" + self.name + "')"; |
| var tooltip = "Show class diagram for " + self.name; |
| if (self==main) { |
| javascript = "javascript:top.showElement('" + self.id + "','" + self.eResource.uri + "')"; |
| tooltip = "Go to " + self.name + " in the Ecore editor"; |
| } |
| |
| label += "<tr><td sides='B' colspan='2' border='1'>" + |
| "<table border='0' cellspacing='0' cellborder='0' cellpading='0'>" + |
| "<tr><td align='right' valign='middle'><img src='" + self.getIcon()+ "'></img></td>" + |
| "<td align='left' valign='middle' href=\""+javascript+"\" tooltip='" + tooltip + "'>" + self.name + "</td></tr></table></td></tr>"; |
| |
| label += "<tr><td></td><td></td></tr>"; |
| |
| for (f in features.sortBy(f|f.name.toLowerCase())) { |
| label += "<tr>"; |
| label += "<td><img src='" + f.getIcon() + "'></img></td><td align='left'>" + f.getLabel(self) + "</td>"; |
| label += "</tr>"; |
| } |
| |
| if (features.isEmpty()){ |
| label += "<tr>"; |
| label += "<td> </td><td> </td>"; |
| label += "</tr>"; |
| } |
| |
| label += "</table>"; |
| return label; |
| } |
| |
| operation EStructuralFeature getLabel(eClass : EClass) { |
| var label = self.name; |
| if (self.eType.isDefined()) label += " : " + self.eType.name; |
| if (self.isMany) label += "["+"*"+"]"; |
| label += " "; |
| if (eClass == main and self.eContainer() == eClass) label = "<font color='blue'>" + label + "</font>"; |
| if (self.isTypeOf(EReference)) { |
| // add href here |
| } |
| return label; |
| } |
| |
| operation EOperation getLabel() { |
| var label = self.name + "(" + self.eParameters.collect(p|p.getLabel()).concat(", ") + ")"; |
| if (self.eType.isDefined()) { |
| label += " : " + self.eType.name; |
| if (self.isMany) { |
| label += "["+"*"+"]"; |
| } |
| } |
| return label; |
| } |
| |
| operation EReference getArrowTail() { |
| if (self.containment) { |
| return "diamond"; |
| } |
| else { |
| return "none"; |
| } |
| } |
| |
| operation Any getIcon() { |
| return new Native("java.io.File") |
| (System.context.module.file.parent, "icons/" + self.eClass.name + ".gif").absolutePath; |
| } |
| |
| operation Any getConstraintLabel() { |
| var label = self.name; |
| if (self.comments.notEmpty()) label = label + ": " + self.comments.first(); |
| return label.toMultiline(); |
| } |
| |
| operation Any getConstraintColour() { |
| if (self.isCritique()) return "khaki1"; |
| else return "mistyrose"; |
| } |
| |
| operation EClass getVisibleEReferences() { |
| var eReferences = self.eReferences; |
| if (not isLayerActive("derived")) eReferences = eReferences.reject(r|r.isDerived); |
| return eReferences; |
| } |
| |
| operation isLayerActive(id : String) { |
| var layer = layers.selectOne(l|l.id = id); |
| if (layer.isDefined()) { |
| return layer.active; |
| } |
| else { |
| return true; |
| } |
| } |
| |
| %] |
| |