Author Topic: Enterprise Architect API DiagramObject Update Fails  (Read 5318 times)

arunraj

  • EA Novice
  • *
  • Posts: 6
  • Karma: +0/-0
    • View Profile
Enterprise Architect API DiagramObject Update Fails
« on: July 21, 2018, 05:26:37 pm »
I am using the EA COM API via C# and trying to create the following hierarchy model:
Code: [Select]
Root (Package)
|
|--RootDiagram (Diagram:CompositeStructure)
|
|--TopPart (Element:Part, IsComposite=true)
    |
    |--TopPartDiagram (Diagram:CompositeStructure)
    |
    |--SubPart (Element:Part)
        |
        |-Port (Element:Port)

I use the Diagram.DiagramObjects.AddNew interface to add:
  • TopPart to the RootDiagram
  • SubPart to the TopPartDiagram
  • Port to the TopPartDiagram
Unfortunately the DiagramObject.Update succeeds only for 1 and 2. When I try to add the Port element, the process crashes with exception.

Via the GUI, I can add it by right clicking the SubPart and selecting Structural Elements. Why can't the automation API do the same thing?

qwerty

  • EA Guru
  • *****
  • Posts: 13584
  • Karma: +396/-301
  • I'm no guru at all
    • View Profile
Re: Enterprise Architect API DiagramObject Update Fails
« Reply #1 on: July 21, 2018, 06:00:37 pm »
That just sounds weird. DiagamObjects are used to put existing element in a diagram. To create them you first have to create the elements.

q.

arunraj

  • EA Novice
  • *
  • Posts: 6
  • Karma: +0/-0
    • View Profile
Re: Enterprise Architect API DiagramObject Update Fails
« Reply #2 on: July 22, 2018, 04:31:11 am »
I did not describe the entire steps because I thought those were obvious. Anyway for better clarity, here is the complete code:

Code: [Select]
EA.Repository oRepository = new EA.Repository();

oRepository.OpenFile("C:\\test.eap");

EA.Package oModel = (EA.Package)oRepository.Models.AddNew("Test", "");
if(!oModel.Update()) { Console.WriteLine("Error"); }

EA.Package oRootPackage = (EA.Package)oModel.Packages.AddNew("Root", "");
if(!oRootPackage.Update()) { Console.WriteLine("Error"); }

EA.Diagram oRootDiagram = (EA.Diagram)oRootPackage.Diagrams.AddNew("RootDiagram", "CompositeStructure");
if(!oRootDiagram.Update()) { Console.WriteLine("Error"); }

EA.Element oPartElement = (EA.Element)oRootPackage.Elements.AddNew("TopPart", "Part");
// Setting IsComposite here has weird results - setting it after creating the diagram gives expected result!
// oPartElement.IsComposite = true;
if(!oPartElement.Update()) { Console.WriteLine("Error"); }

EA.DiagramObject oPartDiagramObject = (EA.DiagramObject)oRootDiagram.DiagramObjects.AddNew("", "");
oPartDiagramObject.ElementID = oPartElement.ElementID;
if(!oPartDiagramObject.Update()) { Console.WriteLine("Error"); }

EA.Diagram oPartDiagram = (EA.Diagram)oPartElement.Diagrams.AddNew("TopPartDiagram", "CompositeStructure");
if(!oPartDiagram.Update()) { Console.WriteLine("Error"); }

oPartElement.IsComposite = true;
if(!oPartElement.Update()) { Console.WriteLine("Error"); }

EA.Element oSubPartElement = (EA.Element)oPartElement.EmbeddedElements.AddNew("SubPart", "Part");
if(!oSubPartElement.Update()) { Console.WriteLine("Error"); }

EA.DiagramObject oSubPartDiagramObject = (EA.DiagramObject)oPartDiagram.DiagramObjects.AddNew("", "");
oSubPartDiagramObject.ElementID = oSubPartElement.ElementID;
if(!oSubPartDiagramObject.Update()) { Console.WriteLine("Error"); }

EA.Element oPortElement = (EA.Element)oSubPartElement.EmbeddedElements.AddNew("Port", "Port");
if(!oPortElement.Update()) { Console.WriteLine("Error"); }

EA.DiagramObject oPortDiagramObject = (EA.DiagramObject)oPartDiagram.DiagramObjects.AddNew("", "");
oPortDiagramObject.ElementID = oPortElement.ElementID;
if(!oPortDiagramObject.Update()) { Console.WriteLine("Error"); }

oRepository.CloseFile();
oRepository.Exit();
oRepository = null;

The oPortDiagramObject.Update() is what fails. Am I doing something wrong here?

qwerty

  • EA Guru
  • *****
  • Posts: 13584
  • Karma: +396/-301
  • I'm no guru at all
    • View Profile
Re: Enterprise Architect API DiagramObject Update Fails
« Reply #3 on: July 22, 2018, 07:20:01 pm »
I just tried these steps in V12 and had no issue. Which version are you using?

q.

P.S. you might want to update the question on SO as well.

arunraj

  • EA Novice
  • *
  • Posts: 6
  • Karma: +0/-0
    • View Profile
Re: Enterprise Architect API DiagramObject Update Fails
« Reply #4 on: July 22, 2018, 08:58:09 pm »
That's strange. I tried first with v13 and also with v12. Same results unfortunately.  :(

This what I see from my console:
Code: [Select]
Unhandled Exception: System.Runtime.InteropServices.COMException: The remote procedure call failed. (Exception from HRESULT: 0x800706BE)
   at EA.IDualDiagramObject.Update()
   at Test.Test.Main(String[] args) in C:\Test\Test.cs:line 128
Press any key to continue . . .

When I comment out the creation of oPortDiagramObject, setting the element ID and updating the object, the program works without any troubles. You do not see any such errors or crashes with the same code and can see the Port added to SubPart under the TopPartDiagram?
« Last Edit: July 22, 2018, 09:14:39 pm by arunraj »

qwerty

  • EA Guru
  • *****
  • Posts: 13584
  • Karma: +396/-301
  • I'm no guru at all
    • View Profile
Re: Enterprise Architect API DiagramObject Update Fails
« Reply #5 on: July 22, 2018, 09:14:37 pm »
Actually I did not compile your code, but mimicked it with a short Perl script (only the part where adding the diagram objects). And that worked well.

q.

arunraj

  • EA Novice
  • *
  • Posts: 6
  • Karma: +0/-0
    • View Profile
Re: Enterprise Architect API DiagramObject Update Fails
« Reply #6 on: July 22, 2018, 09:34:32 pm »
Alright. My original program was in JAVA and when I faced the issue, I did not have any valid error messages from the EA JAR library. Hence I decided to replicate the same scenario using C# hoping that the DLL would give me a meaningful error but without success.

I did a bit of experimentation and found that the problem happens exactly with that hierarchy and where I want the DiagramObjects to be added in the diagram. That is why I mentioned it in my first post. What I found was, if I add an intermediate Part element, the code would work! Something like this:

Code: [Select]
Root (Package)
|
|--RootDiagram (Diagram:CompositeStructure)
|
|--TopPart (Element:Part, IsComposite=true)
    |
    |--TopPartDiagram (Diagram:CompositeStructure)
    |
    |--DummyPart  (Element:Part)
        |
        |--SubPart (Element:Part)
            |
            |-Port (Element:Port)

Notice the DummyPart is now the parent and the outermost Part in the diagram. With this, I am able to add the Port to the SubPart via code - it looked to me like a problem with the hierarchy that I want but I do not understand why.

Would it be possible for you to try my exact code? I did not yet attempt to try it via Perl script.

qwerty

  • EA Guru
  • *****
  • Posts: 13584
  • Karma: +396/-301
  • I'm no guru at all
    • View Profile
Re: Enterprise Architect API DiagramObject Update Fails
« Reply #7 on: July 22, 2018, 10:12:21 pm »
I don't have any compiler on Windoze. The only thing I could do would be to run it with  EA's internal J(ava?)Script. But I'm not very fluent in that. So if you try that I could re-run it here to verify if it fails.

q.

arunraj

  • EA Novice
  • *
  • Posts: 6
  • Karma: +0/-0
    • View Profile
Re: Enterprise Architect API DiagramObject Update Fails
« Reply #8 on: July 22, 2018, 10:23:26 pm »
I am not a fan of Windoof either - just stuck with it. :D

Anyway since you said that you have a Perl environment, I wrote a Perl script for my desired scenario. Please see the full script here:

Code: [Select]
#!/usr/bin/perl

use Win32::OLE;

$repo = Win32::OLE->new('EA.Repository', \&OleQuit) or die "Unable to use COM interface";

$repo->OpenFile("C:\\Test\\Test.EAP") or die "File not found";

$models = $repo->{Models};

$myModel = $models->AddNew("Test", "");
$myModel->Update() or die "Error";

$rootPackages = $myModel->{Packages};

$rootPackage = $rootPackages->AddNew("Root", "");
$rootPackage->Update() or die "Error";

$rootPackageDiagrams = $rootPackage->{Diagrams};

$rootPackageDiagram = $rootPackageDiagrams->AddNew("RootDiagram", "CompositeStructure");
$rootPackageDiagram->Update() or die "Error";

$rootPackageElements = $rootPackage->{Elements};

$topPartElement = $rootPackageElements->AddNew("TopPart", "Part");
# Setting IsComposite here has weird results - setting it after creating the diagram gives expected result!
# $topPartElement->IsComposite = true;
$topPartElement->Update() or die "Error";

$rootPackageDiagramObjects = $rootPackageDiagram->{DiagramObjects};

$rootPackageDiagramObject = $rootPackageDiagramObjects->AddNew("", "");
$rootPackageDiagramObject->{ElementID} = $topPartElement->ElementID;
$rootPackageDiagramObject->Update() or die "Error";

$topPartDiagrams = $topPartElement->{Diagrams};

$topPartDiagram = $topPartDiagrams->AddNew("TopPartDiagram", "CompositeStructure");
$topPartDiagram->Update() or die "Error";

$topPartElement->{IsComposite} = true;
$topPartElement->Update() or die "Error";

$topPartEmbeddedElements = $topPartElement->{EmbeddedElements};

$subPartElement = $topPartEmbeddedElements->AddNew("SubPart", "Part");
$subPartElement->Update() or die "Error";

$topPartDiagramObjects = $topPartDiagram->{DiagramObjects};

$subPartDiagramObject = $topPartDiagramObjects->AddNew("", "");
$subPartDiagramObject->{ElementID} = $subPartElement->ElementID;
$subPartDiagramObject->Update() or die "Error";

$subPartEmbeddedElements = $subPartElement->{EmbeddedElements};

$portElement = $subPartEmbeddedElements->AddNew("Port", "Port");
$portElement->Update() or die "Error";

#$portDiagramObject = $topPartDiagramObjects->AddNew("", "");
#$portDiagramObject->{ElementID} = $portElement->ElementID;
#$portDiagramObject->Update() or die "Error";

$repo->CloseFile();
$repo->Exit();

sub OleQuit {
   my $self = shift;
   $self->Exit();
}


The above code works. Next I un-comment and enable the following code section:

Code: [Select]
$portDiagramObject = $topPartDiagramObjects->AddNew("", "");
$portDiagramObject->{ElementID} = $portElement->ElementID;
$portDiagramObject->Update() or die "Error";

This gives: Error at sample.pl line 63. (the exact problem I am having in my JAVA program and C# test program)

qwerty

  • EA Guru
  • *****
  • Posts: 13584
  • Karma: +396/-301
  • I'm no guru at all
    • View Profile
Re: Enterprise Architect API DiagramObject Update Fails
« Reply #9 on: July 23, 2018, 12:18:24 am »
You code has a few syntax errors where you use ->(roundBracket) instead of ->{curlyBracket} but I also see the update failure in the last call. Will have a coffee and start looking.

(I thought Windoof is only used in Germany?)

q.

qwerty

  • EA Guru
  • *****
  • Posts: 13584
  • Karma: +396/-301
  • I'm no guru at all
    • View Profile
Re: Enterprise Architect API DiagramObject Update Fails
« Reply #10 on: July 23, 2018, 01:06:56 am »
I just went through it, and I'm pretty sure this is an EA bug you need to report (use the form below in the Support section and just reference this thread). When doing things in two steps (that is to have a first run creating elements/diagrams) and then a 2nd one to finally add the port it runs with no issue.

q.