如何使用Java代码生成EMF模型



我想用Java代码生成EMF模型。例如,我想创建一个新的Ecore建模项目,并构建一个简单的模型,就像在许多教程中看到的那样(例如,像vogella教程)。但我不想用GUI手工做。我想学习如何使用EMF-Ecore-API用Java代码创建模型。

我试着找到关于这个主题的教程。但令我失望的是,我找不到关于这个话题的太多信息。我唯一能找到的是一些代码片段,通过代码加载和修改现有的模型。但没有提到创造新模式。而仅仅浏览API并不能帮助我。

有关于这个话题的资料吗?如果没有,我如何通过java代码创建EMF模型?

IBM有一个关于动态EMF的主题。

但是如果你熟悉emf中创建的工作方式,它是非常直接的。每个EPackage都有自己的EFactoryEPackage实例,它们处理创建(工厂)或存储有关元模型本身(包)的信息。

Ecore有自己的EPackageEFactory,所以完全可以像这样创建新的元模型:

    /*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);
更新:

    /*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

现在也可以将您的新eppackage保存到.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包:

    /*
     * 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);

更新:Ecore当然有自己的元模型。在文档中,你可以找到一个很好的ecore架构概述。

所以如果你想使用动态EMF,你需要理解这一点。正如我所展示的,动态创建EPackage非常简单,但是您需要知道如何设置核心模型的基本属性(EClass、EAttributes、EReferences、EType、containment、超类型……)。一旦理解了体系结构,就非常容易了。请看一下页面底部的uml图。

我还更新了上面的代码,以向您展示如何初始化类之间的关系

相关内容

  • 没有找到相关文章

最新更新