如何以编程方式在EMF中创建模型实例的子实例

时间:2017-10-11 16:36:37

标签: merge model eclipse-emf emf eclipse-emf-ecore

我正在开发EMF模型的测试套件。我有一个使用图形编辑器创建的元模型(.ecore文件(类图))。

现在我能够以编程方式创建动态实例,但在我的元模型中,我有一个组合(包含引用),其中我想创建包含类的子实例(以编程方式)。

请查看以下信息以供参考

类图:

metamodel

JUnit测试用例:

public class DynamicTest extends TestCase
{
    public void testCreateModel() throws IOException {
    ResourceSet rs = new ResourceSetImpl();
    rs.getResourceFactoryRegistry().getExtensionToFactoryMap().put("ecore", 
    new XMIResourceFactoryImpl());
    Resource res = rs.createResource( URI.createFileURI( 
    "C:/Users/Manoj/Documents/FreshStart/Company/model/company.ecore" ));
    res.load(null);
    EPackage metapackage = (EPackage)res.getContents().get(0);
    System.out.println("meta Package "+metapackage.getName());
    EFactory employeeFactoryInstance = metapackage.getEFactoryInstance();
    EClass employeeClass = (EClass)metapackage.getEClassifier("Employee");
    EObject employeeObject = employeeFactoryInstance.create(employeeClass);
    EAttribute employeeName = employeeClass.getEAllAttributes().get(0);
    EAttribute employeeManager = employeeClass.getEAllAttributes().get(1);
    employeeObject.eSet(employeeName, "Manoj");
    employeeObject.eSet(employeeManager, "Albert");
    String empName = (String)employeeObject.eGet(employeeName);
    String empManager = (String)employeeObject.eGet(employeeManager);
    ResourceSet resourseSet = new ResourceSetImpl();
    resourseSet.getPackageRegistry().put(metapackage.getNsURI(), 
    metapackage); 

    ResourseSet.getResourceFactoryRegistry().getExtensionToFactoryMap().put
    ("*", new XMIResourceFactoryImpl());
    Resource resource = 
    ResourseSet.createResource(URI.createURI("./model/Employee.xmi"));
    resource.getContents().add(employeeObject);
    Map options = new HashMap();
    options.put(XMIResource.OPTION_SCHEMA_LOCATION, Boolean.TRUE);
    try 
    {
        resource.save(options);
    } catch (IOException e) {
        // TODO: handle exception
        e.printStackTrace();
    }
    EPackage metapackage1 = (EPackage)res.getContents().get(0);
    EFactory departmentFactoryInstance = metapackage1.getEFactoryInstance();
    EClass departmentClass = 
    (EClass)metapackage1.getEClassifier("Department");
    EObject departmentObject = 
    departmentFactoryInstance.create(departmentClass);
    EAttribute departmentName = departmentClass.getEAllAttributes().get(0);
    EAttribute departmentNumber = 
    departmentClass.getEAllAttributes().get(1);
    EObject depRef = employeeClass.eContainmentFeature().eContents().get(0);
    departmentObject.eSet(departmentName, "SMS");
    departmentObject.eSet(departmentNumber, 101);
    String depName = (String)departmentObject.eGet(departmentName);
    Integer depNumber = (Integer)departmentObject.eGet(departmentNumber);
    ResourceSet resSet = new ResourceSetImpl();
    resSet.getPackageRegistry().put(metapackage1.getNsURI(), metapackage1);
    resSet.getResourceFactoryRegistry().getExtensionToFactoryMap().put("*", 
    new XMIResourceFactoryImpl());
    Resource res1 = 
    resSet.createResource(URI.createURI("./model/Department.xmi"));  
    res1.getContents().add(departmentObject);
    Map options1 = new HashMap();
    options1.put(XMIResource.OPTION_SCHEMA_LOCATION, Boolean.TRUE);
    try 
    {
        res1.save(options1);
    } catch (IOException e) {
        // TODO: handle exception
        e.printStackTrace();
    }         
  }
}

请帮助我以编程方式从部门实例创建新的子实例。

1 个答案:

答案 0 :(得分:2)

首先获取作为特征值的列表,将对象添加到多值特征。然后在该列表中添加一个元素。

示例:

EStructuralFeature employeeFeature = departmentClass.getEStructuralFeature("employee");
@SuppressWarnings("unchecked")  // Safe cast as long as only Employees are added
List<EObject> employees = (List<EObject>) departmentObject.eGet(employeeFeature);
employees.add(employeeObject);

关于您的代码的一些注意事项:

  • employeeObject如果包含在departmentObject中,则不应添加到资源中。只应将未包含在任何其他对象中的顶级对象添加到资源中。
  • 最好使用EClass.getEStructuralFeature来获得正确的功能。这样,如果功能的顺序发生变化,您的代码就不会中断。
  • 从反射模型对象中获取EStructuralFeature会更好,如下所示:

    EStructuralFeature employeeFeature = PackageClass.Literals.EMPLOYEE_FEATURE;