2016-10-23 3 views
1

Ich möchte EMF-Modelle mit Java-Code generieren. Ich möchte zum Beispiel ein neues Ecore-Modellierungsprojekt erstellen und ein einfaches Modell erstellen, wie es in vielen Tutorials zu sehen ist (z. B. die vogella tutorial). Aber ich möchte das nicht per Hand tun, mit der GUI. Ich möchte lernen, wie man ein Modell mit Java-Code unter Verwendung der EMF-Ecore-API erstellt.So generieren Sie EMF-Modelle mit Java-Code

Ich habe versucht, Tutorials zu diesem Thema zu finden. Aber zu meiner Enttäuschung konnte ich nicht viel über dieses Thema finden. Das einzige, was ich finden konnte, war etwas code snippets to load and modify existing models by code. Aber nichts über das Erstellen neuer Modelle. Und nur durch die API zu schauen hat mir nicht geholfen.

Gibt es Quellen zu diesem Thema? Und wenn nicht, wie kann ich EMF-Modelle mit Java-Code erstellen?

Antwort

2

IBM hat ein Thema über dynamische EMF.

Aber es ist ziemlich einfach, wenn Sie mit der Art, wie die Erstellung in EMF funktioniert, vertraut sind. Jedes EPackage hat seine eigenen EFactory und EPackage Instanzen, die die Erstellung (Factory) übernehmen oder Informationen über das Metamodell selbst (EPackage) speichern.

Ecore hat seine eigene EPackage und EFactory so ist es absolut möglich, neue Meta-Modelle on the fly wie diese zu erstellen:

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

Jetzt haben Sie Ihre eigene EPackage mit eine neue EClass, die eine EAttribute Name des Typs EString

hat Jetzt ist es auch möglich, Ihre neue EPackage zu einer .ecore Datei wie folgt zu speichern:

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

und umgekehrt, wenn Sie eine vorhandene ecore EPackage laden mögen:

/* 
    * 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 hat von Natürlich ein eigenes Metamodell. In der Docs finden Sie einen tollen Überblick über die ecore Architektur.

Also, wenn Sie dynamische EMF verwenden möchten, müssen Sie dies verstehen. Wie ich Ihnen gezeigt habe, ist es sehr einfach, eine EPackage dynamisch zu erstellen, aber Sie müssen wissen, wie Sie die grundlegenden Attribute des ecore-Modells (EClass, EAttributes, EReferences, EType, containment, supertypes ...) festlegen. Sobald Sie die Architektur verstanden haben, ist es ziemlich einfach. Sehen Sie sich das UML-Diagramm unten auf der Seite an.

ich den Code auch über aktualisierte Ihnen zu zeigen, wie sich die Beziehungen zwischen Eclasses

+0

Danke für Ihre Hilfe zu initialisieren, aber ich habe noch eine Frage: Wie würden Sie eine Beziehung zwischen zwei Klassen erstellen? Wie eine normale Referenz oder eine SuperType-Beziehung? – ConveniencePatterns

+1

Meine Antwort wurde aktualisiert –