Sparx Systems Forum
Enterprise Architect => Automation Interface, Add-Ins and Tools => Topic started by: Edoardo on August 12, 2009, 01:14:51 am
-
Hi all,
I'm writing a plugin in C# for EA.
The goal of this application is to create an UML class diagram in an EA project starting from a set of functional requirements.
Basically this plugin takes in input some requirements in a project in EA and their relations (requires, excludes, extends), it generates a list of objects that represent a Feature Diagram of a Product Line.
The features of the product line are then organized in classes and groups which have properties, gerarchy and so on.
The algorithms for creating the objects are just ready.
I would like to learn how can I use the API to create a C# code that make me create and manipulate UML classes, stereotypes and constraints.
Thank you in advance.
Edoardo.
-
Ok, maybe I made it more complicated that it is.
All I need to do now is to create a UML class diagram from scratch using C# code in my plugin.
Could someone give me a starting point?
Thanks.
-
If all you need to do is designate a newly created diagram as a Class Diagram, that should be easy.
Create the diagram using the AddNew method of the parent package (or element). Set the Type parameter to "Logical" to specify a Class Diagram.
Or do you mean something else?
-
Yes, but I need to do it using the SDK. I need to write in C# some code that does the job and embed it into the plugin I'm developing.
-
It's really not that hard to create a class using the API.
Here are the steps you should take to create a class in a package.
- get a reference to the repository: If you are using an add-in you get the Repository in the "EA_MenuClick" operation.
- select the package you want:
EA.Package myPackage = Repository.Repository.GetPackageByID(123)
- add a class to the package
EA.Element myNewClass = (EA.Element)myPackage.Elements.AddNew("ClassName","Class")
- save the class
myNewClass.Update();
Hope this helps
Geert
-
Hmm, should have read you question more carefully. (I thought you needed to create a class, not a class diagram)
Anyway the same principle is used but not you are not adding an Element in the Elements collection, but a diagram in the Diagrams collection:
EA.Diagram myDiagram = (EA.Diagram)myPackage.Diagrams.AddNew("myDiagramName","Logical")
myDiagram.Update()
-
Geert's code is right on the mark. [No surprise there!]
One thing to pay close attention to is the cast to EA.Diagram - Geert's example does this. The AddNew method of any EA collection returns a result of object type. You must cast this to the appropriate type before you use it in your code. [Unless you are using a weakly typed language of course.]
-
Thanks a lot!
now I only need to learn how to populate the diagram just created, inserting classes and relationships among them.
-
You are most of the way there Edoardo,
Look up the DiagramObject and DiagramLink classes in the SDK. Remember that these are representations of the elements in your model, not the elements themselves. Thus you can have many DiagramObject instances (on several diagrams) for a given element. Use the ElementID (or ConnectorID) property of the DiagramObject (or DiagramLink) to specify what it represents.
Once you get started you'll figure out the rest in no time.
David
-
Ok, I almost got it, but an example would really really be helpful.
Suppose I need to represent this situation:
- there are three classes: A, B, C
- B and C extends A
By now I only know how to create the diagram, the classes and how to insert them into the diagram.
But what about the links between them and their constraints?
More important: what's the code to set multiplicity (like 0...1 or 0...*) to the UML associations?
Would you be so kind to show me some code?
Thanks a lot!
-
To get the relations between elements you need the
"Element.Connectors". These contain all kinds of relation between different elements.
Each of those Connectors has a Type field which indicates whether it is a "Generalization", "Association", etc..
To find all Connectors between two given Elements you loop all the connectors of an element and compare the "SupplierID" and "ClientID" with the Element.ElementID.
Once you have found a Connector which you wish to show on your diagram you add a DiagramLink to the Diagram.DiagramLinks collection.
Set the DiagramLink.ConnectorID to the Connector.ConnectorID.
The multiplicity of association can be set in the ConnectorEnd of the Connector.
The field ConnectorEnd.Cardinality contains this information in a string format.
Hope this helps
Geert
-
And one more thing.
Sometimes you will need to create a connector - this is not the same thing as adding a DiagramLink representing a connector that already exists; but once you get a diagram going missing connectors can quickly become evident. When you do so, remember to first add the connector to the Connectors collection of one element; this sets the ClientID of the new connector to the ElementID of the element that owns the collection. Next set the SupplierID of the connector to the ElementID of the element at the other end of the connector (which might be the same as the client end, making the connector a self reference). Then save the connector to the EA schema by calling the connector's Update method. This is one case where you must set an additional property before calling Update the first time.
The above does not apply when adding a new DiagramLink to a diagram. Remember that this merely draws a representation of a connector that must already exist in the model. [Even if you just added the connector via the above method it has to be created before you reference it on a diagram.] When adding a DiagramLink you create the link and set the ConnectorID attribute, then call Update to save the new link. Since the connector itself must already have a valid client and supplier the DiagramLink provides EA with (a pathway to) all the information needed to draw the link.
HTH, David
-
Thanks a lot to everybody for the help!
-
Once I've created the diagram, I would like to order it's element. In EA there is the command Diagram->Layout Diagram.
Can I do that from the API automatically?
-
I think its located in the project interface.
Geert
-
Yes I found it, is project.layoutDiagram. Thanks.
How can I access to the project object to call it's method, assuming I'm handling a Diagram or a Package in it?
-
through the repository object.
Geert
-
ok, thanks, I used this statement:
this.repository.GetProjectInterface().LayoutDiagram(diagram.DiagramGUID, 1);
the integer is layoutStyle. Do you know what integer i should insert to obtain the same effect as I get using the EA menu Layout Diagram?
When I use "1" it seems somehow different...
-
No sorry, I don't use the autolayout functions so I wouldn't know.
But isn't there a mapping somewhere in the documentation between the numbers and the layout styles?
Geert
-
I do not know where to find the documentation... Maybe I was looking in the wrong places, could you please give me a link? Thanks a lot!
-
Look here: http://www.sparxsystems.com/uml_tool_guide/sdk_for_enterprise_architect/project_2.html
for LayoutDiagramEx
Geert
-
Here I am again,
I cannot find a way to modify, by API, the appearance of the classes in the Diagram. I would like to change background color and, mostly important, the dimensions.
Can you help me?
Many thanks!
-
look into the DiagramObject and its properties.
Geert
-
I am trying to change color of a Connector, but it seems to produce no results.
I'm calling
connector.color = 255 000000() //which is red
connector.update();
I got no results from theese statements.
Any ideas?
thanks
-
Hi again,
when I try to connect a class to another using "composition" with this statement:
EA.Connector con1 = (EA.Connector)associazione.Connectors.AddNew("", "Composition");
con1.SupplierID = madre.ElementID;
con1.Update();
in my diagram appears an aggregation relation instead (a white diamond)
How can I create a real composition connector (black diamond)?
thanks a lot
-
Hi,
I would like to change the route style of my diagram connectors via automation interface. I need them to be routed with "vertical" style.
I tried with the following code but it has no effect:
con2.RouteStyle = 4;
con2.Update();
(con2 is an EA.Connector)
Can you help me please?
-
Hi Edoardo,
Did you already try to update/refresh the diagram where these connectors appear?
Just a guess ...
WBR
Günther
-
Hi Edoardo,
Did you already try to update/refresh the diagram where these connectors appear?
Just a guess ...
WBR
Günther
Yes I did...
-
Hi Edoardo,
Did you already try to update/refresh the diagram where these connectors appear?
Just a guess ...
WBR
Günther
Yes I did...
Any clues?
-
I would try to create a DiagramLink and set the layout options on that one.
Geert
-
I would try to create a DiagramLink and set the layout options on that one.
Geert
Done, but the layout option entry is not documented, I don't really know how to set it.
I tried something but it has no effect at all.
-
Hi again, please help me with this
when I try to connect a class to another using "composition" with this statement:
Code:
EA.Connector con1 = (EA.Connector)associazione.Connectors.AddNew("", "Composition");
con1.SupplierID = madre.ElementID;
con1.Update();
in my diagram appears an aggregation relation instead (a white diamond)
How can I create a real composition connector (black diamond)?
thanks a lot
-
It could be that you have to set the aggregationKind of the connectorEnd to the appropriate value ("Composite").
Geert
-
It could be that you have to set the aggregationKind of the connectorEnd to the appropriate value ("Composite").
Geert
Sorry, I cannot find the aggregationKind entry in con1.SupplierEnd
-
[size=18]...[/size]
EA.Connector con1 = (EA.Connector)associazione.Connectors.AddNew("", "Composition");
[size=18]...[/size]
Hi Edoardo,
According to the EA Help, "Composition" is not a valid type here. The Connector Type needed is "Aggregation"
The AggregationKind is represented by the Aggregation attribute of the appropriate ConnectorEnd.
Valid values are:
0 = None
1 = Shared
2 = Composite.
Be warned though, that your "appropriate end" may be affected by the way you have instructed EA to draw Aggregations.
The general advice by long-term users is to avoid EAAggregations and use ordinary Associations appropriately adorned. If you do a search for Aggregations you find more on this.
Paolo
-
[size=18]...[/size]
EA.Connector con1 = (EA.Connector)associazione.Connectors.AddNew("", "Composition");
[size=18]...[/size]
Hi Edoardo,
According to the EA Help, "Composition" is not a valid type here. The Connector Type needed is "Aggregation"
The AggregationKind is represented by the Aggregation attribute of the appropriate ConnectorEnd.
Valid values are:
0 = None
1 = Shared
2 = Composite.
Be warned though, that your "appropriate end" may be affected by the way you have instructed EA to draw Aggregations.
The general advice by long-term users is to avoid EAAggregations and use ordinary Associations appropriately adorned. If you do a search for Aggregations you find more on this.
Paolo
Thanks a lot, this solved my problem!