1

2つのemfモデルAとBがありますが、Bには追加の子ノードがあるためAとは異なります。

ここで、コードからのemfcompareを使用して次のことを行います。

1)モデルAとBを読み取り、AとBのマージモデルであるモデルCを作成します。基本的にこれは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 'statemachine.impl.StateImpl@11ce012 (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:eg.2C .22org.eclipse.emf.ecore.xmi.DanglingHREFException:_The_object_.27com.example.Foo.402f5dda_.28.29.27_is_not_contained_ .22_What_do_I_need_to_do.3F

州は地域に含まれているので、なぜ例外が発生するのかわかりません...何かアイデアはありますか?

4

3 に答える 3

2

トゥル、

取得したスタックトレースは、「マージされた」オブジェクトの1つがリソースに含まれていないことを意味します。マージするときに、ステートマシン(名前は「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;
    }
}
于 2011-04-19T08:42:25.230 に答える
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);
}
于 2011-04-18T15:02:11.773 に答える
0

例外: "org.eclipse.emf.ecore.resource.Resource $ IOWrappedException:オブジェクト'statemachine.impl.StateImpl@11ce012(name:bbbb)'はリソースに含まれていません。" 。StateImpl @ 11ce012(名前:bbbb)はst2.xmiという名前の1つのリソースにありますが、一致要素は「match.xml」という名前の別のリソースにあります。2つのリソースは異なり、相互に参照しません。したがって、match要素はStateImplを参照できません。この問題を解決するには、すべての要素(state01、state02、match、diff)を1つのリソースに保存する必要があります。コードは次のとおりです。

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

ちなみに、条件「state02.eResource() == null」は必須ではありません。

于 2017-06-27T10:34:18.327 に答える