Эффективный способ пакетного импорта XMI в Enterprise Architect

наша команда, используя Enterprise Architect version 10 и SVN для репозитория. Потому что EAP размер файла довольно большой (например, 80 МБ), мы экспортируем каждый пакет в отдельный XMI и хранил его в SVN. The EAP сам файл фиксируется после некоторой вехи. Проблема заключается в синхронизации EAP файл с работой от сотрудника во время разработки, нам нужно импортировать много XMI (например, всего может быть 500 файлов).

Я знаю, что после EAP файл обновляется, мы можно использовать Package Control - > получить все последние. Поэтому эта проблема возникает только при параллельной разработке.

мы использовали shorcuts клавиатуры для того чтобы сделать импорт как следовать:

  1. Ctrl+Alt+я (импорт пакета из )
  2. выберите имя файла для импорта
  3. Alt+я (импорт)
  4. Enter (Да)
  5. повторите шаг № 2 до 4, пока модуль не будет завершен

но все же импорт сотен файлов неэффективен.

Я проверил, что пакет управления имеет пакетный Импорт/Экспорт. Пакетный импорт/экспорт работают, когда я явно жестко XMI Filename, но параметры недоступны при использовании контроля версий (параметры пакетного импорта/экспорта выделены серым цветом).

есть ли лучшие способы синхронизации EAP и XMI файлы?

2 ответов


есть сценарии интерфейс в EA. С его помощью можно автоматизировать импорт. Я не использовал его, но, вероятно, довольно хорошо.

Я не уверен, я полностью понимаю вашу рабочую среду, но у меня есть некоторые общие моменты, которые могут быть интересны. Возможно, если вы используете EA по-другому (особенно мой первый пункт ниже), необходимость пакетного импорта может исчезнуть.

Multiworker

во-первых, несколько люди могут работать над одним и тем же файлом EAP одновременно. Файл EAP - это не что иное, как файл базы данных Access, и EA использует блокировку, чтобы остановить одновременное редактирование одного и того же пакета несколькими людьми. Но вы можете комфортно иметь несколько человек, редактирующих разные пакеты в одном файле EAP одновременно. Размещение файла EAP в файловом ресурсе где-то-хороший способ сделать это.

Встроенный Контроль Версий

во-вторых, советник может напрямую взаимодействовать с SVN (и другие системы контроля версий). См.этой. Короче говоря, вы можете настроить файл EAP так, чтобы отдельные пакеты (и все, что ниже них) контролировались SVN. Затем вы можете проверить отдельный пакет, отредактировать его, вернуть обратно. Или действительно, Вы можете проверить всю ветку ниже пакета (включая субпакеты, которые сами управляются SVN).

под капотом EA импортирует и экспортирует файлы XMI и проверяет их в SVN и из SVN, в то время как EAP файл всегда ревизии. Как и то, что вы делаете вручную, но автоматически. Это имеет смысл, учитывая, что вы все можете использовать один файл ВП. Вам нужно быть немного осторожным при откате-ссылки, исходящие из объектов в более старых версиях одного пакета, могут указывать на объекты, которые больше не существуют (но вы можете посмотреть на ошибки журнала импорта, чтобы увидеть, так ли это). Это займет немного привыкнуть, но это работает довольно хорошо.

там также встроенный пакет baselining функциональность - это может быть все, что вам нужно в любом случае, и работает довольно хорошо, особенно если вы все используете тот же файл EAP.

Больший Компонент Database Engine

В-третьих, вам не обязательно иметь файл EAP вообще. База данных модели может находиться в любой подходящей системе баз данных (MySQL, SQL Server, Oracle и др.). Так что дает вам всевозможные варианты для масштабирования, как он используется,что его как через WAN / Интернет и т. д.

короче Sparx имеют было довольно разумно о том, как EA можно использовать в многопользовательской среде, и его стоит использовать.


Я создал скрипт EA с помощью JScript для автоматизации

вот скрипт для экспорта:

!INC Local Scripts.EAConstants-JScript

/*
 * Script Name : Export List of SVN Packages
 * Author      : SDK
 * Purpose     : Export a package and all of its subpackages information related to version 
 *               controlled. The exported file then can be used to automatically import
 *               the XMIs
 * Date        : 30 July 2013
 * HOW TO USE  : 1. Select the package that you would like to export in the Project Browser
 *               2. Change the output filepath in this script if necessary.
 *                  By default it is "D:\EAOutput.txt"
 *               3. Send the output file to your colleague who wanted to import the XMIs
 */

var f; 

function main()
{
    // UPDATE THE FOLLOWING OUTPUT FILE PATH IF NECESSARY
    var filename = "D:\EAOutput.txt";

    var ForReading = 1, ForWriting = 2, ForAppending = 8;

    Repository.EnsureOutputVisible( "Script" );
    Repository.ClearOutput( "Script" );
    Session.Output("Start generating output...please wait...");

    var treeSelectedType = Repository.GetTreeSelectedItemType();

    switch ( treeSelectedType )
    {
        case otPackage:
        {
            var fso = new ActiveXObject("Scripting.FileSystemObject");
            f = fso.OpenTextFile(filename, ForWriting, true);

            var selectedObject as EA.Package;
            selectedObject = Repository.GetContextObject();
            reportPackage(selectedObject);
            loopChildPackages(selectedObject);

            f.Close();
            Session.Output( "Done! Check your output at " + filename);
            break;
        }
        default:
        {
            Session.Prompt( "This script does not support items of this type.", promptOK );
        }
    }
}

function loopChildPackages(thePackage)
{
    for (var j = 0 ; j < thePackage.Packages.Count; j++)
    {
        var child as EA.Package;
        child = thePackage.Packages.GetAt(j);
        reportPackage(child);
        loopChildPackages(child);
    }
}

function getParentPath(childPackage)
{
    if (childPackage.ParentID != 0)
    {
        var parentPackage as EA.Package;
        parentPackage =  Repository.GetPackageByID(childPackage.ParentID);
        return getParentPath(parentPackage) + "/" + parentPackage.Name;
    }
    return "";
}

function reportPackage(thePackage)
{
    f.WriteLine("GUID=" + thePackage.PackageGUID + ";"
                   + "NAME=" + thePackage.Name + ";" 
                   + "VCCFG=" + getVCCFG(thePackage) + ";" 
                   + "XML=" + thePackage.XMLPath + ";"
                   + "PARENT=" + getParentPath(thePackage).substring(1) + ";"
    );
}

function getVCCFG(thePackage)
{
    if (thePackage.IsVersionControlled)
    {
        var array = new Array();
        array = (thePackage.Flags).split(";");

        for (var z = 0 ; z < array.length; z++)
        {
            var pos = array[z].indexOf('=');

            if (pos > 0)
            {
                var key = array[z].substring(0, pos);
                var value = array[z].substring(pos + 1);

                if (key=="VCCFG")
                {
                    return (value);
                }
            }
        }
    }
    return "";
}

main();

и скрипт для импорта:

!INC Local Scripts.EAConstants-JScript

/*
 * Script Name : Import List Of SVN Packages
 * Author      : SDK
 * Purpose     : Imports a package with all of its sub packages generated from 
 *               "Export List Of SVN Packages" script
 * Date        : 01 Aug 2013
 * HOW TO USE  : 1. Get the output file generated by "Export List Of SVN Packages" script
 *                  from your colleague
 *               2. Get the XMIs in the SVN local copy
 *               3. Change the path to the output file in this script if necessary (var filename).
 *                  By default it is "D:\EAOutput.txt"
 *               4. Change the path to local SVN
 *               5. Run the script
 */

var f; 
var svnPath;

function main()
{
    // CHANGE THE FOLLOWING TWO LINES ACCORDING TO YOUR INPUT AND LOCAL SVN COPY
    var filename = "D:\EAOutput.txt";
    svnPath = "D:\svn.xxx.com\yyy\docs\design\";

    var ForReading = 1, ForWriting = 2, ForAppending = 8;

    Repository.EnsureOutputVisible( "Script" );
    Repository.ClearOutput( "Script" );
    Session.Output("[INFO] Start importing packages from " + filename + ". Please wait...");

    var fso = new ActiveXObject("Scripting.FileSystemObject");
    f = fso.OpenTextFile(filename, ForReading);

    // Read from the file and display the results.
    while (!f.AtEndOfStream)
    {
        var r = f.ReadLine();
        parseLine(r);
        Session.Output("--------------------------------------------------------------------------------");
    }

    f.Close();
    Session.Output("[INFO] Finished");
}

function parseLine(line)
{
    Session.Output("[INFO] Parsing " + line);

    var array = new Array();
    array = (line).split(";");

    var guid;
    var name;
    var isVersionControlled;
    var xmlPath;
    var parentPath;

    isVersionControlled = false;
    xmlPath = "";

    for (var z = 0 ; z < array.length; z++)
    {
        var pos = array[z].indexOf('=');

        if (pos > 0)
        {
            var key = array[z].substring(0, pos);
            var value = array[z].substring(pos + 1);

            if (key=="GUID") {
                guid = value;
            } else if (key=="NAME") {
                name = value;
            } else if (key=="VCCFG") {
                if (value != "") {
                    isVersionControlled = true;
                }
            } else if (key=="XML") {
                if (isVersionControlled) {
                    xmlPath = value;
                }
            } else if (key=="PARENT") {
                parentPath = value;
            }
        }
    }

    // Quick check for target if already exist to speed up process
    var targetPackage as EA.Package;
    targetPackage = Repository.GetPackageByGuid(guid);
    if (targetPackage != null)
    {
        // target exists, do not do anything
        Session.Output("[DEBUG] Target package \"" + name + "\" already exist");
        return;
    }

    var paths = new Array();
    var packages = new Array(paths.Count);

    for (var i = 0; i < paths.Count; i++)
    {
        packages[i] = null;
    }

    paths = (parentPath).split("/");

    if (paths.Count < 2)
    {
        Session.Output("[INFO] Skipped root or level1");
        return;
    }

    packages[0] = selectRoot(paths[0]);
    packages[1] = selectPackage(packages[0], paths[1]);

    if (packages[1] == null)
    {
        Session.Output("[ERROR] Cannot find " + paths[0] + "/" + paths[1] + "in Project Browser");
        return;
    }

    for (var j = 2; j < paths.length; j++)
    {
        packages[j] = selectPackage(packages[j - 1], paths[j]);
        if (packages[j] == null)
        {
            Session.Output("[DEBUG] Creating " + packages[j].Name);

            // create the parent package
            var parent as EA.Package;
            parent = Repository.GetPackageByGuid(packages[j-1].PackageGUID);
            packages[j] = parent.Packages.AddNew(paths[j], "");
            packages[j].Update();
            parent.Update();
            parent.Packages.Refresh();
            break;
        }
    }

    // Check if name (package to import) already exist or not
    var targetPackage = selectPackage(packages[paths.length - 1], name);

    if (targetPackage == null)
    {
        if (xmlPath == "")
        {
            Session.Output("[DEBUG] Creating " + name);

            // The package is not SVN controlled
            var newPackage as EA.Package;
            newPackage = packages[paths.length - 1].Packages.AddNew(name,"");
            Session.Output("New GUID = " + newPackage.PackageGUID);
            newPackage.Update();
            packages[paths.length - 1].Update();
            packages[paths.length - 1].Packages.Refresh();
        }
        else
        {
            // The package is not SVN controlled
            Session.Output("[DEBUG] Need to import: " + svnPath + xmlPath);

            var project as EA.Project;
            project = Repository.GetProjectInterface;
            var result;

            Session.Output("GUID = " + packages[paths.length - 1].PackageGUID);
            Session.Output("GUID XML = " + project.GUIDtoXML(packages[paths.length - 1].PackageGUID));
            Session.Output("XMI file = " + svnPath + xmlPath);
            result = project.ImportPackageXMI(project.GUIDtoXML(packages[paths.length - 1].PackageGUID), svnPath + xmlPath, 1, 0);
            Session.Output(result);

            packages[paths.length - 1].Update();
            packages[paths.length - 1].Packages.Refresh();
        }

    }
    else
    {
        // target exists, do not do anything
        Session.Output("[DEBUG] Target package \"" + name + "\" already exist");
    }
}

function selectPackage(thePackage, childName)
{
    var childPackage as EA.Package;
    childPackage = null;

    if (thePackage == null)
        return null;

    for (var i = 0; i < thePackage.Packages.Count; i++)
    {
        childPackage = thePackage.Packages.GetAt(i);

        if (childPackage.Name == childName)
        {
            Session.Output("[DEBUG] Found " + childName);
            return childPackage;
        }
    }

    Session.Output("[DEBUG] Cannot find " + childName);
    return null;
}

function selectRoot(rootName)
{
    for (var y = 0; y < Repository.Models.Count; y++)
    {
        root = Repository.Models.GetAt(y);
        if (root.Name == rootName)
        {
            return root;
        }
    }
    return null;
}

main();