2016-10-23 120 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

更新了我的答案 –