/* * PatternDiagramGenerator.eol 1.00 15/02/06 */ /** * This PatternDiagramGenerator.eol artefact is used by the method * "executeProPGenPcm2PcpTransformation" of the class "Pcm2PcpBaseHandler" * as part of the component "ProPMan Eclipse plug-in". It creates a Papyrus * diagram for a problem-context or solution pattern. */ removeEdgesNotExistingInUMLModel(); var m = uml::Model.all.selectOne(m|m.name = "PcpModel_for_Pcm_SalaryStatementApplication").println(); for (p in m.closure(p|p.getPackagedElements() ->select(p|p.isKindOf(uml::Package))).including(m)) { ("Generating View for "+p.name).println(); var d = p.fillDiagram(); } addStereotypeAnnotationsToShapes(); "Done".println(); /* Operations on Notation Model Elements */ operation Diagram getDecorationNode() : DecorationNode { return self.children.selectOne(s|s.isKindOf(notation::Shape) and s.type="2007").children.selectOne(e|e.isKindOf(notation::DecorationNode) and e.type="7016"); } operation Diagram getShapes() : Set(Shape) { return self.getDecorationNode().children. select(e|e.isKindOf(notation::Shape)).includingAll(self.children. select(e|e.isKindOf(notation::Shape))); } operation Diagram getShapes(type : String) : Set(Shape) { return self.getShapes().select(s|s.type=type); } operation Diagram getConnectedShapes() : Set(Shape) { return self.edges.collect(c|Set{c.source,c.target}).flatten().asSet(); } operation Diagram removeUnconnectedShapes() { var shapes = self.getShapes("3010").excludingAll(self.getConnectedShapes()); for (s in shapes) { s.println("Deleting: "); delete s; } } /* Operations on UML Model Elements */ operation Package getDiagram() : Diagram { var d = Diagram.all.selectOne(d|d.children.exists(c|c.element. isKindOf(uml::Package) and c.element = self)); if (not d.isDefined()) { /* TODO*/ d = new Diagram; d.type = "PapyrusUMLClassDiagram"; d.name = self.name; // + "\" mesurementUnit = \"Pixel"; d.measurementUnit = notation::MeasurementUnit#Pixel; var s = new Shape; s.type = "2007"; d.children.add(s); var dn = new DecorationNode; dn.type = "5026"; s.children.add(dn); dn = new DecorationNode; dn.type = "7016"; s.children.add(dn); s.element = self; var b = new Bounds; s.layoutConstraint = b; b.x = 0; b.y = 0; b.width = 800; b.height = 400; var st = new DiagramStyle; d.styles.add(st); d.element = uml::Model.all.selectOne(m|m.name = "PcpModel_for_Pcm_SalaryStatementApplication"); } return d; } operation Package fillDiagram() : Diagram { var d = self.getDiagram(); d.children.first().addStereotypeAnnotations(); var elems = self.getPackagedElements(); ("% "+self).println(); for (e in elems) { (" "+e).println(); ("Considering "+e.name).println(); if (e.isKindOf(uml::Class)) { e.getShape(d).addStereotypeAnnotations(); } if (e.isKindOf(uml::Property)) { e.getShape(d).addStereotypeAnnotations(); } if (e.isKindOf(uml::Operation)) { e.getShape(d).addStereotypeAnnotations(); } if (e.isKindOf(uml::Association)) { e.getConnector(d); } if (e.isKindOf(uml::Dependency)) { e.getConnector(d); } } for (e in self.getOwnedComments()) { e.getShape(d).addStereotypeAnnotations(); } //("% % % % % % % % % % %").println(); return d; } operation Class getShape(d:Diagram) : Shape { var s = d.getShapes().selectOne(s|s.element = self); if (not s.isDefined()) { var dn = d.getDecorationNode(); s = new Shape; dn.children.add(s); s.type = "3010"; dn = new DecorationNode; dn.type = "5014"; s.children.add(dn); var bc = new BasicCompartment; s.children.add(bc); bc.type = "7011"; bc.visible = false; var ts = new TitleStyle; bc.styles.add(ts); var ss = new SortingStyle; bc.styles.add(ss); var fs = new FilteringStyle; bc.styles.add(fs); var b = new Bounds; bc.layoutConstraint = b; bc = new BasicCompartment; s.children.add(bc); bc.type = "7012"; bc.visible = false; ts = new TitleStyle; bc.styles.add(ts); ss = new SortingStyle; bc.styles.add(ss); fs = new FilteringStyle; bc.styles.add(fs); b = new Bounds; bc.layoutConstraint = b; bc = new BasicCompartment; s.children.add(bc); bc.type = "7013"; bc.visible = false; ts = new TitleStyle; bc.styles.add(ts); ss = new SortingStyle; bc.styles.add(ss); fs = new FilteringStyle; bc.styles.add(fs); b = new Bounds; bc.layoutConstraint = b; s.element = self; b = new Bounds; s.layoutConstraint = b; b.x = 10; b.y = 10; b.width = 105; b.height = 36; } return s; } operation Property getShape(d:Diagram) : Shape { var s = d.getShapes().selectOne(s|s.element = self); if (not s.isDefined()) { var dn = d.getDecorationNode(); s = new Shape; dn.children.add(s); s.type = "3010"; dn = new DecorationNode; dn.type = "5014"; s.children.add(dn); var bc = new BasicCompartment; s.children.add(bc); bc.type = "7011"; bc.visible = false; var ts = new TitleStyle; bc.styles.add(ts); var ss = new SortingStyle; bc.styles.add(ss); var fs = new FilteringStyle; bc.styles.add(fs); var b = new Bounds; bc.layoutConstraint = b; bc = new BasicCompartment; s.children.add(bc); bc.type = "7012"; bc.visible = false; ts = new TitleStyle; bc.styles.add(ts); ss = new SortingStyle; bc.styles.add(ss); fs = new FilteringStyle; bc.styles.add(fs); b = new Bounds; bc.layoutConstraint = b; bc = new BasicCompartment; s.children.add(bc); bc.type = "7013"; bc.visible = false; ts = new TitleStyle; bc.styles.add(ts); ss = new SortingStyle; bc.styles.add(ss); fs = new FilteringStyle; bc.styles.add(fs); b = new Bounds; bc.layoutConstraint = b; s.element = self; b = new Bounds; s.layoutConstraint = b; b.x = 10; b.y = 10; b.width = 105; b.height = 36; } return s; } operation Operation getShape(d:Diagram) : Shape { var s = d.getShapes().selectOne(s|s.element = self); if (not s.isDefined()) { var dn = d.getDecorationNode(); s = new Shape; dn.children.add(s); s.type = "3010"; dn = new DecorationNode; dn.type = "5014"; s.children.add(dn); var bc = new BasicCompartment; s.children.add(bc); bc.type = "7011"; bc.visible = false; var ts = new TitleStyle; bc.styles.add(ts); var ss = new SortingStyle; bc.styles.add(ss); var fs = new FilteringStyle; bc.styles.add(fs); var b = new Bounds; bc.layoutConstraint = b; bc = new BasicCompartment; s.children.add(bc); bc.type = "7012"; bc.visible = false; ts = new TitleStyle; bc.styles.add(ts); ss = new SortingStyle; bc.styles.add(ss); fs = new FilteringStyle; bc.styles.add(fs); b = new Bounds; bc.layoutConstraint = b; bc = new BasicCompartment; s.children.add(bc); bc.type = "7013"; bc.visible = false; ts = new TitleStyle; bc.styles.add(ts); ss = new SortingStyle; bc.styles.add(ss); fs = new FilteringStyle; bc.styles.add(fs); b = new Bounds; bc.layoutConstraint = b; s.element = self; b = new Bounds; s.layoutConstraint = b; b.x = 10; b.y = 10; b.width = 105; b.height = 36; } return s; } operation Comment getShape(d:Diagram) : Shape { var s = d.getShapes().selectOne(s|s.element = self); if (not s.isDefined()) { var dn = d.getDecorationNode(); s = new Shape; dn.children.add(s); s.type = "3028"; dn = new DecorationNode; dn.type = "5063"; s.children.add(dn); s.element = self; var b = new Bounds; s.layoutConstraint = b; b.x = 10; b.y = 10; b.width = 200; b.height = 100; } return s; } operation Association getConnector(d : Diagram) : notation::Connector { var con = d.edges.selectOne(e|e.element = self); if (con.isDefined()) { return con; } var targetProps = self.navigableOwnedEnd; var sourceProps = self.memberEnd.excludingAll(targetProps); if (targetProps.size() == 1 and sourceProps.size() == 1) { var source : Class; var target : Class; if (self.isDirected()) { source = self.getSource(); target = self.getTarget(); } else { var ends = self.getEnds(); source = ends.at(0); target = ends.at(1); } var targetShape = target.getShape(d); var sourceShape = source.getShape(d); con = new notation::Connector; con.source = sourceShape; con.target = targetShape; con.lineColor = 0; con.type = "4001"; con.element = self; var dn = new notation::DecorationNode; con.children.add(dn); dn.type = "6001"; var l = new notation::Location; dn.layoutConstraint = l; l.x = -22; l.y = 36; dn = new notation::DecorationNode; con.children.add(dn); dn.type = "6002"; l = new notation::Location; dn.layoutConstraint = l; l.y = 20; dn = new notation::DecorationNode; con.children.add(dn); dn.type = "6003"; l = new notation::Location; dn.layoutConstraint = l; l.y = -20; dn = new notation::DecorationNode; con.children.add(dn); dn.type = "6005"; l = new notation::Location; dn.layoutConstraint = l; l.y = 20; dn = new notation::DecorationNode; con.children.add(dn); dn.type = "6033"; l = new notation::Location; dn.layoutConstraint = l; l.y = 20; dn = new notation::DecorationNode; con.children.add(dn); dn.type = "6034"; l = new notation::Location; dn.layoutConstraint = l; l.y = -20; var fs = new notation::FontStyle; fs.fontName = "Arial"; con.styles.add(fs); var rb = new notation::RelativeBendpoints; con.bendpoints = rb; rb.points=Sequence{}; d.edges.add(con); return con; } else { //1. Create Shape connecting the dependency branches var ddn = d.getDecorationNode(); var s = new notation::Shape; s.type = "2015"; s.element = self; ddn.children.add(s); var l = new notation::Location; s.layoutConstraint = l; l.x = 100; l.y = 100; //2. Create edges from sources to Shape for (sourceProp in sourceProps) { var sourceShape = sourceProp.type.getShape(d); var targetShape = s; con = new notation::Connector; con.source = sourceShape; con.target = targetShape; con.type = "4019"; con.element = self; var dn = new notation::DecorationNode; con.children.add(dn); dn.type = "6024"; l = new notation::Location; dn.layoutConstraint = l; l.y = -20; dn = new notation::DecorationNode; con.children.add(dn); dn.type = "6035"; l = new notation::Location; dn.layoutConstraint = l; l.y = 20; var fs = new notation::FontStyle; fs.fontName = "Arial"; con.styles.add(fs); var eovs = new notation::EObjectValueStyle; eovs.name = "Semantic_Branch_Style"; eovs.eObjectValue = sourceProp; var rb = new notation::RelativeBendpoints; con.bendpoints = rb; rb.points=Sequence{}; d.edges.add(con); } //2. Create edges from Shape to target for (targetProp in targetProps) { var targetShape = targetProp.type.getShape(d); var sourceShape = s; con = new notation::Connector; con.source = sourceShape; con.target = targetShape; con.type = "4019"; con.element = self; var dn = new notation::DecorationNode; con.children.add(dn); dn.type = "6024"; var l = new notation::Location; dn.layoutConstraint = l; l.y = -20; dn = new notation::DecorationNode; con.children.add(dn); dn.type = "6035"; l = new notation::Location; dn.layoutConstraint = l; l.y = 20; var fs = new notation::FontStyle; fs.fontName = "Arial"; con.styles.add(fs); var eovs = new notation::EObjectValueStyle; eovs.name = "Semantic_Branch_Style"; eovs.eObjectValue = targetProp; var rb = new notation::RelativeBendpoints; con.bendpoints = rb; rb.points=Sequence{}; d.edges.add(con); } } } operation Dependency getConnector(d : Diagram) : notation::Connector { var con = d.edges.selectOne(e|e.element = self); if (con.isDefined()) { return con; } var sources = self.client; var targets = self.supplier; if (sources.size() == 1 and targets.size() == 1) { var source = sources.first(); var target = targets.first(); var sourceShape = source.getShape(d); var targetShape = target.getShape(d); con = new notation::Connector; con.source = sourceShape; con.target = targetShape; con.lineColor = 0; con.type = "4008"; con.element = self; var dn = new notation::DecorationNode; con.children.add(dn); dn.type = "6026"; var l = new notation::Location; dn.layoutConstraint = l; l.x = -22; l.y = 36; dn = new notation::DecorationNode; con.children.add(dn); dn.type = "6027"; l = new notation::Location; dn.layoutConstraint = l; l.x = -13; l.y = 20; var fs = new notation::FontStyle; fs.fontName = "Arial"; con.styles.add(fs); var rb = new notation::RelativeBendpoints; con.bendpoints = rb; rb.points=Sequence{}; d.edges.add(con); return con; } else { //1. Create Shape connecting the dependency branches var ddn = d.getDecorationNode(); var s = new notation::Shape; s.type = "2014"; s.element = self; ddn.children.add(s); var dn = new notation::DecorationNode; dn.type = "1"; var l = new notation::Location; dn.layoutConstraint = l; s.children.add(dn); l.x = -7; l.y = 30; l = new notation::Location; s.layoutConstraint = l; l.x = 50; l.y = 50; //2. Create edges from sources to Shape for (source in sources) { var sourceShape = source.getShape(d); var targetShape = s; con = new notation::Connector; con.source = sourceShape; con.target = targetShape; con.type = "4018"; con.element = self; var fs = new notation::FontStyle; fs.fontName = "Arial"; con.styles.add(fs); var rb = new notation::RelativeBendpoints; con.bendpoints = rb; rb.points=Sequence{}; d.edges.add(con); } //3. Create edges from Shape to target for (target in targets) { var targetShape = target.getShape(d); var sourceShape = s; con = new notation::Connector; con.source = sourceShape; con.target = targetShape; con.type = "4018"; con.element = self; var fs = new notation::FontStyle; fs.fontName = "Arial"; con.styles.add(fs); var rb = new notation::RelativeBendpoints; con.bendpoints = rb; rb.points=Sequence{}; d.edges.add(con); } return con; } } operation removeEdgesNotExistingInUMLModel() { //Diagram.all.edges.flatten().println(); var edges = Diagram.all.edges.flatten().select(e| not e.element.isDefined() or not e.element.name.isDefined()); //edges.println(); for (e in edges) { delete e; } } operation Shape addStereotypeAnnotations() { var e = self.element; if (e.isDefined()) { var stereos = e.getAppliedStereotypes().qualifiedName.asOrderedSet(); if(not stereos.isEmpty()) { var stereotypeAnnotations = self.eAnnotations.select(n|n.isDefined() and n.source="Stereotype_Annotation"); if (stereotypeAnnotations.isEmpty()){ var eAnn = new EAnnotation; self.eAnnotations.add(eAnn); eAnn.source="Stereotype_Annotation"; var es = new EStringToStringMapEntry; eAnn.details.add(es); es.key="StereotypeWithQualifiedNameList"; es.value=""; es = new EStringToStringMapEntry; eAnn.details.add(es); es.key="StereotypeList"; es.value=""; es = new EStringToStringMapEntry; eAnn.details.add(es); es.key="Stereotype_Presentation_Kind"; es.value="HorizontalStereo"; es = new EStringToStringMapEntry; eAnn.details.add(es); es.key="PropStereoDisplay"; es.value=""; es = new EStringToStringMapEntry; eAnn.details.add(es); es.key="StereotypePropertyLocation"; es.value="Compartment"; stereotypeAnnotations = self.eAnnotations. select(n|n.isDefined() and n.source="Stereotype_Annotation"); } var stereotypeList = stereotypeAnnotations.collect(n|n.details. select(e|e.isDefined() and e.key="StereotypeList")). flatten().first(); if (stereotypeList.isDefined()) { stereotypeList.value = stereos.removeAt(0); for (st in stereos) { stereotypeList.value = stereotypeList.value + "," + st; } } } } } operation addStereotypeAnnotationsToShapes() { for (s in ProPManPatternModel!Shape.all.select(s|s.element.isDefined())) { s.addStereotypeAnnotations(); } } /* */ operation Element showStereotypePropertiesAsComment() { //var d = self.owner.getDiagram(); for (d in Diagram.all.select(d|d.edges.exists(e|e.element = self))) { self.showStereotypePropertiesAsComment(d); } } operation Element showStereotypePropertiesAsComment(d : Diagram) { if (not self.isKindOf(Dependency) and not self.isKindOf(Association)) { break; } var con = self.getConnector(d); /** First add/update the eAnnotations of the Dependency to show the stereotype properties as comment */ var stereos = self.getAppliedStereotypes().asOrderedSet(); if(not stereos.isEmpty()) { var stereotypeAnnotations = con.eAnnotations.select(n|n.isDefined() and n.source="Stereotype_Annotation"); if (stereotypeAnnotations.isEmpty()){ var eAnn = new EAnnotation; con.eAnnotations.add(eAnn); eAnn.source="Stereotype_Annotation"; var es = new EStringToStringMapEntry; eAnn.details.add(es); es.key="StereotypeWithQualifiedNameList"; es.value=""; es = new EStringToStringMapEntry; eAnn.details.add(es); es.key="StereotypeList"; es.value=""; es = new EStringToStringMapEntry; eAnn.details.add(es); es.key="Stereotype_Presentation_Kind"; es.value="HorizontalStereo"; es = new EStringToStringMapEntry; eAnn.details.add(es); es.key="PropStereoDisplay"; es.value=""; es = new EStringToStringMapEntry; eAnn.details.add(es); es.key="StereotypePropertyLocation"; es.value="Comment"; stereotypeAnnotations = con.eAnnotations.select(n|n.isDefined() and n.source="Stereotype_Annotation"); } var propStereoDisplay = stereotypeAnnotations.collect(n|n.details. select(e|e.isDefined() and e.key="PropStereoDisplay")). flatten().first(); if (propStereoDisplay.isDefined()) { stereos = self.getAppliedStereotypes().asOrderedSet(); propStereoDisplay.value = stereos.removeAt(0).getPropertyList(); for (st in stereos) { propStereoDisplay.value = propStereoDisplay.value + "," + st.getPropertyList(); } } /** Second we add/select the Comment to show the stereotype properties of the Dependency */ var dn = d.getDecorationNode(); //var comments = Shape.all.select(c|c.type="AppliedStereotypesComment"); var comments = dn.children.select(c|c.type="AppliedStereotypesComment"); comments = comments.select(c|c.styles. selectOne(s|s.isKindOf(notation::EObjectValueStyle) and s.name="BASE_ELEMENT").eObjectValue = self); //comments.println(); var comment = comments.first(); if (not comment.isDefined()) { comment = new Shape; comment.type = "AppliedStereotypesComment"; comment.element = null; dn.children.add(comment); var eAnn = new EAnnotation; comment.eAnnotations.add(eAnn); eAnn.source="Stereotype_Annotation"; var es = new EStringToStringMapEntry; eAnn.details.add(es); es.key="StereotypeWithQualifiedNameList"; es.value=""; es = new EStringToStringMapEntry; eAnn.details.add(es); es.key="StereotypeList"; es.value=""; es = new EStringToStringMapEntry; eAnn.details.add(es); es.key="Stereotype_Presentation_Kind"; es.value="HorizontalStereo"; es = new EStringToStringMapEntry; eAnn.details.add(es); es.key="PropStereoDisplay"; es.value=""; es = new EStringToStringMapEntry; eAnn.details.add(es); es.key="StereotypePropertyLocation"; es.value="Compartment"; stereotypeAnnotations = comment.eAnnotations. select(n|n.isDefined() and n.source="Stereotype_Annotation"); var propStereoDisplay = stereotypeAnnotations.collect(n|n.details. select(e|e.isDefined() and e.key="PropStereoDisplay")). flatten().first(); if (propStereoDisplay.isDefined()) { stereos = self.getAppliedStereotypes().asOrderedSet(); propStereoDisplay.value = stereos.removeAt(0).getPropertyList(); for (st in stereos) { propStereoDisplay.value = propStereoDisplay.value + "," + st.getPropertyList(); } } var ts = new TitleStyle; ts.showTitle = true; comment.styles.add(ts); var ovs = new EObjectValueStyle; ovs.name = "BASE_ELEMENT"; ovs.eObjectValue = self; comment.styles.add(ovs); var b = new Bounds; b.x = 300; b.y = 50; comment.layoutConstraint = b; } /** Finally, we add the link between the Comment and the Dependency if not existing */ var link = d.edges.select(c|c.type="AppliedStereotypesCommentLink"). selectOne(c|c.source = con and c.target = comment); if (not link.isDefined()) { link = new notation::Connector; link.type = "AppliedStereotypesCommentLink"; link.source = con; link.target = comment; var fs = new FontStyle; link.styles.add(fs); var ovs = new EObjectValueStyle; ovs.name = "BASE_ELEMENT"; ovs.eObjectValue = self; link.styles.add(ovs); var rb = new notation::RelativeBendpoints; link.bendpoints = rb; rb.points=Sequence{}; link.element = null; d.edges.add(link); } } } operation ProPAnMarkUp() { var relatedTo = uml::Dependency.all.select(d| not d.getStereotypeApplications("relatedTo").isEmpty()); var contains = uml::Association.all.select(d| not d.getStereotypeApplications("contains").isEmpty()); var linkableToD = uml::Dependency.all.select(d| not d.getStereotypeApplications("linkableTo").isEmpty()); var linkableToA = uml::Association.all.select(d| not d.getStereotypeApplications("linkableTo").isEmpty()); var derivedFrom = uml::Dependency.all.select(d| not d.getStereotypeApplications("derivedFrom").isEmpty()); var showProps = relatedTo.includingAll(contains). includingAll(linkableToD).includingAll(linkableToA). includingAll(derivedFrom); var packages = Package.all.select(p| not (p.getStereotypeApplications("PersonalInformationDiagram").isEmpty() and p.getStereotypeApplications("AvailableInformationDiagram").isEmpty())); for (p in packages) { //p.println(); var phens = p.getStereotypeInstances("relatedTo"). collect(r|r.base_Dependency.client.first()); phens.addAll(p.getStereotypeInstances("linkableTo"). collect(r|r.base_Dependency.client.first())); //phens.println(); var cons = contains.select(c | phens.includes(c.getSource()) and phens.includes(c.getTarget())); cons.addAll(derivedFrom.select(c|phens.includesAll(c.supplier) and phens.includes(c.client.first()))); //cons.println(); var d = p.getDiagram(); for (a in cons) { //("Called for: "+p+" and "+a).println(); a.getConnector(d); } } for (d in showProps) { d.showStereotypePropertiesAsComment(); } }