Skip to content

Instantly share code, notes, and snippets.

@romualdrichard
Created January 29, 2026 13:59
Show Gist options
  • Select an option

  • Save romualdrichard/b0e9f3198207e6b8be65a6698787864c to your computer and use it in GitHub Desktop.

Select an option

Save romualdrichard/b0e9f3198207e6b8be65a6698787864c to your computer and use it in GitHub Desktop.
#jarchi create a view from a criteria
/*
* JArchi Script - Search and Create View
* Search for model elements by text and create a view with the results
*/
// Import necessary SWT classes
var SWT = Java.type('org.eclipse.swt.SWT');
var Shell = Java.type('org.eclipse.swt.widgets.Shell');
var Display = Java.type('org.eclipse.swt.widgets.Display');
var Dialog = Java.type('org.eclipse.swt.widgets.Dialog');
var Label = Java.type('org.eclipse.swt.widgets.Label');
var Text = Java.type('org.eclipse.swt.widgets.Text');
var Button = Java.type('org.eclipse.swt.widgets.Button');
var Combo = Java.type('org.eclipse.swt.widgets.Combo');
var GridLayout = Java.type('org.eclipse.swt.layout.GridLayout');
var GridData = Java.type('org.eclipse.swt.layout.GridData');
var SelectionAdapter = Java.type('org.eclipse.swt.events.SelectionAdapter');
// Class for the search dialog box
function SearchDialog(parentShell) {
this.searchText = "";
this.scope = "all"; // all, elements, relations
this.searchInName = true;
this.searchInDocumentation = true;
this.searchInProperties = true;
this.cancelled = true;
this.open = function() {
var display = parentShell ? parentShell.getDisplay() : Display.getDefault();
var shell = new Shell(parentShell, SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL);
shell.setText("Search ArchiMate Elements");
shell.setSize(500, 300);
var layout = new GridLayout(2, false);
shell.setLayout(layout);
// Label and text field for search
var labelSearch = new Label(shell, SWT.NONE);
labelSearch.setText("Search text:");
var textSearch = new Text(shell, SWT.BORDER);
var gdText = new GridData(SWT.FILL, SWT.CENTER, true, false);
textSearch.setLayoutData(gdText);
// Label and combo for scope
var labelScope = new Label(shell, SWT.NONE);
labelScope.setText("Search scope:");
var comboScope = new Combo(shell, SWT.READ_ONLY);
comboScope.setItems(["All model", "Elements only", "Relations only"]);
comboScope.select(0);
var gdCombo = new GridData(SWT.FILL, SWT.CENTER, true, false);
comboScope.setLayoutData(gdCombo);
// Label for search criteria
var labelCriteria = new Label(shell, SWT.NONE);
labelCriteria.setText("Search in:");
var gdLabelCriteria = new GridData(SWT.LEFT, SWT.TOP, false, false);
labelCriteria.setLayoutData(gdLabelCriteria);
// Composite for checkboxes
var checkboxComposite = new Shell(shell, SWT.NONE);
var checkboxLayout = new GridLayout(1, false);
checkboxComposite.setLayout(checkboxLayout);
var gdCheckboxComposite = new GridData(SWT.FILL, SWT.FILL, true, false);
checkboxComposite.setLayoutData(gdCheckboxComposite);
var checkName = new Button(shell, SWT.CHECK);
checkName.setText("Name");
checkName.setSelection(true);
var gdCheckName = new GridData(SWT.FILL, SWT.CENTER, true, false);
checkName.setLayoutData(gdCheckName);
var checkDoc = new Button(shell, SWT.CHECK);
checkDoc.setText("Documentation");
checkDoc.setSelection(true);
var gdCheckDoc = new GridData(SWT.FILL, SWT.CENTER, true, false);
checkDoc.setLayoutData(gdCheckDoc);
var checkProps = new Button(shell, SWT.CHECK);
checkProps.setText("Properties");
checkProps.setSelection(true);
var gdCheckProps = new GridData(SWT.FILL, SWT.CENTER, true, false);
checkProps.setLayoutData(gdCheckProps);
// OK and Cancel buttons
var buttonComposite = new Shell(shell, SWT.NONE);
var buttonLayout = new GridLayout(2, true);
buttonComposite.setLayout(buttonLayout);
var gdButtons = new GridData(SWT.RIGHT, SWT.CENTER, true, false);
gdButtons.horizontalSpan = 2;
buttonComposite.setLayoutData(gdButtons);
var btnOK = new Button(shell, SWT.PUSH);
btnOK.setText("OK");
var gdOK = new GridData(SWT.RIGHT, SWT.CENTER, false, false);
gdOK.widthHint = 80;
gdOK.horizontalSpan = 1;
btnOK.setLayoutData(gdOK);
var btnCancel = new Button(shell, SWT.PUSH);
btnCancel.setText("Cancel");
var gdCancel = new GridData(SWT.RIGHT, SWT.CENTER, false, false);
gdCancel.widthHint = 80;
btnCancel.setLayoutData(gdCancel);
var self = this;
// Handle OK button
btnOK.addSelectionListener(new SelectionAdapter() {
widgetSelected: function(e) {
self.searchText = textSearch.getText();
var scopeIndex = comboScope.getSelectionIndex();
if (scopeIndex === 0) self.scope = "all";
else if (scopeIndex === 1) self.scope = "elements";
else if (scopeIndex === 2) self.scope = "relations";
self.searchInName = checkName.getSelection();
self.searchInDocumentation = checkDoc.getSelection();
self.searchInProperties = checkProps.getSelection();
// Verify that at least one criterion is selected
if (!self.searchInName && !self.searchInDocumentation && !self.searchInProperties) {
window.alert("Please select at least one search criterion!");
return;
}
self.cancelled = false;
shell.close();
}
});
// Handle Cancel button
btnCancel.addSelectionListener(new SelectionAdapter() {
widgetSelected: function(e) {
self.cancelled = true;
shell.close();
}
});
// Center the window
var parentBounds = parentShell ? parentShell.getBounds() : display.getPrimaryMonitor().getBounds();
var shellBounds = shell.getBounds();
var x = parentBounds.x + (parentBounds.width - shellBounds.width) / 2;
var y = parentBounds.y + (parentBounds.height - shellBounds.height) / 2;
shell.setLocation(x, y);
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
return !this.cancelled;
};
}
// Function to search for text in an element
function matchesSearch(element, searchText, searchInName, searchInDocumentation, searchInProperties) {
if (!searchText || searchText.trim() === "") {
return true;
}
var search = searchText.toLowerCase();
// Search in name
if (searchInName && element.name && element.name.toLowerCase().indexOf(search) !== -1) {
return true;
}
// Search in documentation
if (searchInDocumentation && element.documentation && element.documentation.toLowerCase().indexOf(search) !== -1) {
return true;
}
// Search in properties
if (searchInProperties && element.prop) {
var props = element.prop();
for (var i = 0; i < props.length; i++) {
var key = props[i];
var value = element.prop(key);
if (key.toLowerCase().indexOf(search) !== -1 ||
(value && value.toLowerCase().indexOf(search) !== -1)) {
return true;
}
}
}
return false;
}
// Main function
function main() {
// Check that a model is open
if (!model) {
window.alert("No model is open!");
return;
}
// Display the dialog box
var dialog = new SearchDialog(shell);
if (!dialog.open()) {
console.log("Search cancelled by user");
return;
}
var searchText = dialog.searchText;
var scope = dialog.scope;
var searchInName = dialog.searchInName;
var searchInDocumentation = dialog.searchInDocumentation;
var searchInProperties = dialog.searchInProperties;
console.log("Search: '" + searchText + "' in scope: " + scope);
console.log("Search in - Name: " + searchInName + ", Documentation: " + searchInDocumentation + ", Properties: " + searchInProperties);
// Collections to store results
var foundElements = [];
var foundRelations = [];
var elementsToDisplay = {}; // Map to avoid duplicates
// Search in elements
if (scope === "all" || scope === "elements") {
$("element").each(function(element) {
if (matchesSearch(element, searchText, searchInName, searchInDocumentation, searchInProperties)) {
foundElements.push(element);
elementsToDisplay[element.id] = element;
}
});
}
// Search in relations
if (scope === "all" || scope === "relations") {
$("relationship").each(function(relation) {
if (matchesSearch(relation, searchText, searchInName, searchInDocumentation, searchInProperties)) {
foundRelations.push(relation);
// Add source and target of found relations
if (relation.source) {
elementsToDisplay[relation.source.id] = relation.source;
}
if (relation.target) {
elementsToDisplay[relation.target.id] = relation.target;
}
}
});
}
// Remove duplicates in relations
var uniqueRelations = [];
var relationIds = {};
foundRelations.forEach(function(rel) {
if (!relationIds[rel.id]) {
uniqueRelations.push(rel);
relationIds[rel.id] = true;
}
});
console.log("Elements found: " + foundElements.length);
console.log("Relations found: " + uniqueRelations.length);
console.log("Total elements to display: " + Object.keys(elementsToDisplay).length);
// Check if there are results
if (Object.keys(elementsToDisplay).length === 0 && uniqueRelations.length === 0) {
window.alert("No results found for '" + searchText + "'");
return;
}
// Create a new view
var scopeLabel = "";
if (scope === "all") scopeLabel = "All";
else if (scope === "elements") scopeLabel = "Elements";
else if (scope === "relations") scopeLabel = "Relations";
var viewName = "Search [" + scopeLabel + "]: " + searchText;
var view = model.createArchimateView(viewName);
// Add elements to the view
var visualElements = {};
var x = 50, y = 50;
var spacing = 150;
var elementsPerRow = 5;
var count = 0;
for (var id in elementsToDisplay) {
var element = elementsToDisplay[id];
var visualElement = view.add(element, x, y, -1, -1);
visualElements[id] = visualElement;
count++;
if (count % elementsPerRow === 0) {
x = 50;
y += spacing;
} else {
x += spacing;
}
}
// Add relations to the view
uniqueRelations.forEach(function(relation) {
if (visualElements[relation.source.id] && visualElements[relation.target.id]) {
view.add(relation, visualElements[relation.source.id], visualElements[relation.target.id]);
}
});
// Apply automatic layout
view.openInUI();
var message = "View created successfully!\n\n" +
"Elements: " + Object.keys(elementsToDisplay).length + "\n" +
"Relations: " + uniqueRelations.length;
window.alert(message);
}
// Run the script
main();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment