Book a Demo

Author Topic: Script to convert elements from UML to ArchiMate  (Read 87560 times)

Modesto Vega

  • EA Practitioner
  • ***
  • Posts: 1183
  • Karma: +30/-8
    • View Profile
Script to convert elements from UML to ArchiMate
« on: September 17, 2025, 02:15:47 am »
Trying to get some scripts written to converts element from a UML based MDG to an ArchiMate based MDG.

Let's take What I thought will be a simple example, converting a UML Component with a stereotype of "System" to an ArchiMate "Application Component" - i.e., an element with a stereotype of "ArchiMate_ApplicationComponent".

At first the scripts worked fine but then things got unexpectedly weird.

There are 2 scripts in play:
Code: [Select]
!INC Local Scripts.EAConstants-JScript
!INC DAF2.daf2_Element_Utilities

/*
 * 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)
{
Session.Output("Please open a diagram and select an element.");
return;
}
else if ( currentDiagram != null )
{
// Get a reference to any selected connector/objects
var selectedObjects as EA.Collection;
selectedObjects = currentDiagram.SelectedObjects;

if (selectedObjects.Count == 0)
{
Session.Output("❌ No elements selected in the diagram.");
return;
}

Session.Output("🔁 Processing selected elements in diagram...");

for (var i = 0; i < selectedObjects.Count; i++)
{
var diagramObject = selectedObjects.GetAt(i);
var element = Repository.GetElementByID(diagramObject.ElementID);

if (element == null)
{
Session.Output("⚠️ Skipping: could not retrieve element at index " + i);
continue;
}

Session.Output("✅ Converting '" + element.Name + "' (Component) → ArchiMate_ApplicationComponent...");

// Use utility function
convertElementType(element, "ArchiMate_ApplicationComponent", "Component");
}
}

currentDiagram.Update();

Session.Output("✅ Conversion complete.");
}

OnDiagramScript();
And
Code: [Select]
function convertElementType(element, newStereotype, newType)
{
element.Stereotype = newStereotype;
element.Type = newType;

    // Clear custom style overrides (optional)
    element.StyleEx = "";

    element.Update();
}

I thought the original test was successful but I am having my doubts now because the scripts does not change the type or stereotype and must be missing something obvious I cannot see.




Geert Bellekens

  • EA Guru
  • *****
  • Posts: 13495
  • Karma: +572/-33
  • Make EA work for YOU!
    • View Profile
    • Enterprise Architect Consultant and Value Added Reseller
Re: Script to convert elements from UML to ArchiMate
« Reply #1 on: September 17, 2025, 07:29:47 am »
Don't use .Stereotype. Instead use .StereotypeEx, and pass the fully qualified stereotype.

Geert

Sunshine

  • EA Practitioner
  • ***
  • Posts: 1349
  • Karma: +121/-10
  • Its the results that count
    • View Profile
Re: Script to convert elements from UML to ArchiMate
« Reply #2 on: September 17, 2025, 10:23:39 am »
Here is some code that I used to do something similar but selecting a package in project browser.
https://sparxsystems.com/forums/smf/index.php/topic,45674.msg267977.html#msg267977
If you replace the following line
Code: [Select]
//Convert standards to MDG standard
Conversions[0] = new TypeConversion("Class", "Standard", "Class", "Motivation::Standard");
With this line it should convert a UML Component to ArchiMate3::ApplicationComponent
Code: [Select]
//Convert Component
elementConversions[0] = new TypeConversion( "Component", "","Component", "ArchiMate3::ArchiMate_ApplicationComponent");
It should work.
Note that I developed this script further to convert connectors and diagram types however, when I tried to post it I got blocked as I had to use SQL to convert the diagram.
Happy to help
:)

Geert Bellekens

  • EA Guru
  • *****
  • Posts: 13495
  • Karma: +572/-33
  • Make EA work for YOU!
    • View Profile
    • Enterprise Architect Consultant and Value Added Reseller
Re: Script to convert elements from UML to ArchiMate
« Reply #3 on: September 17, 2025, 05:10:15 pm »
Here's my full conversion script:

Code: [Select]
'[path=\Projects\Project EL\Conversion]
'[group=Conversion]
option explicit

!INC Local Scripts.EAConstants-VBScript
!INC Wrappers.Include
'
' Script Name: Convert Archimate Stereotypes
' Author: Geert Bellekens
' Purpose: Convert ArchiMate Capabilities from standard to GB MDG
' Date: 2023-01-20
'
const outPutName = "Convert Model"


dim stereotypeMapping
set stereotypeMapping = CreateObject("Scripting.Dictionary")

dim taggedValuesMapping
set taggedValuesMapping = CreateObject("Scripting.Dictionary")
dim taggedValuesCopy
set taggedValuesCopy = CreateObject("Scripting.Dictionary")
'----------------CONFIGURATION---------------------------------------
'Stereotypes
'stereotypeMapping.Add "GB Modelling::ArchiMate_BusinessFunction", "GB Modelling::ArchiMate_Capability"
'stereotypeMapping.Add "ArchiMate3::ArchiMate_Capability", "GB Modelling::ArchiMate_Capability"
'stereotypeMapping.Add "ArchiMate3::ArchiMate_BusinessFunction", "GB Modelling::ArchiMate_Capability"
'stereotypeMapping.Add "ArchiMate3::ArchiMate_BusinessObject", "GB Modelling::GB_BIM_Class"
'stereotypeMapping.Add "Class;<null>", "GB Modelling::GB_BIM_Class"
'stereotypeMapping.Add "Attribute;<null>", "GB Modelling::GB_BIM_Attribute"
'stereotypeMapping.Add "Association;<null>", "GB Modelling::GB_BIM_Association"
'stereotypeMapping.Add "Aggregation;<null>", "Association;GB Modelling::GB_BIM_Association"
'stereotypeMapping.Add "GB Modelling::GB_BIM_Association", "Association;GB Modelling::GB_BIM_Association" 'temporary
'stereotypeMapping.Add "Logical;<null>", "GB Modelling::BIM View"
'stereotypeMapping.Add "GB Modelling::BIM View", "GB Modelling::CBIM View" 'temporary
stereotypeMapping.Add "GB Modelling::GB_BIM_Class", "GB Modelling::GB_CBIM_Class"
stereotypeMapping.Add "GB Modelling::GB_BIM_Association", "GB Modelling::GB_CBIM_Association"
'TaggedValues (replace by)
'taggedValuesMapping.Add "Capa Maturity", "Maturity"
'taggedValuesMapping.Add "Capa Level", "Level"

'TaggedValues (copy value to)
'taggedValuesCopy.Add "Maturity", "Maturity 50Hz"
'----------------CONFIGURATION---------------------------------------

sub main
'reset output tab
Repository.CreateOutputTab outPutName
Repository.ClearOutput outPutName
Repository.EnsureOutputVisible outPutName
'report progress
Repository.WriteOutput outPutName, now() & " Starting " & outPutName, 0
'do the actual work
convertCapabilities()
'report progress
Repository.WriteOutput outPutName, now() & " Finished " & outPutName, 0
end sub

function convertCapabilities()
dim package as EA.Package
set package = Repository.GetTreeSelectedPackage
convertPackage package

end function

function convertPackage(package)
'report progress
Repository.WriteOutput outPutName, now() & " Processing '" & package.Name & "'", 0
'convert elements
dim element as EA.Element
for each element in package.Elements
convertElement element, -1
next
'process diagrams
convertDiagrams(package)
'process subPackages
dim subPackage as EA.Package
for each subPackage in package.Packages
convertPackage subPackage
next
end function

function convertElement(element, level)
dim mappingKey
if len(element.FQStereotype) > 0 then
mappingKey = element.FQStereotype
else
mappingKey = element.Type & ";<null>"
end if
dim userMessage
userMessage = " Converting element '" & element.Name & "'"
'Repository.WriteOutput outPutName, now() & " debug before convertItem: " & element.Name, 0
'convert the element
convertItem element, userMessage, mappingKey, level
'Repository.WriteOutput outPutName, now() & " debug after convertItem: " & element.Name, 0
'process attributes
dim attribute as EA.Attribute
for each attribute in element.Attributes
convertAttribute element, attribute
next
'process (outgoing) relations
dim connector as EA.Connector
for each connector in element.Connectors
if connector.ClientID = element.ElementID then
convertConnector element, connector
end if
next
'process diagrams
convertDiagrams(element)
'process subElements
dim subElement as EA.Element
for each subElement in element.Elements
convertElement subElement, level + 1
next
end function

function convertConnector(element, connector)
dim mappingKey
if len(connector.FQStereotype) > 0 then
mappingKey = connector.FQStereotype
else
mappingKey = connector.Type & ";<null>"
end if
dim userMessage
userMessage = " Converting connector '" & element.Name & "." & connector.Name & "'"
'convert the connector
convertItem connector, userMessage, mappingKey, ""
end function



function convertAttribute(element, attribute)
dim mappingKey
if len(attribute.FQStereotype) > 0 then
mappingKey = attribute.FQStereotype
else
mappingKey = "Attribute;<null>"
end if
dim userMessage
userMessage = " Converting attribute '" & element.Name & "." & attribute.Name & "'"
'convert the attribute
convertItem attribute, userMessage, mappingKey, ""
end function

function convertDiagrams(diagramOwner)
dim diagram as EA.Diagram
for each diagram in diagramOwner.Diagrams
'get mapping key
dim mappingKey
if len(diagram.MetaType) > 0 then
mappingKey = diagram.MetaType
else
mappingKey = diagram.Type & ";<null>"
end if
'convert
if stereotypeMapping.Exists(mappingKey) then
'if true then 'temporary for CBIM conversion
Repository.WriteOutput outPutName, now() & " Converting diagram '" & diagram.Name & "'", 0
dim styleEx
'hide connector stereotypes
styleEx = setValueForKey(diagram.StyleEx, "HideConnStereotype", "1")
'set view to empty
styleEx = setValueForKey(styleEx, "MDGView", "")
'disable fully scoped object names
styleEx = setValueForKey(styleEx, "NoFullScope", "1")

dim extendedStyle
'hide attribute stereotypes
extendedStyle = setValueForKey(diagram.ExtendedStyle, "HideStereo", "1")
'hide element stereotypes
extendedStyle = setValueForKey(extendedStyle, "HideEStereo", "1")

diagram.StyleEx = styleEx
diagram.ExtendedStyle = extendedStyle
diagram.MetaType = stereotypeMapping(mappingKey)
'diagram.MetaType = "GB Modelling::CBIM View" 'temporary for CBIM conversion
diagram.Update
end if
next
end function

function convertItem(item,  userMessage, mappingKey, level)
if stereotypeMapping.Exists(mappingKey) then
dim tagsDictionary
set tagsDictionary = getTagsDictionary(item)
dim setLevel3
setLevel3 = false
if instr(mappingKey, "ArchiMate_BusinessFunction") > 0 then
setLevel3 = true
end if
'report progress
Repository.WriteOutput outPutName, now() & userMessage, 0
dim dirty
dirty = false
'check if we have a type to convert to
dim mappingTarget
dim targetSteretoype
mappingTarget = stereotypeMapping(mappingKey)
if instr(mappingTarget, ";") > 0 then
'fix the aggregation direction if needed
'aggregation with Direction "Source -> Destination" don't have arrows.
'If we change the type to Association, they do, so we change Direction to Unspecified in order to remove the arrow
if item.ObjectType = otConnector then
if item.Type = "Aggregation" _
  and item.Direction = "Source -> Destination" then
item.Direction = "Unspecified"
dirty = true
end if
end if
'get type and stereotype
dim mappingTargetParts
mappingTargetParts = split(mappingTarget, ";")
if item.Type <> mappingTargetParts(0) then
item.Type = mappingTargetParts(0) 'type
dirty = true
end if
targetSteretoype= mappingTargetParts(1)
else
targetSteretoype = mappingTarget
end if
if item.FQStereotype <> targetSteretoype then
item.StereotypeEx = targetSteretoype 'stereotype
dirty = true
end if
if dirty then
item.Update
end if
'Repository.WriteOutput outPutName, now() & " debug after item update: " & item.Name, 0
if setLevel3 then
'convert tagged values
convertTaggedValues item, "3", tagsDictionary
else
'convert tagged values
convertTaggedValues item, level, tagsDictionary
end if
end if
end function

function getTagsDictionary(item)
dim tagsDictionary
set tagsDictionary = createObject("Scripting.Dictionary")
dim tag as EA.TaggedValue
for each tag in item.TaggedValues
if not tagsDictionary.Exists(tag.Name) then
tagsDictionary.Add tag.Name, tag.Value
'Repository.WriteOutput outPutName, now() & " adding tag to dictionary " & tag.Name & " value: " & tag.Value , 0
end if
next
'return
set getTagsDictionary = tagsDictionary
end function

function convertTaggedValues(element, level, tagsDictionary)
'Repository.WriteOutput outPutName, now() & " debug before update existing tags: " & element.Name, 0
dim tag as EA.TaggedValue
element.TaggedValues.Refresh
'Repository.WriteOutput outPutName, now() & " debug after taggedvalues refresh: " & element.Name, 0
'first loop tagged values to copy the pre-existing tag values
for each tag in element.TaggedValues
'Repository.WriteOutput outPutName, now() & " debug processing tag: " & tag.Name & " tagsDictionary.Count: " & tagsDictionary.Count , 0
'check the pre-existing tags and copy their value
if tagsDictionary.Exists(tag.Name) then
'Repository.WriteOutput outPutName, now() & " debug updating tag: " & tag.Name, 0
tag.Value = tagsDictionary(tag.Name)
tag.Update
end if
next
'refresh to make sure we have the correct tags and values
element.TaggedValues.Refresh
'Repository.WriteOutput outPutName, now() & " debug after update existing tags: " & element.Name, 0
'then convert if needed
for each tag in element.TaggedValues
dim convertedTag
'convert tags
if taggedValuesMapping.Exists(tag.Name) then
set convertedTag = getExistingOrNewTaggedValue(element, taggedValuesMapping(tag.Name))
convertedTag.Value = tag.Value
convertedTag.Update
deleteTag element, tag.Name
end if
'copy tag values
if taggedValuesCopy.Exists(tag.Name) then
'Repository.WriteOutput outPutName, now() & " debug tag to copy: " & tag.Name, 0
set convertedTag = getExistingOrNewTaggedValue(element, taggedValuesCopy(tag.Name))
convertedTag.Value = tag.Value
convertedTag.Update
end if

'check level tag
if lcase(tag.Name) = "level" then
dim correctLevel
correctLevel = "L" & level
if not lcase(tag.Value) = lcase(correctLevel) then
if lcase(tag.Value) = "tbd" or len(tag.Value) = 0 then
tag.Value = correctLevel
tag.Update
else
'report issue
Repository.WriteOutput outPutName, now() & " ERROR: Level tag on '" & element.Name & "' with GUID '" & element.ElementGUID & "' is '" & tag.Value & "' and should be '" & correctLevel  & "'", 0
end if
end if
end if
next

end function

main

Geert

Modesto Vega

  • EA Practitioner
  • ***
  • Posts: 1183
  • Karma: +30/-8
    • View Profile
Re: Script to convert elements from UML to ArchiMate
« Reply #4 on: September 17, 2025, 10:32:10 pm »
Thank you for both of your contributions. After making changes to the scripts based on a variation of both your contributions, it appears that the new target stereotype gets added to any existing element stereotype and as a result the type gets changed to a "Class".

In other words, using this adds an additional stereotype to the element being converted.
Instead use .StereotypeEx, and pass the fully qualified stereotype.

Somehow, I was expecting this code to do the trick but it does not.

VBScript
Code: [Select]
if item.FQStereotype <> targetSteretoype then
item.StereotypeEx = targetSteretoype 'stereotype
dirty = true
end if

JScript
Code: [Select]
var dirty = 0

if (element.FQStereotype  != newStereotype)
{
element.StereotypeEx = newStereotype;
dirty = 1
}

It is looking like somehow the existing StereotypeEx  needs to be cleared.

Do I need to set element.StereotypeEx to "", update the element, and set the new stereotype?

Please keep in mind that we have not developed the new MDG out, at the moment we are testing how to translate existing content to ArchiMate.

Sunshine

  • EA Practitioner
  • ***
  • Posts: 1349
  • Karma: +121/-10
  • Its the results that count
    • View Profile
Re: Script to convert elements from UML to ArchiMate
« Reply #5 on: September 18, 2025, 04:22:37 pm »
Setting stereotypeEx clears all stereotypes and sets it to just one.
If you are thinking of creating an MDG extension to archimate let me know. I have one.
Happy to help
:)

Modesto Vega

  • EA Practitioner
  • ***
  • Posts: 1183
  • Karma: +30/-8
    • View Profile
Re: Script to convert elements from UML to ArchiMate
« Reply #6 on: September 18, 2025, 04:50:04 pm »
Setting stereotypeEx clears all stereotypes and sets it to just one.
I was expecting this but stereotypeEx doesn’t clear the stereotypes.

Quote
If you are thinking of creating an MDG extension to archimate let me know. I have one.
We are thinking about creating an MDG extension of ArchiMate. Please feel free to DM me.


Geert Bellekens

  • EA Guru
  • *****
  • Posts: 13495
  • Karma: +572/-33
  • Make EA work for YOU!
    • View Profile
    • Enterprise Architect Consultant and Value Added Reseller
Re: Script to convert elements from UML to ArchiMate
« Reply #7 on: September 18, 2025, 07:54:19 pm »
I've had that problem too in the past, but I don't remember exactly how I solved it.

Might have been something like reloading (using Repository.GetElementByID) the element after setting the stereotype or something.

Geert

Modesto Vega

  • EA Practitioner
  • ***
  • Posts: 1183
  • Karma: +30/-8
    • View Profile
Re: Script to convert elements from UML to ArchiMate
« Reply #8 on: September 18, 2025, 11:04:35 pm »
This gets better by the minute, the script now works fine with or without using using Repository.GetElementByID. The scripts have not changed, only the day has changed, including disconnecting and reconnecting the laptop from the network and logging in without restarting the computer, it even applies the right colour fill.

I am officially happily confused. Only explanation I can think of is that Sparx EA was somehow caching the script.

Geert Bellekens

  • EA Guru
  • *****
  • Posts: 13495
  • Karma: +572/-33
  • Make EA work for YOU!
    • View Profile
    • Enterprise Architect Consultant and Value Added Reseller
Re: Script to convert elements from UML to ArchiMate
« Reply #9 on: September 18, 2025, 11:33:09 pm »
This gets better by the minute, the script now works fine with or without using using Repository.GetElementByID. The scripts have not changed, only the day has changed, including disconnecting and reconnecting the laptop from the network and logging in without restarting the computer, it even applies the right colour fill.

I am officially happily confused. Only explanation I can think of is that Sparx EA was somehow caching the script.
That is indeed a possibility. In some weird conditions I've seen that happen as well.

Geert

Sunshine

  • EA Practitioner
  • ***
  • Posts: 1349
  • Karma: +121/-10
  • Its the results that count
    • View Profile
Re: Script to convert elements from UML to ArchiMate
« Reply #10 on: September 19, 2025, 06:19:56 am »
You can find the model I originally used to create Archimate Extension on GitHub.
https://github.com/EASunshine/Sparx-EA/
Download the file EAMDGProfile.zip - Has Full EA Model and files, icons etc to create a ArchiMate MDG Extension.
Instructions on how to build the MDG can be found in model.
If I get time over the weekend I'll update it. Found I needed to restructure it so it worked with Prolaborate. For now that should give you a good start at creating your own.
Used this at several organisations successfully to manage large transformations.
« Last Edit: September 19, 2025, 08:07:26 am by Sunshine »
Happy to help
:)