Using scripting to copy a subset of one model to a new model

Started by fanievh, July 13, 2023, 10:47:01 AM

Previous topic - Next topic

fanievh

Apologies if what I'm asking is already solved in a much simpler way.

I want to be able to select a folder containing views and possibly sub-folders with views and "copy" this to a new Archi Model. So it's not a copy of the whole source model, only a selected subset of it.  That means all the elements present on the views, all the relationships, the folders relative to the folder selected, all the views in the correct folders.  I'm not sure if there's a simple or elegant way to do this (other than round tripping from current model to CSV and back to target model with some scripts that the community has created).  If there is a way to do this easily, please ignore the rest and I would appreciate advice how to do it (and this might be a total noob question, so apologies)?

I'm considering creating a jArchi script for that.  Obviously such a script would not just have to create all the relevant concepts in the target model by iterating through the source model collections, but also need to ensure that the visual elements are recreated correctly ito bounds etc in the target model.

Is it feasible to work with 2 models concurrently in a script, one being set as the current model and having a reference to the other model and switching between them as required by the scripting logic?  It seems to be implied in the API documentation, but I might be misreading it?

From the documentation:
var myModel = model.load("path/test.archimate");
myModel.setAsCurrent();


jsimoncello

Hi,
I have done something similar, but I don't really work on two models simultaneously. I copy the whole model to a new one, then remove everything I don't want  :
var FileClass = Java.type('java.io.File');

var filePath = window.promptSaveFile({ title: "Exporter le nouveau modèle ", filterExtensions: ["*.archimate"] });
var newModelFile = new FileClass(filePath);
if (filePath != null) {
    model.save(filePath);
    $.model.load(filePath).setAsCurrent();
    model.name = newModelFile.getName() + " export (" + new Date().toISOString().slice(0, 10) + ")";
}

Jean-Baptiste Sarrodie

Hi,

There's an easy way to do this:

1. Create a copy of the "source" model and delete any view you don't want.
2. Run a script to delete any element or relationship that does not appear in the remaining view: https://gist.github.com/jbsarrodie/aae4ed4981ada94834cfdf48d978a13f
3. Import the resulting model into your "target" model

Regards,

JB
If you value and use Archi, please consider making a donation!
Ask your ArchiMate related questions to the ArchiMate Community's Discussion Board.

fanievh

Thank you for the replies and suggestions. I decided to develop a script which does the copying of a selected folder in a model to a new model.  Even though it was much more work, I did it partly to better understand the jArchi API and also because I have some use cases that will require a subset of similar code to create diagrams.

https://gist.github.com/fanievh/4ec7d14247616846f3d16b5e22dc80a9

I'm sure there are still some bugs and edge cases not supported by the current version. One of the challenges I haven't found a solution for, is how to save/export any custom images in a model which are linked to visual objects or specializations, in order to add them to a target model. Is there a way to do that?

From the documentation and examples it doesn't seem to be the case:
// Load an image and assign it
object.imageSource = IMAGE_SOURCE.CUSTOM;
object.image = model.createImage("cat.png");

// Use an image from another object in the same model
object.imageSource = IMAGE_SOURCE.CUSTOM;
object.image = anotherObject.image;

fanievh

I guess I would need some Java code in the script, similar to the code below in the GraficoModelExporter class, to store the custom images in the source model to the file system and then add them to the target model using model.createImage("cat.png") ??

/**
     * Extract and save images used inside a model as separate image files
     */
    private void saveImages() throws IOException {
        Set<String> added = new HashSet<>();

        IArchiveManager archiveManager = (IArchiveManager)fModel.getAdapter(IArchiveManager.class);
        if(archiveManager == null) {
            archiveManager = IArchiveManager.FACTORY.createArchiveManager(fModel);
        }
       
        for(Iterator<EObject> iter = fModel.eAllContents(); iter.hasNext();) {
            EObject eObject = iter.next();
            if(eObject instanceof IDiagramModelImageProvider) {
                IDiagramModelImageProvider imageProvider = (IDiagramModelImageProvider)eObject;
                String imagePath = imageProvider.getImagePath();
               
                if(imagePath != null && !added.contains(imagePath)) {
                    byte[] bytes = archiveManager.getBytesFromEntry(imagePath);
                    if(bytes == null) {
                        throw new IOException("Could not get image bytes from image path: " + imagePath); //$NON-NLS-1$
                    }
                   
                    File file = new File(fLocalRepoFolder, imagePath);
                    Files.write(file.toPath(), bytes, StandardOpenOption.CREATE);
                    added.add(imagePath);
                }
            }
        }
    }

fanievh

Updated the script to copy custom images from the source model to the target model. Not super elegant but it works (only if the source model archimate file is in archive/zip format)

Was a good learning experience but I think it would probably be better as a plugin because the custom image code isn't exposed to the javascript environment by JArchi. I would definitely support a move to store the custom images as EMF objects in a future version of Archi  :)

Thanks to the team making Archi what it is today.  I really appreciate the power that it provides users to craft very powerful solutions using it.

https://gist.github.com/fanievh/4ec7d14247616846f3d16b5e22dc80a9