實現 UML 模型的自動化比較及合併

myattitude發表於2009-04-14
在這篇文章中,“Rational 軟體”表示這些產品中的任何一個:Rational® Software Architect, Rational® Application Developer, 或者 Rational® Software Modeler。

這裡有幾種情形,對通過命令列工具在模型之間產生差別列表是十分有利的,在一個構建過程或者當量中或許只是作為一個步驟。例如:

  • 在一個模型當量的任何一點,都可能選擇兩個版本——或許是最新的版本和在先前構建基線的版本——為釋出到 Wiki 或者其它 Web 網頁進行瀏覽產生一個差異列表。
  • 在簡單的 ad hoc 建模中,可能要在各自獨立的開發模型中執行這個過程,且這兩個模型擁有類似的結構並演化成共享的語義資料,比如有相同名稱的類和角色。此外,有了合併這些模型可以用這種方式來比較。
  • 在高階的模型驅動開發情景中,一個軟體構架可以調解使一個演化模型與一個生成的演化碼基線一致,從 Java 到 UML 轉換能力可以產生一個可以與原始原始碼一致並可以與之比較的模型,從而建立和釋出這個瀏覽列表。

這篇文章主要研究 MDD 情形,因為這很可能就是這個技術所需要的情形。而在其它 情形採用此技術則相對比較直接。

在程式碼和模型之間產生差量列表的選項

根據這個專案規模的大小,主模型的變更可來自多個開發人員。一個構件可能需要在將它們引入到主模型之前瀏覽來自單個貢獻者的變更設定。通常情況下,這是由一個轉換來完成的,比如 Java-to-UML。這個轉換會產生一個反映 Java 程式碼當前狀態的 UML 模型。要檢視主模型和一個源自此程式碼的模型之間的區別,可以採取幾種方式來實現。

方法之一是將這個目標轉換輸出作為這個主模型。在 Rational 軟體環境中執行此轉換將會啟動一個可視的結構合併會話(正如 融合 ——請參見下面的 Note),這樣可以在把它們應用到主機(目標)模型之前展現一個變更列表。這種方法將會在委託此結構合併會話之上修改這個主模型。

註釋: 融合 (一個 結構對比)是一項僅僅利用合格的名稱來對照模型的技術,並且為在模型之間或者結構變更提供一個機制,而且無論這些模型是否共享一個始祖。它還受到合併模型命令的刺激。融合廣泛地應用於 MDD 中 調整工作流程

然而,這項技術卻不能自動從命令列中產生。相反,這個合併技術(請參見下面的 Note)卻可用來將這個問題轉換為身份的對照。一個生成的模型可以儲存到一個位置標誌符(一個空白模型),與主模型合併,然後對照會話就可以執行,從而建立一個變更列表(請參見圖 1)。這個合併工具和身份對照技術都允許自動化和命令列的呼叫。

註釋: 模型 聯合就是一項可以改善目標模型的元素身份使其與源模型中相同的元素相匹配的技術。它利用精密的身份匹配器來產生在稍後的模型中可以匹配的關鍵元素,這樣以來這些元素 ID 就可以向前移動。這樣就有效地在這些模型之間建立了一個始祖關係,它們似乎都是直接從一個到另一個這樣演化而來的。這樣利用這篇文章中所描述的方法就可以使它們變得具有可比性。


圖 1. 兩個連線模型的比較會話
變更列在左邊,合併結果檢視在右邊

圖 2 顯示了在這些模型之間的視覺化合並過程中,當點選 Save deltas 按鈕時這些差量列表是如何儲存的。假設這個標識必須從一個視覺化會話中產生,並且由於要剖析這個檔案從而建立更多精緻的瀏覽工具十分困難,就會採用可替換機制和檔案格式。


圖 2. Delta 記錄檔案內容
螢幕輸出

執行一個 Ant 任務實現自動化

這種方法是由一個 Apache Ant 任務實現自動化的。Ant 任務可以從命令列開始以批量處理模式執行,這樣可以產生一個變更列表並將它們儲存到一個檔案中。此外,生成的變更列表可以以可導向模式儲存。Compare Merge 中的功能可以下載這樣的檔案到 Rational 軟體並用 Delta Annotation Viewer 來瀏覽它們,如圖 3所示(請參見資源,可學習更多的關於 deltas 的知識)。


圖 3. Delta 註釋瀏覽器
ModelDeltas 頁籤

建立一個 Eclipse Ant 專案

假設這樣的情景:

  • 一個 Java-to-UML 轉換必須執行從而產生 UML 模型。
  • 這個模型必須儲存,與一個主模型保持一致,那麼這兩個模型就必須相互比較。
  • 兩個模式之間的差異表稍後需要儲存進行評審。
  • 使這項工作在批量(headless 操作)模式中執行。

要滿足這些需求,您將建立一個您可以通過命令部署的 Ant 任務類。

  1. 首先,建立一個樣本 Eclipse 外掛,如圖 4 所示。(您可以在 com.acme.headless.ant_1.0.0.jar 找到帶有原始碼的完整的外掛)。

圖 4. 建立這個 headless 操作模式的 Ant 外掛
Package Explorer 檢視

  1. 將顯示在列表 1 中的依存關係新增到這個清單檔案中。

列表 1. 依存關係新增到這個清單檔案中
				
  Manifest-Version: 1.0
  Bundle-ManifestVersion: 2
  Bundle-Name: Ant Plug-in
  Bundle-SymbolicName: com.acme.headless.ant;singleton:=true 
  Bundle-Version: 1.0.0 
  Bundle-Activator: com.acme.headless.ant.Activator
  Bundle-Vendor: ACME
  Bundle-Localization: plugin
  Require-Bundle: org.eclipse.ui,
  org.eclipse.core.runtime,
  org.eclipse.ant.core,
  org.apache.ant,
  org.eclipse.gmf.runtime.emf.core.compatibility,
  com.ibm.xtools.transform.core,
  com.ibm.xtools.uml.core, 
  com.ibm.xtools.uml.msl,
  com.ibm.xtools.comparemerge.modelconverter,
  com.ibm.xtools.comparemerge.delta.annotation.ui,
  com.ibm.xtools.comparemerge.core
  Eclipse-LazyStart: true

  1. 建立一個如列表 2所示的 Differences Logger 類,並新增一些屬性到這個類。公共屬性將會被當作 Ant 任務引數使用。

列表 2. 建立一個附加屬性的 Differences Logger 類
				
package com.acme.headless.ant.task;

public class DifferencesLogger extends org.apache.tools.ant.Task {
// ant task parameter variables
// absolute path to transformation configuration (.tc) file
public String transformConfigPath; 
// absolute path to the master model to be compared to
public String masterModelPath; 
// absolute path to the auto-generated changes log (the file does not have pre-exist) 
public String deltaLogFileName;
// absolute path to a blank model template
public String blankModelPath; 

// private members
private String tempModelName = "HTBlankModel"; //$NON-NLS-1$
private URI tempModelURI = null;
}

  1. 現在建立這個任務execute()方法(請參見列表 3)。

列表 3. 建立 execute() 方法
				
/*
* Execute task 
* (non-Javadoc)
* @see org.apache.tools.ant.Task#execute()
*/
public void execute() throws BuildException {

try {
// load transformation configuration file
IFile file = 
ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(
new Path(transformConfigPath));
ITransformConfig config = TransformConfigUtil.loadConfiguration(file);

//prepare Java to UML transformation forward context by switching its target container 
to point to a temporary, empty model file 
ITransformContext forwardContext = createTarget(config);
//execute transformation
IStatus status = 
TransformController.getInstance().
execute(config, forwardContext, false, true, null);

System.out.println("Completed transform. execution, status = " + status.getMessage()); 

if (status.getCode() == IStatus.OK) {

// instantiate model alignment facade
ModelConverterFacade mc_facade = new ModelConverterFacade();

//verify that master copy does exist
File baseFile = new File(getMasterModelPath());
if (!baseFile.exists()) {
System.out.println("Invalid master copy path: " + getMasterModelPath()); 
System.out.println("Please correct the parameter and re-run the script"); 
return;
}

// obtain model file created by transformation. Verify it exits
File contributorFile = new File(getTemporaryModelURI().toFileString());
if (!contributorFile.exists()) {
System.out.println("Error during transformation: failed to create target file"); 
System.out.println("Verify that " + contributorFile.getParent() + " is not read-only”); 
return;
}

// align master and contributor files
if (!mc_facade.alignSingleModelFile(baseFile, contributorFile, null, contributorFile)) 
{
System.out.println("Error during model alignment"); 
System.out.println(contributorFile.getAbsolutePath() + " should exist!"); 
return;
}
// compare aligned models and save changes log
compareWithEachOther(baseFile, contributorFile);
} 
} catch (Exception e) {
e.printStackTrace();
System.out.println("Failed execution" + e.getLocalizedMessage()); 
}
}

  1. 在 com.acme.headless 外掛中建立一個 plugin.xml 檔案,並宣佈這個 Ant 任務(列表 4)。

列表 4. 建立一個 plugin.xml 檔案並宣告這個 Ant 任務
				





  1. 更新如列表 5所示的這個外掛的構建屬性。

列表 5. 更新這個外掛的構建屬性
				
bin.includes = META-INF/,\
delta_logger.jar,\
plugin.xml
source.delta_logger.jar = src/
output.delta_logger.jar = bin/

  1. 右鍵點選這個 plugin.xml 檔案,並通過選擇 PDE Tools > Create Ant Build File 來建立一個 Ant build.xml 檔案(請參見圖 5)。


圖 5. 建立 Ant 構建檔案
下拉選單顯示了所描述的選擇

  1. 右鍵點選這個 build.xml 檔案並選擇 Run As > Ant Build 。這樣將會在這個外掛根目錄中建立一個 diff_logger.jar 檔案。
  2. 最後,如圖 6 所描述的那樣,在 Project Explorer 中,選擇這個 com.acme.headless.ant 外掛並點選下拉選單上的 Export ,從而將它匯入 Rational 軟體外掛目錄中(C:\Program Files\IBM\SDP70\plugins, typically):作為一個可部署的外掛(com.acme.headless.ant_1.0.0.jar)。

圖 6. 匯入這個 com.acme.headless.ant 外掛
顯示外掛,然後匯出所選擇的

安裝執行環境

要闡述這個步驟,我們已經在附加的 Projects.zip 壓縮檔案中提供了三個案例(請參見 下載)。按照下列這些步驟來使用這三個專案:

  1. 使用現存的工作空間(C:\targets\my-workspace)。或者建立一個新的工作空間。
  2. 啟動您的 Rational 軟體來使用 C:\targets\my-workspace 。
  3. 將這些檔案從 Projects.zip 壓縮檔案中解壓出來,並將這三個專案 Import 到您的工作空間。
  4. 轉到 AntRunnerPlugin 專案 並右鍵點選這個 plugin.xml 檔案。然後選擇 PDE Tools > Create Ant Build File 。這樣將產生一個 build.xml 檔案。
  5. 開啟這個 build.xml 檔案並對它進行編輯,如圖 6所示的那樣來新增最後的目標。
    1. 第一個引數(transformConfigPath) 指向 Java-to-UML 轉換配置檔案。
    2. 這個masterModelPath引數指向您的基本 UML 模型的位置。這個模型將不會被這個任務改寫。
    3. 這個deltaLogFileName引數指向產生的變更日誌檔案的未來的位置(它先前並不一定存在,並不一定在這個工作空間)。
    4. 這個blankModelPath 引數指向這個任務所使用的一個空模型模版的位置,因為它僅僅被用來作為模版。這個模版可以是任何一個空模型,但是您可以利用它提供便利的案例。

列表 6. 編輯這個 build.xml 檔案從而新增最後的目標
				

< diff_logger
transformConfigPath='C:\targets\my-workspace\Java Project\J2UML.tc'
masterModelPath='C:\targets\my-workspace\Model Project\Blank Model.emx'
deltaLogFileName='C:\targets\my-workspace\Model Project\changes_log.xml'
blankModelPath='C:\targets\my-workspace\Model Project\template\EmptyModel.emx'
/>

      

  1. 更新這個預設的任務(Ant 構建檔案的第一行)為mytest 任務

註釋:
確保 C:\targets\my-workspace 是由您工作空間的真實位置所代替的。

  1. 儲存這個修改的 Ant 構建檔案。

執行環境現在已經安裝,這個任務可以在 Rational 軟體中,也可以在 headless 操作模式中執行。

  1. 要在 Rational 軟體中執行這個 Ant 任務,請選擇 build.xml 檔案,右鍵點選,然後選擇 Run As > Ant build
  2. 注意在 Model Project 中有一個叫做 changes_log.xml 的新檔案。可以通過選擇 Window > Show View > Other > Model Delta Annotation Viewer > Model deltas ,在這個 delta 日誌瀏覽器(圖 7)中複製這個檔案。

圖 7. 在 delta 註解瀏覽器中檢視變更。
在最上方的 build.xml 頁籤,在底部的 ModelDeltas 頁籤

  1. 簡單地將生成的這個檔案拖拽到這個瀏覽器上。

這個 EMF 層級 deltas (單個的變更), 顯示在葉節點,可以在 UML 層級很方便地歸到複核的 deltas 中。這些複合構件代表姿勢或者其它邏輯分類(比如一個拖拽-放下複合物件圖解,這將導致一個組位置變更,包裹-相關變更,比如變更到特定的包裹複合 delta,等等)。

在 headless 操作模式中執行這個任務

  1. 記住您的 Ant build.xml 檔案的絕對位置,並將這個 runant.bat 檔案從列表 7 複製到您的 Rational 軟體的根資料夾中(比如, C:\Program Files\IBM\SDP70)。

列表 7. runant.bat 檔案
				
setlocal
REM RUNANT_DIR=This directory (which may, or may not, be your current working directory)
set RUNANT_DIR=%~dp0

set debug=
if not '%1' == 'debug' goto studio
set debug=-Xdebug -Xnoagent -Djava.compiler=none ^
-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000

:studio
REM The root directory of your Studio installation
set STUDIO_DIR=C:\Program Files\IBM\SDP70
if not exist '%STUDIO_DIR%'\jdk\jre set STUDIO_DIR=%RUNANT_DIR%..\..\..
if not exist '%STUDIO_DIR%'\jdk\jre echo 
ERROR: incorrect STUDIO_DIR=%STUDIO_DIR%
if not exist '%STUDIO_DIR%'\jdk\jre goto done

:java
if not $%JAVA_DIR%$==$$ goto workspace
set JAVA_DIR=jdk\jre\bin
:workspace
if not $%WORKSPACE%$==$$ goto check
REM #######################################################
REM ##### you must edit the 'WORKSPACE' setting below #####
REM #######################################################
REM *********** The location of your workspace ************
set WORKSPACE=C:\targets\my-workspace
:check
REM ************* The location of your workspace *****************
if not exist '%WORKSPACE%' echo ERROR: 
incorrect workspace=%WORKSPACE%, edit this runAnt.bat and correct the WORKSPACE envar
if not exist '%WORKSPACE%' goto done

set LOCATIONS=-DSTUDIO.DIR=%STUDIO_DIR% -DSTUDIO.RUNANT=
%RUNANT_DIR% -DSTUDIO.WORKSPACE=%WORKSPACE%

:run
@echo on
'%JAVA_DIR%\java' -cp '%STUDIO_DIR%\startup.jar' 
%debug% org.eclipse.core.launcher.Main 
-debug -application org.eclipse.ant.core.antRunner -data 
'%WORKSPACE%' -file %WORKSPACE%\AntRunnerPlugin\build.xml

  1. 開啟並編輯這個檔案,從而將具體的路徑對映到您的環境中。這些都非常重要的路徑:
    • STUDIO_DIR: 您的 Studio 安裝的根目錄(例如, C:\Program Files\IBM\SDP70)
    • JAVA_DIR: 絕對或者相對批量檔案位置 Java Runtime Environment,或者 JRE(例如, jdk\jre\bin)
    • WORKSPACE: 您的 Rational 軟體工作空間的位置(通常是,C:\targets\my-workspace)
    • 批量檔案最新的命令列: 您的 build.xml 檔案位置與您的工作空間相互關聯(比如, AntRunnerPlugin\build.xml)
  2. 修改這個任務路徑,使其指向 build.xml 檔案位置,這個檔案是在 Step 4 中產生的。
  3. 執行從本地命令列到批量檔案位置的 antRun.bat 檔案。這個結果應該與 Step 6 中的一樣。

改編一個客戶的轉換

  1. 建立一個 Java-to-UML 轉換(或者採用一個現存的轉換)。
  2. 配置它並儲存到這個配置檔案。
  3. 修改這個在先前步驟中生成的 build.xml 檔案,使其指向您的配置檔案(請參見 transformConfigPath 引數)。
  4. 修改這個masterModelPath引數,使其指向您的主模型檔案(這個檔案將不會被改寫)。
  5. 修改這個deltaLogFileName引數使其指向 delta 日誌檔案的位置。
  6. 修改這個blankModelPath變數使其指向這個空白的(空的)模型模版(這個檔案將不會被改寫)。
  7. 在先前的例子中執行這個 Ant 任務。


 

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/14780914/viewspace-588973/,如需轉載,請註明出處,否則將追究法律責任。

相關文章