2016-10-23 65 views
1

我想使用Java代碼生成EMF模型。例如,我想創建一個新的Ecore建模項目,並構建一個簡單的模型,就像在許多教程中看到的一樣(即像vogella tutorial一樣)。但我不想用手操作,使用GUI。我想了解如何使用EMF-Ecore-API來創建帶有Java代碼的模型。如何使用Java代碼生成EMF模型

我試圖找到關於這個主題的教程。但令我失望的是,我無法找到這個話題。我能找到的唯一東西是一些code snippets to load and modify existing models by code。但沒有關於創建新模型。而通過API瀏覽並沒有幫助我。

有沒有在這個題目的來源?如果不是,我怎樣才能通過java代碼創建EMF模型?

回答

2

IBM有一個關於動態EMF的話題。

但是,如果您熟悉emf中的創作方式,這非常簡單。每個EPackage都有自己的EFactoryEPackage實例,它們處理創建(工廠)或存儲關於元模型本身(epackage)的信息。

的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

現在,它也可以到新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); 

更新: Ecore的有當然是自己的元模型。在Docs中,您可以找到ecore體系結構的完美概述。

所以,如果你想使用動態EMF你需要了解這一點。正如我向您展示的那樣,動態創建EPackage非常簡單,但您需要知道如何設置ecore模型(EClass,EAttributes,EReferences,EType,包含,超類型等)的基本屬性。一旦你瞭解了這個架構,那麼它很容易。查看頁面底部的UML圖。

我也更新上面的代碼向你展示如何初始化的eclass之間的關係

+0

感謝您的幫助,但我有一個問題:你如何創建兩個類之間的關係?就像一個普通的引用或超類型的關係? – ConveniencePatterns

+1

更新了我的答案 –