Как программно создать дочерний экземпляр экземпляра модели в EMF

Я работаю над разработкой набора тестов для моделей EMF. У меня есть метамодель (файл .ecore (диаграмма классов)), созданная с помощью графического редактора.

Теперь я могу создавать динамические экземпляры программно, но в моей метамодели у меня есть композиция (ссылка на содержание), в которой я хочу создать дочерний экземпляр содержащегося класса (программно).

Пожалуйста, найдите приведенную ниже информацию для справки

Диаграмма классов:

метамодель

Тестовый пример 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();
    }         
  }
}

Пожалуйста, помогите мне программно создать новый дочерний экземпляр из экземпляра отдела.


person Manoj Keshavaprakash    schedule 11.10.2017    source источник
comment
Ваш код имеет странный формат. Это затрудняет чтение. Больше людей захотят посмотреть на вашу проблему, если код будет правильно отформатирован.   -  person Lii    schedule 20.12.2017


Ответы (1)


Вы добавляете объект к многозначной функции, сначала получая список, который является значением функции. Затем вы добавляете элемент в этот список.

Пример:

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;
    
person Lii    schedule 20.12.2017