Page 1 of 1

Accessing a Part's Type via JS

PostPosted: Tue Mar 30, 2021 8:21 am
Hey all - when I apply a stereotype to a part property, under the "Type" value, it shows both the type and the path. For example, for a Rockwell PLC it will have Type: Rockwell PLC [Components::Controllers]

Now - I am trying to write a Javascript macro that reads that entire line, including the path - but when I get the type, it only returns "Rockwell PLC." Is there a way to get the entire string, including [Components::Controllers] as well?

Re: Accessing a Part's Type via JS

PostPosted: Thu Apr 01, 2021 7:43 am
If you're looking to just get a string that says what the "Type" box in the specification window says, then there is a bit of busy work we'll need to do but it isn't too crazy.

For this, I'll assume you have an instantiated variable in JavaScript for your part property. If you can't get to the part property you're looking for, you can use the following code as a surrogate. It will take an element selected in the containment tree and assign it to the variable named "selectedElement".
Code: Select all

// Get the project currently open //
var project = com.nomagic.magicdraw.core.Application.getInstance().getProject();

// Get the model browser currently on the screen //
var browser = project.getBrowser();

// Get the element selected in the Containment Tree of that browser//
var selectedElement = browser.getContainmentTree().getSelectedNode().getUserObject();

With your particular part property, we'll need to construct the string that you see in the specification window. The command ".getType()" you probably already know gets you the block that a particular part property is characterized by. There are three other commands we'll need. "getQualifiedName()", "lastIndexOf(String str)" and "substring(int beginIndex, int endIndex)". Let's start with the qualified name.

If we were to just use the "getQualifiedName" method, we may get something like this:
Code: Select all
selectedElement.getType().getQualifiedName() // -> Returns: "Components::Controllers::Rockwell PLC"

This isn't exactly what we want. We want "[Components::Controllers]". So we'll just have to make it ourselves. This is where "lastIndexOf(String str)" and "substring(int beginIndex, int endIndex)" come into play. We want to eliminate the last set of colons and everything after them. So we do this with two commands, first with "lastIndexOf" and then with "substring":
Code: Select all
// Get the index of that last instance of colons //
var lastIndex = selectedElement.getType().getQualifiedName().lastIndexOf("::");

// create a substring with everything after those colons omitted //
var qualName = selectedElement.getType().getQualifiedName().substring(0,lastIndex);

Of course, there is a situation where there aren't any colons with a qualified name. So we might want to add a conditional to check that case. At the end of the day, though, we can put the whole thing inside of a JavaScript function that you can call with a part property input and it will autogenerate the full string that you see in the specification window. Here is what that might look like.

Code: Select all
function fullType(property) {
    // Start by declaring variables //
    var type = "";
    var qName = "";
    var lastColon = 0;
    var output = "";
    // get the element's type first //
    type = property.getType().getName();
    // next get the qualified name //
    qName = property.getType().getQualifiedName();
    // perform the substring process //
    lastColon = qName.lastIndexOf("::");
    if (lastColon != -1) {
        qName = qName.substring(0,lastColon);
        output = type + " [" + qName + "]";
        return output;
    } else {
        return type;

fullType(selectedElement); // -> Returns: "Rockwell PLC [Components::Controllers]"

Hope that helps!

Re: Accessing a Part's Type via JS

PostPosted: Fri Apr 02, 2021 8:37 am
Hey Tiffany, appreciate the response - the .getType().getQualifiedName() is what I was looking for, thanks! This works perfectly now ...