Author Topic: Find in all diagrams via API  (Read 4245 times)

bctm

  • EA Novice
  • *
  • Posts: 14
  • Karma: +0/-0
    • View Profile
Find in all diagrams via API
« on: September 27, 2012, 10:04:48 pm »
Hi Community,

I'm searching for a way to access the "find in all diagrams" functionality via the API. I suspect that this performs a search for the component in all existing diagrams? Or is there any kind of direct connection between a component and the diagram I didn't notice?

The rationale for my question is that I want to check whether the component is used in a special kind of diagram (i.e. a sequence diagram) - if so, some magic should happen.

Thank you in advance,
bctm

Geert Bellekens

  • EA Guru
  • *****
  • Posts: 13402
  • Karma: +566/-33
  • Make EA work for YOU!
    • View Profile
    • Enterprise Architect Consultant and Value Added Reseller
Re: Find in all diagrams via API
« Reply #1 on: October 01, 2012, 04:59:30 pm »
Your component is an EA.Element, and it is connected to an EA.Diagram by means of a EA.DiagramObject.

Now you could of course loop through all diagrams of your project, loop through all DiagramObject in  Diagram.DiagramObjects and check whether or not it represents your object, but that will easily take minutes if not hours for a large model.

If is a lot more efficient (as in seconds rather then minutes) to use SQL for that purpose.

This part of the ElementWrapper class does exactly that:

Code: [Select]
   //returns a list of diagrams that somehow use this element.
    public override HashSet<T> getUsingDiagrams<T>()
    {
        string sqlGetDiagrams = @"select distinct d.Diagram_ID from t_DiagramObjects d
                                  where d.Object_ID = " + this.wrappedElement.ElementID;
        List<UML.Diagrams.Diagram> allDiagrams = this.model.getDiagramsByQuery(sqlGetDiagrams).Cast<UML.Diagrams.Diagram>().ToList(); ; ;
        HashSet<T> returnedDiagrams = new HashSet<T>();
        foreach (UML.Diagrams.Diagram diagram in allDiagrams)
        {
            if (diagram is T)
            {
                T typedDiagram = (T)diagram;
                if (!returnedDiagrams.Contains(typedDiagram))
                {
                    returnedDiagrams.Add(typedDiagram);
                }
            }
        }
        return returnedDiagrams;
    }

Geert

bctm

  • EA Novice
  • *
  • Posts: 14
  • Karma: +0/-0
    • View Profile
Re: Find in all diagrams via API
« Reply #2 on: October 02, 2012, 01:07:57 am »
Hi Geert,

thank you very much for your reply. I was using the iterate-over-all-diagrams approach and it took much too long for our model. Therefore I tried to distribute the task into threads, but somehow I couldn't get it running. Does the EA support threading with API calls? The thread froze when it tried to call an API function.

Anyway, this problem isn't that important anymore since I'll try to use your SQL query instead of my multi-thread approach - even though it would be interesting whether this would be possible.

Thanks again and I will get back to you as soon as this approach works :- )

Geert Bellekens

  • EA Guru
  • *****
  • Posts: 13402
  • Karma: +566/-33
  • Make EA work for YOU!
    • View Profile
    • Enterprise Architect Consultant and Value Added Reseller
Re: Find in all diagrams via API
« Reply #3 on: October 02, 2012, 01:45:14 am »
I'm not sure about the multi-thread approach.
I think there's only one EA application object, and one database engine, so I think your threads get queued anyway.

I think as long as you have one thread dealing with EA, and maybe another tread dealing with your GUI that might just work. I think I'm going to try that in the near future to improve the performance of the EA Navigator. I'll know more after that experiment.

Geert

bctm

  • EA Novice
  • *
  • Posts: 14
  • Karma: +0/-0
    • View Profile
Re: Find in all diagrams via API
« Reply #4 on: October 02, 2012, 03:01:04 am »
Multi-Threading definitely works if you have one Thread for the GUI and one for the EA - I'm already using this to show a progress bar, while the other thread uses the API. But somehow it didn't work when I was trying to use the API with the fork thread.

Anyway, I do have an addition to your code above. While your code covers diagrams that have objects connected as "simple links", it doesn't include objects that were connected via "Instance of Element".
This query should fix it:

Code: [Select]
//C#
// repo is the EA.Repository
repo.SQLQuery(@"select d.Diagram_ID from t_diagramobjects d WHERE d.Object_ID IN  (select o.Object_ID from t_object o where o.Classifier = " + element.ElementID + " )");
I'm taking the elements in the t_object table which have the current element I am checking as "Classifier" (which is the base type of an instance). Then I'm comparing these elements with the t_DiagramObjects table like you did.

Thanks again for your help, this SQLQuery stuff offers a new dimension to my work with the EA. I didn't do that before.