Author Topic: Changing an element type and stereotype using JavaScript  (Read 2419 times)

Sunshine

  • EA Practitioner
  • ***
  • Posts: 1296
  • Karma: +119/-10
  • Its the results that count
    • View Profile
Re: Changing an element type and stereotype using JavaScript
« Reply #15 on: July 11, 2024, 04:08:54 pm »
I created a JavaScript Library MDG a while back with a script that does that. You can find it along with the Sparx Model that created it on git hub. https://github.com/EASunshine/Sparx-EA/tree/master
Happy to help
:)

Modesto Vega

  • EA Practitioner
  • ***
  • Posts: 1063
  • Karma: +28/-8
    • View Profile
Re: Changing an element type and stereotype using JavaScript
« Reply #16 on: July 12, 2024, 02:39:12 am »
Well, this is now officially confusing.

Based  on this comment
Why use both "selectedObjects.Count()" and "selectedObjects.Count"?
Count is a property and should not be used as a method?

Further do you get the desired ArchiMate type?
When I use something similar in my scripts, I end up with stereotype "ArchiMate::ArchiMate_Requirement" which is an ArchiMate2 reference instead of ArchiMate3.

Upon changing the script to use selectedObjects.Count on the while loop. The end result is a bit puzzling:

1) The code changing the type of element no longer works - i.e., this code
Code: [Select]
currentElement.Type = "Class"; now does not do anything. But
Code: [Select]
currentElement.Stereotype = "ArchiMate_Requirement changes the stereotype.
2) Even worse using using
Code: [Select]
currentElement.Type = "Class";
currentElement.Stereotype = "";
currentElement.Update();
currentElement.SteretoypEx = "ArchiMate3::ArchiMate_Requirement";
does nothing, it does not change the type or the stereotype
3) and, just to put the cherry on the cake, reverting back to selectedObjects.Count() now results on the error I would expect after reading the post above.

In short, the JavaScript scripting engine appears to be exhibiting inconsistent behaviour without nay Sparx EA upgrade.

DeBAAT

  • EA User
  • **
  • Posts: 59
  • Karma: +2/-0
    • View Profile
Re: Changing an element type and stereotype using JavaScript
« Reply #17 on: July 12, 2024, 05:21:16 pm »
Sorry, but I think you are mixing Stereotype and StereotypeEx (apart from the typo):

Code: [Select]
currentElement.Type = "Class";
currentElement.Stereotype = "";
currentElement.Update();
currentElement.SteretoypEx = "ArchiMate3::ArchiMate_Requirement";

I think it should be:

Code: [Select]
currentElement.Type = "Class";
currentElement.Stereotype = "";
currentElement.Update();
currentElement.Stereotype = "ArchiMate3::ArchiMate_Requirement";
currentElement.Update();

According to the documentation StereotypeEx is a list of Stereotypes (see https://www.sparxsystems.com/enterprise_architect_user_guide/16.1/add-ins___scripting/element2.html).

Modesto Vega

  • EA Practitioner
  • ***
  • Posts: 1063
  • Karma: +28/-8
    • View Profile
Re: Changing an element type and stereotype using JavaScript
« Reply #18 on: July 12, 2024, 07:59:56 pm »
Thank you DeBAAT, but I am still officially confused, perhaps because it has been a long week and I am no longer used to writing code.

This script is doing some seriously strange things.
Code: [Select]
!INC Local Scripts.EAConstants-JavaScript

/*
 * This code has been included from the default Diagram Script template.
 * If you wish to modify this template, it is located in the Config\Script Templates
 * directory of your EA install path.
 *
 * Script Name:
 * Author:
 * Purpose:
 * Date:
 */

/*
 * Diagram Script main function
 */
function OnDiagramScript()
{
// Get a reference to the current diagram
var currentDiagram as EA.Diagram;
currentDiagram = Repository.GetCurrentDiagram();

if ( currentDiagram != null )
{
// Get a reference to any selected connector/objects
var selectedConnector as EA.Connector;
var selectedObjects as EA.Collection;
selectedConnector = currentDiagram.SelectedConnector;
selectedObjects = currentDiagram.SelectedObjects;

if ( selectedConnector != null )
{
// A connector is selected
}
else if ( selectedObjects.Count > 0 )
{
// One or more diagram objects are selected
var objectCount = 0;

while (objectCount < selectedObjects.Count)
//while (objectCount < selectedObjects.Count())
{
Session.Output("Enumerating");
var currentDiagElement as EA.DiagramObject;
currentDiagElement = selectedObjects.GetAt(objectCount);
var currentElement = Repository.GetElementByID(currentDiagElement.ElementID);
Session.Prompt(currentElement.Type, promptOK); //[1]
Session.Prompt(currentElement.Name, promptOK); //[2]
//Session.Prompt(currentElement.Steretoype, promptOK); //[3]
currentElement.Type = "Class";
currentElement.Stereotype = "";
currentElement.Update();
//currentElement.Steretoype = "ArchiMate_Requirement"; //[5]
currentElement.Steretoype = "ArchiMate3::ArchiMate_Requirement"; //[6]
currentElement.Update();
Session.Prompt(currentElement.Type, promptOK); //[7]
Session.Prompt(currentElement.Name, promptOK); //[8]
Session.Prompt(currentElement.Steretoype, promptOK); //[9]
objectCount = objectCount + 1;
}
}
else
{
// Nothing is selected
}
}
else
{
Session.Prompt( "This script requires a diagram to be visible.", promptOK)
}

Repository.ReloadDiagram(currentDiagram.DiagramID);
}

OnDiagramScript();
1) Lines 47 & 48, marked [1] & [2], return the correct values.
2) Line 49, marked [3], always errors, if not commented out, but it is an exact copy of line 58. The error is "Parameter 1 type mismatch". I am attributing this to the stereotype being blank, but if that is the case, it must be a bug, see below.
3) Lines 53 and 54, marked [7] & [8], both work. We are settling with line 54.
4) Line 56, marked [7], returns the correct type, as per the change from line 50.
5) Line 58, marked [9], returns the stereotype as per the change from line 54.
6) Nothing else visibly errors.
7) Line 72 reloads a diagram with all elements changed as per line 50 - i.e., to a class, but a blank/empty  stereotype - i.e., the change applied by lines 54, mark as [7] and 55, and correctly displayed by line 58, marked as [9], disappear.
8) Just to help matters, sarcasm intended, line 58, marked [9], does not error, despite now having a blank/empty stereotype, but line 49, mark as [3], always errors when not commented out.

Geert Bellekens

  • EA Guru
  • *****
  • Posts: 13071
  • Karma: +544/-33
  • Make EA work for YOU!
    • View Profile
    • Enterprise Architect Consultant and Value Added Reseller
Re: Changing an element type and stereotype using JavaScript
« Reply #19 on: July 13, 2024, 08:16:08 am »
Code: [Select]
//Session.Prompt(currentElement.Steretoype, promptOK); //[3]
   
2) Line 49, marked [3], always errors, if not commented out, but it is an exact copy of line 58. The error is "Parameter 1 type mismatch". I am attributing this to the stereotype being blank, but if that is the case, it must be a bug, see below.

Please look carefully how you have spelled Stereotype in your code above, as in line [9] and [6]

Geert

DeBAAT

  • EA User
  • **
  • Posts: 59
  • Karma: +2/-0
    • View Profile
Re: Changing an element type and stereotype using JavaScript
« Reply #20 on: July 13, 2024, 07:28:05 pm »
As Geert said, check your spelling.

In line [3], you are using a non-defined property "Steretoype".
In line [6], you are assigning this non-defined property a value, thus making it defined.
In line [9], this does not generate an error because you defined the property in line [6].

Sometimes it is nice to have weak type-checking, sometimes it is not...

Geert Bellekens

  • EA Guru
  • *****
  • Posts: 13071
  • Karma: +544/-33
  • Make EA work for YOU!
    • View Profile
    • Enterprise Architect Consultant and Value Added Reseller
Re: Changing an element type and stereotype using JavaScript
« Reply #21 on: July 14, 2024, 02:14:31 am »
If you are seeing weird results when testing scripts, it might be due to caching.

In some circumstances (I don't know exactly when) EA caches scripts when executing.
So you think you are executing version B, but in fact you are still executing a cached version A.

If you suspect that is happening you might want to exit and restart EA.

Geert

Modesto Vega

  • EA Practitioner
  • ***
  • Posts: 1063
  • Karma: +28/-8
    • View Profile
Re: Changing an element type and stereotype using JavaScript
« Reply #22 on: July 16, 2024, 07:51:31 pm »

As Geert said, check your spelling.

In line [3], you are using a non-defined property "Steretoype".
In line [6], you are assigning this non-defined property a value, thus making it defined.
In line [9], this does not generate an error because you defined the property in line [6].

Sometimes it is nice to have weak type-checking, sometimes it is not...
Sorry but IMHO this is a bug. Stereotype is a property of the Element object, if it is mistyped - e.g., Steretoype - I am expecting Sparx EA to throw and error instead of going through it as if it were a supported property. I find very odd that methods are strongly typed but properties are not, essentially this means that I can try to fabricate any for any object which is very questionable.

If you are seeing weird results when testing scripts, it might be due to caching.

In some circumstances (I don't know exactly when) EA caches scripts when executing.
So you think you are executing version B, but in fact you are still executing a cached version A.

If you suspect that is happening you might want to exit and restart EA.

Geert
Since the prompts always appear in the right sequence, this may not be due to caching.

Anyway, a working version of the script is below, a key change (other than the spelling corrections) was the addition of the following line "var currentElement as EA.Element;"

Code: [Select]
!INC Local Scripts.EAConstants-JavaScript

/*
 * This code has been included from the default Diagram Script template.
 * If you wish to modify this template, it is located in the Config\Script Templates
 * directory of your EA install path.
 *
 * Script Name:
 * Author:
 * Purpose:
 * Date:
 */

/*
 * Diagram Script main function
 */
function OnDiagramScript()
{
// Get a reference to the current diagram
var currentDiagram as EA.Diagram;
currentDiagram = Repository.GetCurrentDiagram();

if ( currentDiagram != null )
{
// Get a reference to any selected connector/objects
var selectedConnector as EA.Connector;
var selectedObjects as EA.Collection;
selectedConnector = currentDiagram.SelectedConnector;
selectedObjects = currentDiagram.SelectedObjects;

if ( selectedConnector != null )
{
// A connector is selected
}
else if ( selectedObjects.Count > 0 )
{
// One or more diagram objects are selected
var objectCount = 0;

while (objectCount < selectedObjects.Count)
//while (objectCount < selectedObjects.Count())
{
Session.Output("Enumerating");
var currentDiagElement as EA.DiagramObject;
var currentElement as EA.Element;
currentDiagElement = selectedObjects.GetAt(objectCount);
currentElement = Repository.GetElementByID(currentDiagElement.ElementID);
//Session.Prompt(currentElement.Type, promptOK); //[1]
//Session.Prompt(currentElement.Name, promptOK); //[2]
//Session.Prompt(currentElement.Stereotype, promptOK); //[3]
currentElement.Type = "Class";
currentElement.Stereotype = "";
currentElement.Update();
//currentElement.Stereotype = "ArchiMate_Requirement"; //[5]
currentElement.Stereotype = "ArchiMate3::ArchiMate_Requirement"; //[6]
currentElement.Update();
//Session.Prompt(currentElement.Type, promptOK); //[7]
//Session.Prompt(currentElement.Name, promptOK); //[8]
//Session.Prompt(currentElement.Stereotype, promptOK); //[9]
objectCount = objectCount + 1;
}
}
else
{
// Nothing is selected
}
}
else
{
Session.Prompt( "This script requires a diagram to be visible.", promptOK)
}
Repository.ReloadDiagram(currentDiagram.DiagramID);
}

OnDiagramScript();

My conclusion is that writing JavaScripts is a very cumbersome time consuming process which is better to avoid unless there is an abundance of spare time.

Geert Bellekens

  • EA Guru
  • *****
  • Posts: 13071
  • Karma: +544/-33
  • Make EA work for YOU!
    • View Profile
    • Enterprise Architect Consultant and Value Added Reseller
Re: Changing an element type and stereotype using JavaScript
« Reply #23 on: July 16, 2024, 08:18:30 pm »
My conclusion is that writing JavaScripts is a very cumbersome time consuming process which is better to avoid unless there is an abundance of spare time.

I agree that there is a steep learning curve, but once you have mastered the skill, it is pretty fast and very powerful.

Geert

Modesto Vega

  • EA Practitioner
  • ***
  • Posts: 1063
  • Karma: +28/-8
    • View Profile
Re: Changing an element type and stereotype using JavaScript
« Reply #24 on: July 16, 2024, 10:16:12 pm »
I am not worried about the learning curve. I am more worried about having weakly typed properties and strongly typed methods; presumably the former is the reason why 1) the script editor does not show the properties in a different font colour, and 2) Sparx EA does not throw any errors.

Agreed scripts are very powerful but life will be easier if they were not required certain operations.

Geert Bellekens

  • EA Guru
  • *****
  • Posts: 13071
  • Karma: +544/-33
  • Make EA work for YOU!
    • View Profile
    • Enterprise Architect Consultant and Value Added Reseller
Re: Changing an element type and stereotype using JavaScript
« Reply #25 on: July 16, 2024, 11:35:57 pm »
I am not worried about the learning curve. I am more worried about having weakly typed properties and strongly typed methods; presumably the former is the reason why 1) the script editor does not show the properties in a different font colour, and 2) Sparx EA does not throw any errors.

Agreed scripts are very powerful but life will be easier if they were not required certain operations.

I have been using VBScript in EA for ages, now, so I was a bit surprised that indeed Javascript doesn't automatically raises an exception if you try to access a property that doesn't exist.
According to this post on stackoverflow https://stackoverflow.com/a/32214394/2018133 that is a feature that might be turned on, but I wouldn't know if or how that could work in EA.
Maybe there are some more experienced Javascript coders here that know how to avoid typo's like that?

Geert

DeBAAT

  • EA User
  • **
  • Posts: 59
  • Karma: +2/-0
    • View Profile
Re: Changing an element type and stereotype using JavaScript
« Reply #26 on: July 17, 2024, 02:20:41 am »
I do not know how to turn that feature on.
I do know that the internal JavaScript editor within EA is capable of autocompleting both methods and properties.
So I usually try to either copy/paste code or add the property by the autofill of the editor.

Modesto Vega

  • EA Practitioner
  • ***
  • Posts: 1063
  • Karma: +28/-8
    • View Profile
Re: Changing an element type and stereotype using JavaScript
« Reply #27 on: July 17, 2024, 02:36:10 am »
It does auto-complete methods but, in our installation base, it does not auto-complete properties, and we don't know how to turn that on.

Getting to auto-complete properties will definitely make a big difference.

DeBAAT

  • EA User
  • **
  • Posts: 59
  • Karma: +2/-0
    • View Profile
Re: Changing an element type and stereotype using JavaScript
« Reply #28 on: July 17, 2024, 03:18:54 am »
Strange, can't recall changing any settings regarding JavaScripting.
In my configuration, after setting the '.' (dot), the editor shows a pop-up with both methods and properties.
All in one single list, sorted alphabetically.
There is a difference in the color though.

Modesto Vega

  • EA Practitioner
  • ***
  • Posts: 1063
  • Karma: +28/-8
    • View Profile
Re: Changing an element type and stereotype using JavaScript
« Reply #29 on: July 17, 2024, 06:18:31 pm »
Strange, can't recall changing any settings regarding JavaScripting.
In my configuration, after setting the '.' (dot), the editor shows a pop-up with both methods and properties.
All in one single list, sorted alphabetically.
There is a difference in the color though.
After a full system reboot I get both methods and properties on a list after entering the '.' (dot) for everything in the script.

Somehow I got in my head that a) I have seem a similar behaviour with VBScript, and b) it has something to do with how the scripts are written, specially if they are weakly typed by accident or design.

Regarding the later point, I have not tried this yet but I am wondering if the following explains the issue with the script editor listing the methods and properties of an object; an earlier version of the script
1) was missing the following line
Code: [Select]
var currentElement as EA.Element;2) only had the following line - i.e., currentElement was, as you pointed out, weakly typed
Code: [Select]
currentElement = Repository.GetElementByID(currentDiagElement.ElementID);3) as a result, typing currentElement followed by '.' (dot) did not result on a list of methods and methods for this particular object because it was weakly typed;
4) when we introduced the line of code on point 1, it continued not listing methods and properties for that object because of caching;
5) a full system reboot cleared the caches and everything started working as expected.