Sparx Systems Forum
Enterprise Architect => Suggestions and Requests => Topic started by: wikitect on December 14, 2009, 07:20:12 pm
-
Searches are necessary when using EA for enterprise architecture as often there is a stronger emphasis on discovering and presenting relationships between classes. In EA relationships are the second class citizens (poor relations ;)) in EA e.g. not appearing in the normal searches, not having the same fields (an Alias for a connector is shoe-horned into a StyleEx field along with all sorts of other things).
Similarly the matrix view of a diagram only lists the classes not the relationships between classes for the diagram so that isn't very helpful.
Whilst I can create a SQL query that lists the objects and relationships between them what EA won't allow me to do is to base the query on the diagram that is selected in the catalogue. If it did then EA could be used to present the matrix equivalent of a diagram with relationships - essential for architecture frameworks.
Of course the next part of the problem is that EA doesn't provide the means to export search results as a CSV (unlike the relationship matrix).
-
I think there is something like an addin-search as well.
Maybe that can be used to search based on the selected diagram?
Geert
-
I think there is something like an addin-search as well.
Maybe that can be used to search based on the selected diagram?
Geert
Geert,
I think the big problem is that while arcs are second class citizens, diagram links are third class. We've already alluded in other topics that there's no collection diagram.DiagramLinks.
As a consequence, there is NO guarantee that for each link are that is visible in the diagram, there is an associated t_DiagramLinks row.
The search may or may not return the right number of rows.
Paolo
-
I seem to recall some discussions a while back about how badly the EA schema is is need of an overhaul ;) ...
-
Hi wikitect, I've created an EA JScript (version 7.5+ is required) that lists all connectors on a diagram in the search window. Hopefully it should satisfy your requirements.
I'm just sorting out my access to the community site, so it should be available from there in an hour or two.
PS: In the future we plan on listing scripts flagged as "Project Browser" scripts in the Project Browser context menu, so that they can be accessed conveniently.
-
PPS: Looks like the script is taking a while to get through the review process for the community site, so I'll post it here.
Please note that due to the 5k word limit I've had to split it over a few posts.
Part 1 of 2
/*
* Script Name: ListDiagramConnectors
*
* Author: Michael Fraser (Sparx Systems)
*
* Purpose: Lists relationships between objects that appear on the diagram that is
* currently selected in the project browser
*
* Date: 2009-12-17
*/
// ==========================================
// GLOBAL DEFINITIONS
// ==========================================
var DIAGRAM_OT = 8;
// The columns that will appear in the Model Search window
var SEARCH_SPECIFICATION = "<ReportViewData>" +
"<Fields>" +
"<Field name=\"CLASSGUID\" />" +
"<Field name=\"CLASSTYPE\" />" +
"<Field name=\"Client\" />" +
"<Field name=\"Supplier\" />" +
"<Field name=\"Direction\" />" +
"<Field name=\"Name\" />" +
"<Field name=\"Notes\" />" +
"<Field name=\"Client Aggregation\" />" +
"<Field name=\"Client Cardinality\" />" +
"<Field name=\"Client Role\" />" +
"<Field name=\"Supplier Aggregation\" />" +
"<Field name=\"Supplier Cardinality\" />" +
"<Field name=\"Supplier Role\" />" +
"</Fields>" +
"<Rows/>" +
"</ReportViewData>";
/*
* Main function
*/
function ListDiagramConnectors()
{
Repository.EnsureOutputVisible( "Script" );
Session.Output( "JScript: List Diagram Relationships" );
Session.Output( "=========================================" );
// Get the type of element selected in the Project Browser
var treeSelectedType = Repository.GetTreeSelectedItemType();
// Handling Code
switch ( treeSelectedType )
{
case DIAGRAM_OT:
{
// Code for when a diagram is selected
var theDiagram as EA.Diagram;
theDiagram = Repository.GetTreeSelectedObject();
// Create a DOM object to represent the search tree
var xmlDOM = new ActiveXObject( "MSXML2.DOMDocument.4.0" );
xmlDOM.validateOnParse = false;
xmlDOM.async = false;
Session.Output( "Working on diagram '" + theDiagram.Name + "' (Type=" +
theDiagram.Type + ", ID=" + theDiagram.DiagramID + ")" );
// Load the search template
if( xmlDOM.loadXML(SEARCH_SPECIFICATION) )
{
// Resolve the results node in the xml template
var node = xmlDOM.selectSingleNode( "//ReportViewData//Rows" );
// A connector has a one to many relationship with diagram (eg one connector
// may appear on many diagrams). The DiagramLink object represents an instance
// of a connector on a single diagram, and contains properties such as its
// geometry, visibility etc.
//
// Get all diagramLinks for this diagram
var diagramLinks as EA.Collection;
diagramLinks = theDiagram.DiagramLinks;
for ( var i = 0 ; i < diagramLinks.Count ; i++ )
{
// Get the current diagram link
var currentLink as EA.DiagramLink;
currentLink = diagramLinks.GetAt( i );
// Load the corresponding connector object for the link
var correspondingConnector as EA.Connector;
correspondingConnector = Repository.GetConnectorByID( currentLink.ConnectorID );
// Add the connector's details to the search data
AddRow( xmlDOM, node, correspondingConnector );
}
// Fill the Model Search window with the results
Repository.RunModelSearch( "", "", "", xmlDOM.xml );
}
else
{
Session.Prompt( "Failed to load search xml", 0 );
}
break;
}
default:
{
// Error message
Session.Prompt( "This script does not support items of this type.", 0 );
}
}
Session.Output( "Done!" );
}
-
Part 2 of 2:
/*
* Adds an entry for the method object 'theRelationship' to the xml row node 'rowsNode'
*/
function AddRow( xmlDOM, rowsNode, theRelationship )
{
// Cast theMethod for intellisense
var relationship as EA.Connector;
relationship = theRelationship;
// Create a Row node
var row = xmlDOM.createElement( "Row" );
// Get client details for the connector
var client as EA.Element;
var clientEnd as EA.ConnectorEnd;
client = Repository.GetElementByID( relationship.ClientID );
clientEnd = relationship.ClientEnd;
// Get supplier details for the connector
var supplier as EA.Element;
var supplierEnd as EA.ConnectorEnd;
supplier = Repository.GetElementByID( relationship.SupplierID );
supplierEnd = relationship.SupplierEnd;
// Add the Model Search row data to our DOM
AddField( xmlDOM, row, "CLASSGUID", relationship.ConnectorGUID );
AddField( xmlDOM, row, "CLASSTYPE", "connector" );
AddField( xmlDOM, row, "Client", client.Name );
AddField( xmlDOM, row, "Client", supplier.Name );
AddField( xmlDOM, row, "Direction", relationship.Direction );
AddField( xmlDOM, row, "Name", relationship.Name );
AddField( xmlDOM, row, "Notes", relationship.Notes );
AddField( xmlDOM, row, "Client Aggregation", clientEnd.Aggregation );
AddField( xmlDOM, row, "Client Cardinality", clientEnd.Cardinality );
AddField( xmlDOM, row, "Client Role", clientEnd.Role );
AddField( xmlDOM, row, "Supplier Aggregation", supplierEnd.Aggregation );
AddField( xmlDOM, row, "Supplier Cardinality", supplierEnd.Cardinality );
AddField( xmlDOM, row, "Supplier Role", supplierEnd.Role );
// Append the newly created row node to the rows node
rowsNode.appendChild( row );
}
/*
* Adds an Element to our DOM called Field which makes up the Row data for the Model Search window.
* <Field name "" value ""/>
*/
function AddField( xmlDOM, row, name, value )
{
var fieldNode = xmlDOM.createElement( "Field" );
// Create first attribute for the name
var nameAttribute = xmlDOM.createAttribute( "name" );
nameAttribute.value = name;
fieldNode.attributes.setNamedItem( nameAttribute );
// Create second attribute for the value
var valueAttribute = xmlDOM.createAttribute( "value" );
valueAttribute.value = value;
fieldNode.attributes.setNamedItem( valueAttribute );
// Append the fieldNode
row.appendChild( fieldNode );
}
ListDiagramConnectors();
-
Thanks for this.
Will have to have a play later and see what happens.
What I was trying to list was
for the visible connectors of a particular stereotype
[* source object attributes - name, alias]
[* connector attributes - name, alias, notes, direction]
[* target object attributes - name, alias]
in order to represent / characterise 'interfaces' (flows of data, energy, materiel)
No doubt some good pickings to be had once I figure out what's going on in the script - not something I've touched in EA yet.
Anyway, good stuff!
Now on to the next suggestion/request wrt relationships .... import...
[/list]
-
Michael - thanks for the script. I got it to run - small step for others but a major leap forward in my learning curve for EA scripting.
Just interested - would it be possible to distinguish - through code - the "visible" connectors from all connectors on a diagram?
-
When interpreting the script, it is important to understand the role of the DiagramLink object. A connector has a one to many relationship with diagram (eg one connector may appear on many diagrams). Whereas a Connector object describes the relationship between two entities, the DiagramLink object represents an instance of a connector on a single diagram, and contains properties such as its geometry, visibility etc.
If it helps, a basic psuedocode of the script would be as such:
START
Construct an XML document that will be sent to the search window (This document will describe both the headings and the data that will be displayed)
Find the currently selected item in the tree
If it's a diagram:
Get the collection of diagramlinks for the diagram
For each diagramlink in the diagram
Get the corresponding connector object for the diagramlink
Add the connector's details to the search data (AddRow function)
Send the search data to the search window and display the results.
END
@wikitect
If you want to add/remove what data is displayed in the search report you must change two things:
1. The XML search template provided in the variable SEARCH_SPECIFICATION (this defines which headings are included in the search window).
2. The script method AddRow (this contains the logic for how the fields are populated). Currently it displays various bits of data for the Connector, Source and Target Objects. Each of these objects has autocomplete intellisense available, so you should easily be able to get a list of what data is available to you. If not, check out the Enterprise Architect SDK for Connectors (http://www.sparxsystems.com/uml_tool_guide/sdk_for_enterprise_architect/connector2_2.html) and Elements (http://www.sparxsystems.com/uml_tool_guide/sdk_for_enterprise_architect/element2.html).
@wikitect and Thelonius
As was mentioned above, the DiagramLink object describes an instance of a Connector on a diagram. The DiagramLink object (http://www.sparxsystems.com/uml_tool_guide/sdk_for_enterprise_architect/diagramlinks.html) has a property called IsHidden which can be used to test whether the Connector is visible on the provided diagram. Therefore you could change the code at around line 88 to the following:
// Only process the diagram link if it is visible on the diagram.
if ( !currentLink.IsHidden )
{
// Load the corresponding connector object for the link
var correspondingConnector as EA.Connector;
correspondingConnector = Repository.GetConnectorByID( currentLink.ConnectorID );
// Add the connector's details to the search data
AddRow( xmlDOM, node, correspondingConnector );
}
I hope that helps, if you have any further questions, don't be afraid to ask! 8-)
-
[size=18]...[/size]
the DiagramLink object represents an instance of a connector on a single diagram, and contains properties such as its geometry, visibility etc.
[size=18]...[/size]
Michael,
Does that mean we're NOW guaranteed that there will exist a DiagramLink for every possible connector on the Diagram? I thought that even recently that STILL wasn't the case?
Last time it was mentioned, within the last two months by Neil I think, he still admitted that a DiagramLink may not exist if you haven't done something to the connector to change it from the default.
I'd like to get a definitive answer (for build 850 at least).
Paolo
-
I've just had that chat with Neil myself and it turns out that I was misinformed. From what I understand now, the DiagramLinks collection won't have an entry for Connectors on the diagram that haven't been modified beyond their default settings.
We've had a chat about this, and came to the consensus that the DiagramLinks collection should contain all connector instances on the diagram, regardless of whether they are using their default settings or not. We came up with a fairly simple way to achieve this, so I'll look at getting it implemented ASAP.
-
I've just had that chat with Neil myself and it turns out that I was misinformed. From what I understand now, the DiagramLinks collection won't have an entry for Connectors on the diagram that haven't been modified beyond their default settings.
We've had a chat about this, and came to the consensus that the DiagramLinks collection should contain all connector instances on the diagram, regardless of whether they are using their default settings or not. We came up with a fairly simple way to achieve this, so I'll look at getting it implemented ASAP.
Thanks, Michael,
It's only taken 3 years...
Does that mean you'll also be able to implement a DiagramObject.DiagramLinks collection as mentioned in Need DiagramObject.DiagramLinks collection (http://www.sparxsystems.com/cgi-bin/yabb/YaBB.cgi?num=1248939760)?
Paolo
-
At first glance I can't see why not, but I'd really need to chat to those who have said it can't be done and get a better understanding as to how they got to that opinion.
So I wouldn't rule it out for the future, but for the short term, "No, you can't have it" (Midnight, 2009).