【问题标题】:Efficient Way to do batch import XMI in Enterprise Architect在 Enterprise Architect 中批量导入 XMI 的有效方法
【发布时间】:2013-05-24 10:49:03
【问题描述】:

我们的团队正在使用 Enterprise Architect version 10SVN 作为存储库。 因为EAP 文件非常大(例如80 MB),我们将每个包导出到单独的XMI 并存储到SVNEAP 文件本身在某个里程碑之后被提交。问题是在开发过程中将EAP文件与同事的工作同步,我们需要导入大量XMI(例如总共可以是500个文件)。

我知道一旦EAP 文件更新,我们可以使用Package Control -> Get All Latest。所以这个问题只发生在并行开发过程中。

我们使用键盘快捷键进行导入,如下所示:

  1. Ctrl+Alt+I(从XMI文件导入包)
  2. 选择要导入的文件名
  3. Alt+I(导入)
  4. 输入(是)
  5. 重复步骤 2 到 4,直到模块完成

但是,导入数百个文件仍然是低效的。

我已检查控制包是否具有批量导入/导出功能。当我明确硬编码XMI Filename 时,批量导入/导出正在工作,但如果使用版本控制,则选项不可用(批量导入/导出选项为灰色)。

有没有更好的方法来同步EAPXMI 文件?

【问题讨论】:

    标签: optimization uml enterprise-architect xmi


    【解决方案1】:

    EA 中有一个scripting 接口。您也许可以使用它来自动导入。没用过,应该不错吧。

    我不确定我是否完全了解您的工作环境,但我有一些您可能感兴趣的一般性观点。如果您以不同的方式使用 EA(尤其是我在下面的第一点),可能不需要批量导入。

    多人工作

    首先,多人可以同时处理同一个 EAP 文件。 EAP 文件只不过是一个 Access 数据库文件,EA 使用锁定来阻止多人同时编辑同一个包。但是您可以轻松地让多人同时在一个 EAP 文件中编辑不同的包。将 EAP 文件放在某个文件共享上是一种很好的方法。

    内置修订控制

    其次,EA 可以直接与 SVN(和其他版本控制系统)交互。见this。简而言之,您可以设置您的 EAP 文件,以便单个包(以及它们下面的所有内容)受 SVN 控制。然后,您可以签出单个包,对其进行编辑,重新签入。或者实际上您可以签出包下的整个分支(包括本身受 SVN 控制的子包)。

    EA 的底层是导入和导出 XMI 文件并将它们签入和签出 SVN,而 EAP 文件始终是主要版本。就像你手工做的一样,但是是自动化的。这是有道理的,因为您都可以使用一个 EAP 文件。您确实必须小心回滚 - 源自一个包的旧版本中的对象的链接可能指向不再存在的对象(但您可以查看导入日志错误以查看是否是这种情况)。这需要一点时间来适应,但效果很好。

    还有内置的包基线功能 - 无论如何这可能就是您所需要的,而且效果很好,特别是如果您都使用相同的 EAP 文件。

    更大的数据库引擎

    第三,您根本不需要 EAP 文件。该模型的数据库可以在任何合适的数据库系统(MySQL、SQL Server、Oracle 等)中。因此,这为您提供了各种选项来扩展其使用方式、在 WAN/Internet 上的情况等。

    简而言之,Sparx 对于如何在多工人环境中使用 EA 非常明智,并且值得加以利用。

    【讨论】:

    • 好的,让我检查一下脚本和内置修订控制
    • 内置修订控制与我们现在所做的类似。将包签入到 SVN 并获取 XMI 导出没有问题。问题在于 XMI 的第一次导入,因为每个团队成员都使用自己的 EAP 文件。对于脚本,我只看到了几个例子和解释:(
    • 每个团队成员的 EAP 文件名义上是否相同?如果是这样,您可以选择一个完全最新的(或制作一个),将其粘贴到文件共享中,然后每个人都可以放弃自己的并开始使用那个。然后,您可以设置该单个 EAP 文件以将其自身与 SVN 集成。您将失去修订历史的连续性。简而言之,我建议一次性获取单个 EAP 文件,然后从现在开始使用 EA 的内置自动化 SVN 集成。
    • 每个团队成员都从同一个 EAP 文件开始(不是共享的,而是单独的副本)。后来,他们每个人都在不同的包上工作。因此,我们只能取其中一个EAP,仍然需要导入其他团队成员开发的包
    • 如果您想努力拥有一个共享的 EAP 文件,您可以执行以下操作。让团队成员配对并让他们在他们之间制作一个 EAP 文件。然后获取这些结果,将它们配对,等等。从例如去。 16 个 EAP 到 8、4、2、1。应该相当快
    【解决方案2】:

    我已经使用 JScript 为自动化创建了 EA 脚本

    这是执行导出的脚本:

    !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();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多