JArchi Script Development
Procedural guide for writing JArchi scripts (GraalVM GraalJS, ECMAScript 2024). Requires Archi 5.7+, JArchi 1.11+.
Constraints (NOT Node.js)
- Use
load()for local files — neverrequire()(it resolves tonode_modules/) - No Web Workers, no async I/O, no
setTimeout(unless shimmed) - No Node.js modules (
fs,path,http) — useJava.type()for Java equivalents thisinsideJava.extend()refers to the Java proxy — use the object wrapper pattern below
Creating a Script
Every top-level .ajs script: clear console, load log.js, IIFE, try-catch, "use strict":
/**
* @name Script Name
* @description Brief description
* @version 1.0.0
* @author Author Name
* @lastModifiedDate YYYY-MM-DD
*/
console.clear();
console.show();
load(__DIR__ + "lib/log.js");
load(__DIR__ + "lib/swtImports.js");
(function () {
"use strict";
try {
log.header("Script Name");
// Main script logic
log.success("Script Name: Complete.");
} catch (error) {
log.error("Script failed: " + error.toString());
window.alert("Error: " + error.message);
}
})();
Use Title Case with spaces for .ajs filenames (e.g., ELK Layout.ajs). __DIR__ already includes trailing separator — don't add /.
Creating a Library Module
To create a reusable module in lib/, use the dual-export IIFE with a double-load guard:
(function() {
"use strict";
if (typeof globalThis !== "undefined" && typeof globalThis.myModule !== "undefined") return;
// ... module code ...
if (typeof globalThis !== "undefined") globalThis.myModule = myModule;
if (typeof module !== "undefined" && module.exports) module.exports = myModule;
})();
To load a module: load(__DIR__ + "lib/myModule.js"); then destructure from the global.
Working with the Model
To get the active view, use resolveSelection (never $(selection).filter("archimate-diagram-model")):
load(__DIR__ + "lib/resolveSelection.js");
var view = resolveSelection.activeView(); // current view
var elements = resolveSelection.selectedConcepts("element"); // selected elements
To query elements: $("business-process"). To create: model.createElement("business-process", "Name"). To create relationships: model.createRelationship("serving-relationship", source, target).
Always handle empty names: element.name && element.name.trim() ? element.name : "-- unnamed --".
Building Dialogs
To create a dialog, use swtImports.ExtendedTitleAreaDialog with the object wrapper pattern. Both isResizable and getShellStyle overrides are required — isResizable alone fails because the Java.extend proxy isn't wired during the Java constructor. Always call setHelpAvailable(false) before open().
load(__DIR__ + "lib/swtImports.js");
var { SWT, Text, GridDataFactory, ExtendedTitleAreaDialog } = swtImports;
var myDialog = {
dialog: new ExtendedTitleAreaDialog(shell, {
configureShell: function(newShell) {
Java.super(myDialog.dialog).configureShell(newShell);
newShell.setText("My Dialog");
},
isResizable: function() { return true; },
getShellStyle: function() {
return SWT.CLOSE | SWT.TITLE | SWT.BORDER | SWT.APPLICATION_MODAL | SWT.RESIZE | SWT.MAX;
},
createDialogArea: function(parent) {
var area = Java.super(myDialog.dialog).createDialogArea(parent);
myDialog.dialog.setMessage("Enter information:");
var text = new Text(area, SWT.BORDER);
GridDataFactory.fillDefaults().grab(true, false).applyTo(text);
myDialog._nameText = text;
return area;
},
okPressed: function() {
var value = myDialog._nameText.getText().trim();
if (!value) { myDialog.dialog.setErrorMessage("Required"); return; }
Java.super(myDialog.dialog).okPressed();
}
})
};
myDialog.dialog.setHelpAvailable(false);
if (myDialog.dialog.open() === 0) { /* user clicked OK */ }
For simple prompts: window.prompt("Enter name:"), window.confirm("Sure?"), window.alert("Done.").
Critical Pitfalls
Java.super(this)fails — always useJava.super(myDialog.dialog)via stored object propertyrequire()fails for local files — useload(__DIR__ + "lib/file.js")- Raw
$(selection)misses cases — useresolveSelection.selectedConcepts()/.activeView() - Non-resizable dialogs — override both
isResizable()ANDgetShellStyle() - Help button showing — call
dialog.setHelpAvailable(false)beforeopen() - Null element names — always guard with
name && name.trim()check - Raw console.log — use
log.header/info/detail/success/warn/errorfromlib/log.js - Undisposed resources — use try/finally for Color, Font, Image
- Double path separator —
__DIR__already has trailing separator
Reference Files
For detailed API docs, SWT widget reference, layout patterns, and complete examples:
references/script-development-guide.md— Full guide with dialog patterns, model operations, widget reference, and migration checklistreferences/jarchi-api-reference.md— JArchi 1.11 API: collection methods, element types, view operationsreferences/graaljs-compatibility.md— GraalJS runtime: ECMAScript 2024 features,load()semanticsreferences/java-interop.md—Java.type(),Java.extend(),Java.super(), type mappings, array conversions
Converted and distributed by TomeVault — claim your Tome and manage your conversions.