Skip to content

Instantly share code, notes, and snippets.

@jbsarrodie
Last active August 21, 2024 06:22
Show Gist options
  • Save jbsarrodie/45a312cff559d23cf55ed102422e8af7 to your computer and use it in GitHub Desktop.
Save jbsarrodie/45a312cff559d23cf55ed102422e8af7 to your computer and use it in GitHub Desktop.
#jArchi script to change concepts' type (and optionally convert no more valid relationships to association)
function convert(selection, convertToType) {
var relaxed = window.confirm('By default, selected concepts are converted, and relationships involving them that would no more be valid are converted to associations. Click Ok for this behavior or Cancel if you want a "strict" mode where relationships are not changed.');
$(selection).each(function(o) {
$(concept(o)).outRels().each(function(r) {
if (! $.model.isAllowedRelationship(r.type, convertToType, r.target.type)) {
checkAndConvertRelationship(r, relaxed);
}
});
$(concept(o)).inRels().each(function(r) {
if (! $.model.isAllowedRelationship(r.type, r.source.type, convertToType)) {
checkAndConvertRelationship(r, relaxed);
}
});
concept(o).concept.type = convertToType;
});
}
function checkAndConvertRelationship(r, relaxed) {
if (relaxed) {
r.documentation = 'This relationship has been converted from "'+r.type.replace(/-relationship$/, '')+'" to "association"\n'+r.documentation;
r.type = "association-relationship";
} else {
window.alert('Relationship "'+r.name+'" from "'+r.source.name+'" to "'+r.target.name+'" will no more be valid after convertion and "strict" mode is on. Convertion aborted.');
exit();
}
}
function concept(o) {
return o.concept ? o.concept : o;
}
load(__DIR__+"/../ConvertConcept.lib.js");
convert(selection, getTypeFromFilename());
function getTypeFromFilename() {
return __FILE__.replace(/^.*\//, '').replace(/.ajs$/, '').replace(/%20|\s/g, '-').toLowerCase();
}
load(__DIR__+"/../ConvertConcept.lib.js");
convert(selection, getTypeFromFilename());
function getTypeFromFilename() {
return __FILE__.replace(/^.*\//, '').replace(/.ajs$/, '').replace(/%20|\s/g, '-').toLowerCase();
}
@jbsarrodie
Copy link
Author

jbsarrodie commented Dec 12, 2019

Hi,

This script make it really easy to convert concepts (element or relationship) from one type to another. It also takes care of relationships involving the concept been converted: if after the conversion some relationships are no more valid, it will (optionally) convert them to associations.

To make it easy to use, you should create a top level folder inside the Scripts Manager and name it something like Convert to…. Then, save the ConvertConcept.lib.js inside this folder and create subfolders per ArchiMate layers (your can use some prefix to force the order), leading to something like:

Convert to…
  |-- 1. Strategy
  |-- 2. Business
  |-- 3. Application
  |-- 4. Technology & Physical
  |-- 5. Motivation
  |-- 6. Implementation & Migration
  |-- 7. Other
  |-- 8. Relations

Now, in each folder, you can create small scripts (see Strategy\Capability.ajs or Relations\Serving Relationship.ajs as examples) which are all exactly the same. These scripts will load the main library (which contains the conversion logic) and use the script name to know which type to convert to. So the script name must follow some convention: it has to be the name of the selector associated with the type, in which hyphens are replaced by spaces, followed by the usual extension .ajs.

When done, you can easily convert a concept through the contextual menu:
image

And you'll then be prompter to choose between relaxed (default) or strict mode:
image

Hope you'll find it useful.

JB

@Phillipus
Copy link

Very cool. Thanks for sharing!

@vnevzorov
Copy link

Very helpful! I have felt a need for such capability and I was wondering how this could be implemented. You have done that. Thanks.

@pavelsid
Copy link

Thank you for so cute solution!
Just a little fix to ensure all '%20' replacement correctly (Course of Action):

function getTypeFromFilename() {
return FILE.replace(/^.*//, '').replace(/.ajs$/, '').replace(new RegExp('%20','g'),'-').toLowerCase();
}

@rchevallier
Copy link

Excellent. So useful it shall be integrated in Archi by default. Thanks a lot

@IT-Cleric
Copy link

This is awesome! Thank you!

@Phillipus
Copy link

Phillipus commented Oct 29, 2020

Here's a problem.

Windows uses the "%20" character while Mac uses the " " (space) character in the __FILE__ variable for file paths.

So this should fix it:

function getTypeFromFilename() {
    return __FILE__.replace(/^.*\//, '').replace(/.ajs$/, '').replace(/%20|\s/g, '-').toLowerCase();
}

@jbsarrodie - Can you confirm? I can't edit or push to this gist. :-)

@jbsarrodie
Copy link
Author

jbsarrodie commented Oct 29, 2020

@jbsarrodie - Can you confirm? I can't edit or push to this gist. :-)

This should work, I've seen it tested on Archi's Forum so I'm updating the gist.

Thank you!

Edit: Done, but in fact it would be better to redesign a bit the main ConvertConcept.lib.js script to manage this in only one place. I should maybe create a real GitHub repository to store this and other scripts which are part of my 'toolbox'.

@Phillipus
Copy link

Phillipus commented Oct 29, 2020

but in fact it would be better to redesign a bit the main ConvertConcept.lib.js script to manage this in only one place

Yeah, I thought so too and I was going to have a go at it, but then I opened a beer and picked up my guitar...

@Phillipus
Copy link

Phillipus commented Oct 30, 2020

but in fact it would be better to redesign a bit the main ConvertConcept.lib.js script to manage this in only one place

Try this:

ConvertConcept.lib.js

function convert(filename) {
    convertToType = getTypeFromFilename(filename);

    var relaxed = window.confirm('By default, selected concepts are converted, and relationships involving them that would no more be valid are converted to associations. Click OK for this behavior or Cancel if you want a "strict" mode where relationships are not changed.');

    $(selection).each(function (o) {
        $(concept(o)).outRels().each(function (r) {
            if (!$.model.isAllowedRelationship(r.type, convertToType, r.target.type)) {
                checkAndConvertRelationship(r, relaxed);
            }
        });
        $(concept(o)).inRels().each(function (r) {
            if (!$.model.isAllowedRelationship(r.type, r.source.type, convertToType)) {
                checkAndConvertRelationship(r, relaxed);
            }
        });
        concept(o).concept.type = convertToType;
    });
}

function checkAndConvertRelationship(r, relaxed) {
    if (relaxed) {
        r.documentation = 'This relationship has been converted from "' + r.type.replace(/-relationship$/, '') + '" to "association"\n' + r.documentation;
        r.type = "association-relationship";
    } else {
        window.alert('Relationship "' + r.name + '" from "' + r.source.name + '" to "' + r.target.name + '" will not be valid after conversion and "strict" mode is on. Conversion aborted.');
        exit();
    }
}

function concept(o) {
    return o.concept ? o.concept : o;
}

function getTypeFromFilename(fileName) {
    return fileName.replace(/^.*\//, '').replace(/.ajs$/, '').replace(/%20|\s/g, '-').toLowerCase();
}

Capability.ajs

load(__DIR__ + "/../ConvertConcept.lib.js");
convert(__FILE__); 

@Phillipus
Copy link

Phillipus commented Oct 30, 2020

Also, we may be able to remove selection as an argument:

function convert(filename) {
...
load(__DIR__ + "/../ConvertConcept.lib.js");
convert(__FILE__);

Edit - that works, so updated the code above.

@rchevallier
Copy link

rchevallier commented Jan 7, 2021

With the latest jArchi v1.0.0 and support GraalVM, because of __FILE__ change in path format, to support both ES5, ES6 and Graal:

function getTypeFromFilename() {
   return __FILE__.replace(/^.*[\/\\]/, '').replace(/\.ajs$/, '').replace(/(%20|\s)/g, '-').toLowerCase();
} 

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment