Reputation: 17
I am working on developing a test suite for EMF models. I have a metamodel (.ecore file (class diagram)) created using the graphical editor.
Now I am able to create the dynamic instances programmatically, but in my metamodel I have a composition (Containment reference) wherein I want to create child instance of the contained class (programmatically).
Please find the below information for reference
Class diagram:
JUnit testcase:
public class DynamicTest extends TestCase
{
public void testCreateModel() throws IOException {
ResourceSet rs = new ResourceSetImpl();
rs.getResourceFactoryRegistry().getExtensionToFactoryMap().put("ecore",
new XMIResourceFactoryImpl());
Resource res = rs.createResource( URI.createFileURI(
"C:/Users/Manoj/Documents/FreshStart/Company/model/company.ecore" ));
res.load(null);
EPackage metapackage = (EPackage)res.getContents().get(0);
System.out.println("meta Package "+metapackage.getName());
EFactory employeeFactoryInstance = metapackage.getEFactoryInstance();
EClass employeeClass = (EClass)metapackage.getEClassifier("Employee");
EObject employeeObject = employeeFactoryInstance.create(employeeClass);
EAttribute employeeName = employeeClass.getEAllAttributes().get(0);
EAttribute employeeManager = employeeClass.getEAllAttributes().get(1);
employeeObject.eSet(employeeName, "Manoj");
employeeObject.eSet(employeeManager, "Albert");
String empName = (String)employeeObject.eGet(employeeName);
String empManager = (String)employeeObject.eGet(employeeManager);
ResourceSet resourseSet = new ResourceSetImpl();
resourseSet.getPackageRegistry().put(metapackage.getNsURI(),
metapackage);
ResourseSet.getResourceFactoryRegistry().getExtensionToFactoryMap().put
("*", new XMIResourceFactoryImpl());
Resource resource =
ResourseSet.createResource(URI.createURI("./model/Employee.xmi"));
resource.getContents().add(employeeObject);
Map options = new HashMap();
options.put(XMIResource.OPTION_SCHEMA_LOCATION, Boolean.TRUE);
try
{
resource.save(options);
} catch (IOException e) {
// TODO: handle exception
e.printStackTrace();
}
EPackage metapackage1 = (EPackage)res.getContents().get(0);
EFactory departmentFactoryInstance = metapackage1.getEFactoryInstance();
EClass departmentClass =
(EClass)metapackage1.getEClassifier("Department");
EObject departmentObject =
departmentFactoryInstance.create(departmentClass);
EAttribute departmentName = departmentClass.getEAllAttributes().get(0);
EAttribute departmentNumber =
departmentClass.getEAllAttributes().get(1);
EObject depRef = employeeClass.eContainmentFeature().eContents().get(0);
departmentObject.eSet(departmentName, "SMS");
departmentObject.eSet(departmentNumber, 101);
String depName = (String)departmentObject.eGet(departmentName);
Integer depNumber = (Integer)departmentObject.eGet(departmentNumber);
ResourceSet resSet = new ResourceSetImpl();
resSet.getPackageRegistry().put(metapackage1.getNsURI(), metapackage1);
resSet.getResourceFactoryRegistry().getExtensionToFactoryMap().put("*",
new XMIResourceFactoryImpl());
Resource res1 =
resSet.createResource(URI.createURI("./model/Department.xmi"));
res1.getContents().add(departmentObject);
Map options1 = new HashMap();
options1.put(XMIResource.OPTION_SCHEMA_LOCATION, Boolean.TRUE);
try
{
res1.save(options1);
} catch (IOException e) {
// TODO: handle exception
e.printStackTrace();
}
}
}
Kindly help to me to create new child instance from department instance programmatically.
Upvotes: 0
Views: 1017
Reputation: 12122
You add an object to a multi-valued feature by first getting the list that is the feature value. Then you add an element to that list.
Example:
EStructuralFeature employeeFeature = departmentClass.getEStructuralFeature("employee");
@SuppressWarnings("unchecked") // Safe cast as long as only Employees are added
List<EObject> employees = (List<EObject>) departmentObject.eGet(employeeFeature);
employees.add(employeeObject);
A few notes about your code:
employeeObject
should not be added to a resource if it is contained in departmentObject
. Only the top-level objects, which are not contained by any other objects, should be added to a resource.EClass.getEStructuralFeature
to get the right feature. In that way your code does not break if the order of the features is changed.It's even better to get the EStructuralFeature
from the reflection model objects, like this:
EStructuralFeature employeeFeature = PackageClass.Literals.EMPLOYEE_FEATURE;
Upvotes: 3