2011-04-18 139 views
1

我有兩個電動勢模型A和B,其中B只與A不同,因爲它有一個額外的子節點。使用emf比較代碼?

現在我想用EMF從碼相比較要做到:

1)閱讀模式A和B,創造C型是由A和B的合併模型基本上,這相當於A +額外從B.

節點

我已經看過:

http://dev.eclipse.org/viewcvs/viewvc.cgi/org.eclipse.emf/org.eclipse.emf.compare/examples/org.eclipse.emf.compare.examples.standalone/src/org/eclipse/emf/compare/examples/standalone/ExampleLauncher.java?view=co&root=Modeling_Project

但我不知道怎樣才能使用的代碼計算最終的合併模型:

DiffModel diff = CompareUtils.compare(model1, model2, Collections.<String, Object> emptyMap()); 
CompareUtils.merge(diff); 

顯示如何計算合併模型的任何示例?

我現在已經嘗試:

 private void bob() { 
     ResourceSet resourceSet = new ResourceSetImpl(); 
     Map extensionMap = (Map) resourceSet.getResourceFactoryRegistry() 
      .getExtensionToFactoryMap().put("xmi", new XMIResourceFactoryImpl()); 
     try { 

     Region region01 = StatemachineFactoryImpl.eINSTANCE.createRegion(); 
     addResourceToModel(resourceSet, region01, "st1.xmi"); 
     State state01 = StatemachineFactoryImpl.eINSTANCE.createState(); 
     state01.setName("aaaa"); 
     region01.getState().add(state01); 
     if (state01.eResource() == null) { 
     System.out.println("state01 NOT contained in resource!"); 
     return; 
     } 

     Region region02 = StatemachineFactoryImpl.eINSTANCE.createRegion(); 
     addResourceToModel(resourceSet, region02, "st2.xmi"); 
     State state02 = StatemachineFactoryImpl.eINSTANCE.createState(); 
     state02.setName("bbbb"); 
     region02.getState().add(state02); 
     if (state02.eResource() == null) { 
     System.out.println("state02 NOT contained in resource!"); 
     return; 
     } 

     final MatchModel match = MatchService.doMatch(region01, region02, 
      Collections.<String, Object> emptyMap()); 
     final DiffModel diff = DiffService.doDiff(match, false); 
     final List<DiffElement> differences = new ArrayList<DiffElement>(
      diff.getOwnedElements()); 
     MergeService.merge(differences, true); 

     // Prints the results 
     addResourceToModel(resourceSet, match, "match.xmi"); 
     addResourceToModel(resourceSet, diff, "diff.xmi"); 

     if (match.eResource() != null) 
     System.out.println(ModelUtils.serialize(match)); // Throws an 
                 // exception! 
     if (diff.eResource() != null) 
     System.out.println(ModelUtils.serialize(diff)); 

    } catch (final InterruptedException e) { 
     e.printStackTrace(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 

    } 

    private void addResourceToModel(ResourceSet resourceSet, EObject obj, 
     String path) { 
    Resource res = resourceSet.createResource(URI.createURI(path)); 
    res.getContents().add(obj); 
    } 

但行:

if (match.eResource() != null) 
    System.out.println(ModelUtils.serialize(match)); // Throws an 
                // exception! 

即使match.eResource()= NULL

我得到這個錯誤:

org.eclipse.emf.ecore.resource.Resource$IOWrappedException: The object '[email protected] (name: bbbb)' is not contained in a resource. 
    at org.eclipse.emf.ecore.xmi.impl.XMLSaveImpl.endSave(XMLSaveImpl.java:306) 
    at org.eclipse.emf.ecore.xmi.impl.XMLSaveImpl.save(XMLSaveImpl.java:235) 
    at org.eclipse.emf.ecore.xmi.impl.XMLResourceImpl.doSave(XMLResourceImpl.java:254) 
    at org.eclipse.emf.ecore.xmi.impl.XMLResourceImpl.save(XMLResourceImpl.java:229) 
    at org.eclipse.emf.compare.util.ModelUtils.serialize(ModelUtils.java:429) 

我已添加區域基於這裏的文檔的資源:

http://wiki.eclipse.org/index.php/EMF-FAQ#I_get_a_DanglingHREFException:e.g..2C.22org.eclipse.emf.ecore.xmi.DanglingHREFException:_The_object_.27com.example.Foo.402f5dda_.28.29.27_is_not_contained_in_a_resource..22_What_do_I_need_to_do.3F

和國家被包含在該區域,所以我不明白爲什麼我得到的異常...任何想法?

回答

2

撼訊,

你得到的堆棧跟蹤指「合併」的一個對象不包含到資源:合併時,我們複製引用的statemachine(它的名字是「對象bbbb'),那麼我們需要從複製的對象中引用這個狀態機...並且我們引用的狀態機(是否從您的其他模型複製或直接引用?您應該調試以查看此內容)本身不包含資源。

State state02 = StatemachineFactoryImpl.eINSTANCE.createState(); 
state02.setName("bbbb"); 
region02.getState().add(state02); 
if (state02.eResource() == null) { 
    System.out.println("state02 NOT contained in resource!"); 
    return; 
} 

這應該確保「bbbb」確實包含在資源中。

這一行後:

MergeService.merge(differences, true); 

你能嘗試檢查一次,如果 「state02.eResource()== NULL」?如果是,那就是你的問題。否則,你就必須確保這不會返回:

for (State state : region01.getState()) { 
    if (state.eResource() == null) { 
     System.err.println(state.getName() + " is not contained in a resource); 
     return; 
    } 
} 
2

這是怎麼回事?

Model1 targetModel = EcoreUtil.copy(model1); 
addResourceToModel(targetModel) // assign the copied model to a resource 
MatchModel match = MatchService.doMatch(targetModel, model2, 
        Collections.<String, Object> emptyMap()); 
DiffModel diff = DiffService.doDiff(match, false); 
EList<DiffElement> differences = diff.getDifferences(); 
for (DiffElement diffElement : differences) { 
    MergeService.merge(diffElement, true); 
} 
+0

查看我的最新版本的原始問題。 – u123 2011-04-18 20:28:47

0

您的例外:」 org.eclipse.emf.ecore.resource.Resource $ IOWrappedException:對象「statemachine.impl.StateImpl @ 11ce012(名稱:bbbb)'不包含在資源中。「。StateImpl @ 11ce012(名稱:bbbb)位於一個名爲st2.xmi的資源中,但匹配元素位於另一個名爲「match.xml」的資源中。這兩種資源是不同的,它們不相互引用。所以match元素不能引用StateImpl。爲了解決這個問題,所有元素(state01,state02,match,diff)必須保存在ONE資源中。該代碼是:

res.getContents().add(stat01); 
res.getContents().add(stat02); 
res.getContents().add(match); 
res.getContents().add(diff); 

順便說一句,條件 「state02.eResource() == null」 不是nessary。