2016-10-23 4 views
1

Я хочу генерировать модели EMF с кодом Java. Например, я хочу создать новый проект моделирования Ecore и построить простую модель, как показано во многих учебниках (например, как vogella tutorial). Но я не хочу этого делать вручную, используя графический интерфейс. Я хочу узнать, как создать модель с кодом Java, используя EMF-Ecore-API.Как создать модели EMF с кодом Java

Я попытался найти учебники по этой теме. Но, к моему разочарованию, я не мог много узнать об этой теме. Единственное, что я мог найти, это code snippets to load and modify existing models by code. Но ничего о создании новых моделей. И просто просмотр API не помог мне.

Есть ли источники на эту тему? А если нет, как я могу создать модели EMF с помощью java-кода?

ответ

2

IBM есть тема о динамической ЭМП.

Но это довольно прямолинейно, если вы знакомы с тем, как работает создание эдс. Каждый EPackage имеет свои собственные EFactory и EPackage экземпляры, которые обрабатывают создание (фабрику) или хранят информацию о самой метамодели (epackage).

Ecore имеет свой собственный EPackage и EFactory так что вполне возможно создать новые мета-модели на лету, как это:

/*Use the Ecore factory*/ 
    EcoreFactory ecoreFactory = EcoreFactory.eINSTANCE; 
    /*Create your EPackage*/ 
    EPackage myPackage = ecoreFactory.createEPackage(); 
    /*set EPackage properties*/ 
    myPackage.setName("myTest"); 
    myPackage.setNsPrefix("myTest"); 
    myPackage.setNsURI("http://com.myTest"); 

    /*Create your first EClass*/ 
    EClass myFirstEClass = ecoreFactory.createEClass(); 
    myFirstEClass.setName("myClass"); 
    /*Add to your EPackage's EClassifiers*/ 
    /*EClasses and EDatatypes implement both EClassifiers*/ 
    myPackage.getEClassifiers().add(myFirstEClass); 

    /*Create your first EAtttribute*/ 
    EAttribute myFirstEAtt = ecoreFactory.createEAttribute(); 
    myFirstEAtt.setName("name"); 
    /*Use the EcorePackage Datatypes -> here EString*/ 
    myFirstEAtt.setEType(EcorePackage.eINSTANCE.getEString()); 
    /*use EStructuralFeatures to add your EAtt*/ 
    /*EReferences and EAttributes are both EStructuralfeatures*/ 
    myFirstEClass.getEStructuralFeatures().add(myFirstEAtt); 

Update:

/*Create your second EClass*/ 
    EClass mySecondEClass = ecoreFactory.createEClass(); 
    mySecondEClass.setName("mySecondClass"); 
    myPackage.getEClassifiers().add(mySecondEClass); 

    /*now, the firstClass should hold instances of secondClass*/ 
    /*1. create EReference (Ereferences unlike EAttributes define relationships between EClasses)*/ 
    EReference secondClassesRef = ecoreFactory.createEReference(); 
    secondClassesRef.setName("secondClasses"); 
    /*set containment true -> every EObject must have a Container*/ 
    secondClassesRef.setContainment(true); 
    /*set Type to your EClass*/ 
    secondClassesRef.setEType(mySecondEClass); 
    /*set upperbound -> now the reference is an EList*/ 
    secondClassesRef.setUpperBound(ETypedElement.UNBOUNDED_MULTIPLICITY); 

    /*finally add ERef to EClass*/ 
    myFirstEClass.getEStructuralFeatures().add(secondClassesRef); 

    /*and for example supertypes*/ 
    myFirstEClass.getESuperTypes().add(mySecondEClass); 

Теперь у вас есть свой собственный EPackage с новый EClass, который имеет EAttribute имя типа EString

Теперь это возможно, чтобы сохранить новый EPackage к .ecore файл, например так:

/* 
    * Save your EPackage to file ecore file: 
    */ 

    /*Initialize your EPackage*/ 
    myPackage.eClass(); 
    Resource.Factory.Registry reg = Resource.Factory.Registry.INSTANCE; 
    Map<String, Object> m = reg.getExtensionToFactoryMap(); 
    /*add default .ecore extension for ecore file*/ 
    m.put(EcorePackage.eNAME, new XMIResourceFactoryImpl()); 

    // Obtain a new resource set 
    ResourceSet resSet = new ResourceSetImpl(); 
    // create a resource 
    Resource resource = null; 
    try { 
     resource = resSet.createResource(URI.createFileURI("/Your/Path/To/Directory/myTest.ecore")); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
    /*add your EPackage as root, everything is hierarchical included in this first node*/ 
    resource.getContents().add(myPackage); 

    // now save the content. 
    try { 
     resource.save(Collections.EMPTY_MAP); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 

и наоборот, если вы хотите, чтобы загрузить существующий Ecore EPackage:

/* 
    * load existing EPackage 
    */ 
    EcorePackage.eINSTANCE.eClass(); 
    /*Initialize your EPackage*/ 
    final Resource.Factory.Registry reg = Resource.Factory.Registry.INSTANCE; 
    final Map<String, Object> m = reg.getExtensionToFactoryMap(); 
    m.put(EcorePackage.eNAME, new XMIResourceFactoryImpl()); 

    final ResourceSet resSet = new ResourceSetImpl(); 
    Resource resource = null; 
    try { 
     resource = resSet.getResource(URI.createFileURI("/Your/Path/To/Directory/myTest.ecore"), true); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
    /*load root and cast to EPackage*/ 
    final EPackage root = (EPackage) resource.getContents().get(0); 

Update: Ecore имеет от конечно, свою собственную метамодель. В Docs вы найдете отличный обзор архитектуры ecore.

Итак, если вы хотите использовать динамическую ЭМП, вам нужно это понять. Как я показал вам, очень просто создать EPackage динамически, но вам нужно знать, как установить базовые атрибуты модели ecore (EClass, EAttributes, EReferences, EType, сдерживание, супертипы ...). Как только вы поняли архитектуру, это довольно легко. Посмотрите на UML-диаграмму внизу страницы.

Я также обновил код выше, чтобы показать вам, как инициализировать отношения между EClasses

+0

Спасибо за вашу помощь, но у меня есть еще один вопрос: Как бы вы создать связь между двумя классами? Как нормальное отношение Reference или SuperType? – ConveniencePatterns

+1

Обновлен мой ответ –

Смежные вопросы