結合 EMF(模型生成)與 GEF(圖形編輯框架)進行圖形化建模時,需在建立連線(關聯關係)前驗證其合法性。傳統方式依賴靜態 Schema 驗證(保存時才檢查),使用者體驗差。本文提出基於 EMF 生成代碼特徵的動態驗證機制,於拖曳建立連線即時判斷有效性,並給出完整真值表與實作步驟。
EditPart 為 Controller,Draw2D 繪製 View,模型變更自動同步視圖。Command 執行 → 模型關聯更新 → 視圖刷新 → 保存為 XMI。假設模型 A 與 B1/B2/B3 關聯:
| 關聯類型 | EMF 生成方法特徵 |
|---|---|
| 一對一 | void setB1(B1) / B1 getB1() |
| 一對多 | EList getB2() |
| 多對多 | 雙向 EList |
Schema 定義複雜類型 A 包含元素 B1(maxOccurs=1)、B2(maxOccurs=unbounded)、sourceConn、targetConn。B3 不在 A 定義內,故 A-B3 連線非法。
| A 包含 B | 已存在連線 | B 出現次數限制 | 允許建立 |
|---|---|---|---|
| 否 | - | - | 否 |
| 是 | 是 | - | 否 |
| 是 | 否 | 最多 1 次 | 是 |
| 是 | 否 | 可多次 | 是 |
ConnectionCreateCommand 繼承 GEF Command,實作 validateConnection()。ATypeImpl, BTypeImpl)。ATypeImpl 及父類方法,尋找 setB(B) 或 getB()。ATypeImpl.getSourceConn() 遍歷連線集合,比對目標端類別名。setB(B) 則唯一;若有 EList getB() 則可多重。validateConnection() 回傳值。execute() 中若驗證通過,則建立連線並雙向加入 sourceConn/targetConn 集合;否則不執行。boolean validateConnection() {
// 1. 反射檢查包含關係
boolean contains = hasSetterOrGetter(sourceType, targetTypeSimpleName);
// 2. 檢查既有連線
boolean exists = false;
if (contains) {
EList conns = (EList) invokeGetter(sourceInstance, "getSourceConn");
for (Object c : conns) {
if (c.getClass().getSimpleName().equals(targetTypeSimpleName)) {
exists = true; break;
}
}
}
// 3. 檢查多重性
boolean multi = hasEListGetter(sourceType, targetTypeSimpleName);
// 4. 真值表判斷
return contains && !exists && (multi || !hasSetter(sourceType, targetTypeSimpleName));
}
此機制嚴重依賴 EMF 生成代碼的固定模式(介面/實作命名、Getter/Setter 慣例),若模型代碼生成方式變更(如使用其他框架),驗證邏輯需相應調整。通用化連線驗證框架仍有待進一步研究。