Book a Demo

Author Topic: Convert To Instance via code  (Read 5224 times)

Gary Cleal

  • EA Novice
  • *
  • Posts: 9
  • Karma: +1/-0
    • View Profile
Convert To Instance via code
« on: September 02, 2015, 04:43:40 pm »
Does anyone know how to convert a class element to an Instance via code.. I am looking for a method equivalent to (diagram element right-click) "Advanced\Convert To Instance".
If there is no method(), are there a set of properties that could be set on an element to achieve the same result?

Geert Bellekens

  • EA Guru
  • *****
  • Posts: 13523
  • Karma: +574/-33
  • Make EA work for YOU!
    • View Profile
    • Enterprise Architect Consultant and Value Added Reseller
Re: Convert To Instance via code
« Reply #1 on: September 02, 2015, 04:53:33 pm »
No there isn't.
I wrote something a bit similar as part of a script a while ago.
This operation is used to convert BPMN activities used a "link" on a diagram to local BPMN activities that call this activity using the calledActivityRef tagged value.
Converting to instances is a bit the same thing. You just need to create a new object, set the classifierID to the classifier you are trying to replace, and replace the ElementID on the DiagramObject to the elementID of the new object.

Code: [Select]
Sets the object name to that of the classifier, and set the composite diagram for objects
function synchronizeObjectNames(diagramObject, diagram)
      dim element as EA.Element
      set element = Repository.GetElementByID(diagramObject.ElementID)
      synchronizeElement element
      'set default size for message objects
      if element.Type = "Object" AND element.Stereotype = "Message" then
            diagramObject.bottom = diagramObject.top - 25
            diagramObject.right = diagramObject.left + 40
            setFont diagramObject
            diagramObject.Update
      end if
      'check if it is local activity
      if element.Type = "Activity" and element.Stereotype = "Activity" and (element.PackageID <> diagram.packageID ) then
            'Make a new Activity for this activity
            dim callingActivity as EA.Element
            dim ownerElement as EA.Element
            dim ownerPackage as EA.Package
            if diagram.ParentID > 0 then
                  set ownerElement = Repository.GetElementByID(diagram.ParentID)
                  set callingActivity = ownerElement.Elements.AddNew("","BPMN2.0::Activity")
            else
                  set ownerPackage = Repository.GetPackageByID(diagram.PackageID)
                  set callingActivity = ownerPackage.Elements.AddNew("","BPMN2.0::Activity")
            end if
            'check if callingActivity was created
            if not callingActivity is Nothing then
                  makeCallingActivity callingActivity, element
                  dim updateDiagramObjectSQL
                  'set the element of the diagramObject to the new action
                  updateDiagramObjectSQL = "update t_diagramobjects set object_id = "& callingActivity.ElementID &" where Diagram_ID = " & diagramObject.DiagramID & " and Object_ID = " & element.ElementID
                  Repository.Execute updateDiagramObjectSQL
                  'synchronize                                    
                  synchronizeElement callingActivity
                  Repository.AdviseElementChange(callingActivity.ElementID)
                  'copy embedded elements
                  dim embeddedElement as EA.Element
                  for each embeddedElement in element.EmbeddedElements
                        'check if the embedded element is shown on this diagram
                        
                        ' get the diagramObject for the embedded element
                        dim embeddedDiagramObject
                        set embeddedDiagramObject = getDiagramObjectFromArray(embeddedElement.elementID, diagramObjects, count)
                        if not embeddedDiagramObject is nothing then
                              'if yes then make a new embedded elementin the callingActivity
                              dim newEmbeddedElement as EA.Element
                              set newEmbeddedElement = callingActivity.EmbeddedElements.AddNew("","ObjectNode")
                              newEmbeddedElement.Name = embeddedElement.Name
                              newEmbeddedElement.Stereotype = "IntermediateEvent"
                              newEmbeddedElement.Update()
                              newEmbeddedElement.SynchTaggedValues "BPMN2.0","IntermediateEvent"
                              newEmbeddedElement.TaggedValues.Refresh
                              'Copy tagged values
                              copyTaggedValuesValues embeddedElement, newEmbeddedElement
                              ' set the element id of the diagramobject to the new embedded element
                              'embeddedDiagramObject.ElementID = newEmbeddedElement.ElementID
                              'embeddedDiagramObject.Update
                              'for some reason the update doesn't want to work. so we do it the hard way
                              dim updateEmbeddedDiagramObjectSQL
                              updateEmbeddedDiagramObjectSQL = "update t_diagramobjects set object_id = "& newEmbeddedElement.ElementID &" where Diagram_ID = " & diagramObject.DiagramID & " and Object_ID = " & embeddedElement.ElementID
                              'Session.Output updateEmbeddedDiagramObjectSQL
                              Repository.Execute updateEmbeddedDiagramObjectSQL
                        end if
                  next
            end if
      end if
end function
Synchronize function in a second post.

Geert Bellekens

  • EA Guru
  • *****
  • Posts: 13523
  • Karma: +574/-33
  • Make EA work for YOU!
    • View Profile
    • Enterprise Architect Consultant and Value Added Reseller
Re: Convert To Instance via code
« Reply #2 on: September 02, 2015, 04:54:11 pm »
And here's the synchronizeElement function:
Code: [Select]
' Synchronises the names of the selected objects or BPMN Activities with their classifier/called activity ref.
' Will also set the composite diagram to that of the classifier/ActivityRef in order to facilitate click-through
function synchronizeElement (element)
      'first check if this is an object or an action
      if not element is Nothing then
            if (element.Type = "Object" OR element.Type = "Action") _
            AND element.ClassifierID > 0 then
                  dim classifier
                  set classifier = Repository.GetElementByID(element.ClassifierID)
                  if not classifier is nothing AND classifier.name <> element.name then
                        element.Name = classifier.Name
                        element.Stereotype = classifier.Stereotype
                        element.Update
                        Repository.AdviseElementChange(element.ElementID)
                  end if
                  'elements of type object should also point to the composite diagram of the classifier
                  if element.Type = "Object" then
                        dim compositeDiagram
                        set compositeDiagram = classifier.CompositeDiagram
                        if not compositeDiagram is nothing then
                              setCompositeDiagram element, compositeDiagram
                        end if
                  end if
            elseif element.Type = "Activity" AND element.Stereotype = "Activity" then
                  'BPMN activities that call another BPMN activity need to get the same name and same composite diagram
                  dim calledActivityTV as EA.TaggedValue
                  set calledActivityTV = element.TaggedValues.GetByName("isACalledActivity")
                  dim referenceActivityTV as EA.TaggedValue
                  set referenceActivityTV = element.TaggedValues.GetByName("calledActivityRef")
                  if not calledActivityTV is nothing and not referenceActivityTV is nothing then
                        'only do something when the Activity is types a CalledActivity
                        'Session.Output "calledActivityTV.Value : " & calledActivityTV.Value
                        'Session.Output "referenceActivityTV.Value :" & referenceActivityTV.Value
                        if calledActivityTV.Value = "true" then
                              dim calledActivity as EA.Element
                              set calledActivity = Repository.GetElementByGuid(referenceActivityTV.Value)
                              if not calledActivity is nothing then
                                    'set name to that of the called activity
                                    element.Name = calledActivity.Name
                                    element.Update
                                    'Set composite diagram to that of the called activity
                                    setCompositeDiagram element, calledActivity.CompositeDiagram
                              end if
                        end if
                  end if
            end if
      end if
end function

qwerty

  • EA Guru
  • *****
  • Posts: 13584
  • Karma: +397/-301
  • I'm no guru at all
    • View Profile
Re: Convert To Instance via code
« Reply #3 on: September 02, 2015, 08:06:58 pm »
To summarize (without having looked into Geerts code):

- create a new element of type Object
- set the classifier to the class you want to instantiate from

q.

KP

  • EA Administrator
  • EA Expert
  • *****
  • Posts: 2919
  • Karma: +55/-3
    • View Profile
Re: Convert To Instance via code
« Reply #4 on: September 03, 2015, 09:11:16 am »
Quote
To summarize (without having looked into Geerts code):

- create a new element of type Object
- set the classifier to the class you want to instantiate from

q.
And don't forget...

Quote
and replace the ElementID on the DiagramObject to the elementID of the new object.
« Last Edit: September 03, 2015, 09:17:55 am by KP »
The Sparx Team
[email protected]