2017-09-20 20 views
1

EMF 모델로 작업 중이며이 복사본을 만들어야합니다. 내 모델은 세 개의 메타 모델로 구성된 상호 연결된 인스턴스로 구성되며 그 중 하나는 Ecore 자체입니다. 여태까지는 그런대로 잘됐다.ECoreUtil.Copier를 사용하여 EGenericType 인스턴스 복사

그러나 이러한 모델 (일반적인 프로토콜에 따라 EcoreUtil.Copier.copyAll을 사용)을 복사 할 때 내 모델의 일부는 복사되지 않습니다. 구체적으로, Ecore 인스턴스에는 EGenericType의 인스턴스가 포함되어 있습니다 (참조 및 속성이 있으며 해당 인스턴스가 유형을 표시하기 위해 EGenericType 인스턴스로 자동 설정 됨). 복사 결과에는 모든 것이 포함되지만 이러한 경우는 EGenericType입니다.

EMF 소스 코드를 고음질로 검색해 보았지만 문제점을 파악할 수 없었습니다. 나는 EcoreUtil.Copier의 출처를 살펴본 후 실제로 복사 할 것인지 결정하기 위해 변경 가능하고 파생되지 않은지 여부를 각 구조적 특징을 확인합니다. 이 조건은 EGenericType에 대한 참조에 해당하므로 포함 참조로 복사해야합니다.

흥미롭게도, 의 결과는EGenericType의 복사 된 인스턴스가 개체 그래프의 모든 올바른 위치에 포함되어 있습니다. 그러나 복사기에 매핑되지 않으므로 EcoreUtil.Copier.copy을 호출하여 생성 된 것 같지 않지만 암묵적으로는 생성됩니다.

아이디어가 생성되고 복사기 맵에 표시 될 수있는 아이디어가 있습니까?

많은 감사,

스테

답변

1

확인, 그래서 디버거이 더 깊이 파고 내가 지금 무엇을 이해하고 생각했다가 일어나고 :

기본적으로

, ETypedElement (유형에 포함 된 내용이다 및 제네릭 유형)은 계약을 통해 다소 느슨합니다. eType이나 eGenericType도 파생물로 표시되지 않지만 상황에 따라 그 중 하나는 다른 하나에서 파생됩니다.

특히 eTypeETypedElement으로 설정하면 암시 적으로 새 eGenericType이 생성됩니다. 마찬가지로 eGenericType을 설정하면 암시 적으로 eType이이 제네릭 형식의 지우기로 설정됩니다.

불행히도 ETypedElement에 명시 적으로 설정된 eType이있는 경우이 동작은 EcoreUtil.Copier을 혼란스럽게합니다. 이 경우, 다음과 같은 상황이 발생합니다

  1. EcoreUtil.Copier.copyETypedElement의 새로운 인스턴스를 만든 다음 모든 기능을 복사를 시작합니다.

  2. eType 기능을 가져 오면 eType은 봉쇄 참조가 아니기 때문에 (명백한 이유로)이 시점에서이 기능을 복사하지 않습니다.

  3. 다음은 봉쇄 참조 인 eGenericType입니다. 그러나 먼저 수행 할 작업은 원래 ETypedElement에 설정되어 있는지 확인하는 것입니다.eGenericTypeeType의 경우이 검사 중 하나만 실제로 true을 반환하도록 사용자 지정되었습니다. 결과적으로 ETypedElement의 경우 isSetEType()true이고 isSetEGenericType()true을 반환합니다. 따라서 copyContainment()은 복사 할 내용이 없다고 결정하고 이동합니다. copy() 또는 copyAll() 반환, 어느 것도 eType이나 eGenericType가 새로 생성 된 개체에 대해 설정되어 있지 않은 시간으로

  4. . 이제 copyReferences()이라고 부릅니다.

  5. 이것은 결국 eType 참조를 복사하려고 시도합니다 (이것은 참조 용이 아닌 것으로 표시됨을 기억하십시오). isSetType()true을 반환하므로 copyReference()은 계속 입력 정보를 복사합니다. 복사 된 개체의 eType에 대한 설정자가 EGenericType의 새 인스턴스를 만들고, EcoreUtil.Copier이 표시되지 않습니다. 내가 원래 EGenericType 인스턴스와 복사지도에 표시하기 위해 복사본을 얻으려면

따라서, 나는 서브 클래스 EcoreUtil.Copier에 필요 copyReference() 또는 copyContainment()이 특별한 경우를 처리하기 위해 우선합니다.