12
votes

We have a large project and I am using Enterprise Architect version 10 to reverse engineer a small package within the project into UML for the purposes of refactoring. I want to only include elements that will be contained within the diagrams I am going to create (I know this is stupid, but we can't have 1 model to rule them all).

I would like to reverse all the source and then delete all elements that do not end up on my diagrams. Is there a way to do this? I know that I can find any given element in the diagrams from the GUI, so would there at least be a way to script this?

The alternative is to manually pick all dependencies and reverse only those files, which I may end up doing.

Thanks

4

4 Answers

23
votes

EA comes with a built-in search called "Find Orphans". This will list all elements that do not appear on a diagram. You can run this search (Ctrl+Alt+A, select "Diagram Searches" from the first list box and "Find Orphans" from the second list box and click Run), select all the results (Ctrl+A) and delete all (Ctrl+Del). However, this is at your own risk - there is nothing wrong with an element being in the model but not on any diagrams.

2
votes

Yes, you can script this. It will be a little involved, but it can be done.

There's no immediate API support to find what you're looking for so you'll need to go into the database to find all elements that are not shown in any diagrams. Once you've done that, you can delete each such element from its containing package.

Elements are stored in t_object and diagram objects (the graphical representation of one element in one diagram) in t_diagramobjects. An entry in t_diagramobjects has a reference to the diagram (Diagram_ID) and to the element being displayed (Object_ID).

(If you're new to EA hacking, yes, they're called Elements in the API and Objects in the database. Just a fact of life.)

So:

  1. Find all t_object.Object_ID which do not occur in t_diagramobjects.Object_ID.
  2. Loop through this set and, using Repository.GetElementByID(), retrieve each Element.
  3. Fetch the element's containing package using Repository.GetPackageByID(element.PackageID).
  4. Spin through the package's Elements collection using GetAt() in a for loop, find the Element whose ElementID matches the one you're after and Delete() it. Don't forget to Refresh() the collection afterwards.

There is a method Repository.SQLQuery(), which allows you to perform a select query against the database, but you have to parse the result from a single XML string.

It's simpler to use Repository.GetElementsByQuery(), which returns the elements in a Collection, but this requires you to predefine the query as an EA search. If you use this, you can skip steps 1 and 2 above.

Of course, you could go straight into the database and simply delete all those t_object rows which are not referred to from t_diagramobjects. This is a terribly bad idea which will (I'm pretty sure) leave you with a corrupted database. When you use the API to delete things, EA cleans up all references (so no connectors are left dangling, etc).

And of course, you should only unleash a script like this if you are absolutely sure there are no other elements that aren't shown in diagrams that need to be kept. So a temp project for this is probably a good idea.

Note, finally, that packages are also elements, and if you don't want to lose all your imported source in one fell swoop by deleting the package they're in (because the package itself is typically not shown in a diagram, is it?) you should probably exclude t_object.Object_Type / Element.Type "Package".

2
votes

I know this is old but I think I have something to contribute :)

The simplest answer has already been given and it is the "Find Orphans" thingy. Now while cleaning a big EA repository I inherited I noticed there are cases where a given object may not be in a diagram but a child object will. In this case you don't want to be cleaning the parent object or you may lose the child.

So I crafted the following search:

select 
    o.ea_guid as CLASSGUID, o.object_type as CLASSTYPE, * 
from 
    t_object o 
where 
        o.Object_Type != 'Package' 
    and
        not exists (select t_diagramobjects.Diagram_ID from  t_diagramobjects where t_diagramobjects.Object_ID = o.object_ID)
    and
        not exists (select t2.OBJECT_ID from t_object t2 where t2.PARENTID=o.OBJECT_ID) 

It will only return "orphans that don't have a parent". Of course it could be improved to only return "orphans that don't have a parent that is itself an orphan" but I did not need that and could do some manual work...

(you access the SQL Search interface by Control+F/Builder/SQL)

1
votes

The user interface in Enterprise Architect version 12 appears to have changed slightly for finding orphaned elements.

  1. Ctrl + F to "Find in Project".
  2. Select "Diagram Searches" from the Search Category drop down.
  3. Select "Find Orphans" from the Search drop down.
  4. Leave blank to find all orphans.
  5. Click Run or press Enter.