Shapescripts in Enterprise Architect are used to define the presentation of elements on a diagram. They are mostly used when defining a UML profile in Enterprise Architect that extends UML or another modelling language with project specific elements and properties.
When developing UML profiles these shapescripts are stored in the _image attribute on the stereotype element, an they can be easily edited using the profile helper.
After a while however you’ll have a bunch of shapescripts scattered over different profiles, and projects, and it becomes hard to manage, or do any kind of version control. Finding a specific shapescript where you used a particular feature is next to impossible if you don’t remember exactly which stereotype this shapescript belonged to.
With the shapescript editor you can export each shapescript individually, but once you have more then a couple of shapescripts that quickly becomes a drag to save your shapescripts to files.
So I wrote a script called ExportAllShapeScripts that searches a repository for all stereotypes that have a shapescript, and exports all of these shapescripts in one go.
This script is part of the Enterprise-Architect-VBScript-Library. Read the article How to use the Enterprise Architect VBScript Library for instructions on downloading and using the Library in Enterprise Architect.
Running this script will save each shapescript as a textfile with extension .shapeScript, grouped in packages per profile.
The code explained
The export script first uses an SQL query to find all shapescripts. Technically the shapescripts are stored in the default property of the attribute with the name _image. The script is stored as an xml tag Image in a zipped and base64 encoded format. A typical shapescript might look like this in the database:
<Image type="EAShapeScript 1.0" xmlns:dt="urn:schemas-microsoft-com:datatypes" dt:dt="bin.base64"> UEsDBBQAAAAIABpRIkdk2qflMQIAADIHAAAHABEAc3RyLmRhdFVUDQAHncrmVZ3K5lWdyuZV jVXJTsMwFJxrkfiHCC5FqsRSaIsQhx44sohKcC5toUihqUjYxb8z8xw3jksLsmIn9sx43vOS HFMMMccECZ749ogZNrGBL6sbSNn3gQwvKFg+DHmKLfZPcM+eZzIeqFGw76Tk3LPvneNj9JEb Y8TxayoVHMmML+YLRyqWq8emmxP3ybcmuthDC222OyXS4fpEjjGgxh1rH0OTejP2PbF3whly frewTw2puDbUcVp5kIM62437XHiPDeyy3FnkCXEuviG5D5YXjxrwvcAV6xluiR7za0qP7YUH oa6X+E1zWzmOncdObsytcjuiSkpPqa3jZBFBgzFleDU/GcfloW1zhJqeJYxHLM8cK3VY1is5 xLJSGINW+5lo33dGDanMGYMyInYLB+hZLWddtqvUMpv9N8dNHJKnHdVZ4/hoMdtfmNhFPNdv TmMdZSfGhNEUeAsy02eeRnYyuuZR7GPmp1U66lmODlmkKkwca91jj2zh1+XD6cQe6xjnIcbU 45gaI2Gb2c3xaSulvR/uWs9ZdX7210SjDCgPq336MxWjQqe53YXagQnPeWa3WXWWtCMLu+WE GHE8tXiqc1tXXr4hHNKtkR7tgb8YB+U6Ca8V/R+rY7vdsTqm8B/Wsek7VpWvOi9ufXHf39bq qd70KLvujteaPML9EbQnMvYldKF9MLQbODVGeDvXR76sTsr1uCz/RdLVf2Bgd391yyUlem44 7bq0RG7jgqfqnHfONr8qbN25f34AUEsBAhcLFAAAAAgAGlEiR2Tap+UxAgAAMgcAAAcACQAA AAAAAAAAAACAAAAAAHN0ci5kYXRVVAUAB53K5lVQSwUGAAAAAAEAAQA+AAAAZwIAAAAA </Image>
So the SQL selects all attributes owned by a element with stereotype «stereotype» with the name _image that have the tag in their Default field.
'get all attributes with name _image that have shapescript in the default field and a parent with stereotype «stereotype» dim sqlGetShapescriptAttributes sqlGetShapescriptAttributes = "select a.ID from (t_attribute a " & _ " inner join t_object o on (o.Object_ID = a.Object_ID " & _ " and o.Stereotype = 'stereotype')) " & _ " where a.Name = '_image' " & _ " and a.[Default] like '<Image type=""EAShapeScript" & getWC & "'" dim shapeScriptAttributes set shapeScriptAttributes = getAttributesByQuery(sqlGetShapescriptAttributes)
Then we loop the schapescript attributes, decode the shapescript and save it as an individual text file.
'loop the shape script attributes for each shapeScriptAttribute in shapeScriptAttributes 'get the stereotype dim stereotype as EA.Element set stereotype = Repository.GetElementByID(shapeScriptAttribute.ParentID) dim profile as EA.Package set profile = findProfilePackage(stereotype) 'load the resultset in the xml document dim shapeScript shapeScript = decodeBase64zippedXML(shapeScriptAttribute.Default,"Image") if len(shapeScript) > 0 then dim scriptFile set scriptFile = New TextFile scriptfile.Contents = shapeScript 'save the script scriptFile.FullPath = selectedFolder.FullPath & "\" & profile.Name & "\" & stereotype.Name & ".shapeScript" scriptFile.Save 'debug info Session.Output "saving script: " & scriptFile.FullPath end if next
The real difficulty int his script was to decode the shapescript, which is hidden in the method decodeBase64zippedXML defined in the XML utility script. It first base64 decodes the contents of the tag, then saves it as a zip file, unzips the zip file, gets the text file in the zip file, and returns the contents of the text file. Then it deletes the temporary zip file and folder it was extracted to.
If you have shapescripts of your own that you wish to share you can send a github pull request, or an email to email@example.com.
Any bright ideas on how to document each of the shapescripts with an image of shape are welcome too.