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
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
Meine Antwort wurde aktualisiert –