Notice: This Wiki is now read only and edits are no longer possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.
CDO/Preparing EMF Models
Create an Ecore Model
There's not much to say about this step. The .ecore file for CDO models is the same as for pure EMF models. The only differences are in the Java code that the EMF generator will produce, as you will see in the next step.
The model1
example model in the usual Ecore model editor looks like follows:
The XML form of this Ecore model is:
<?xml version="1.0" encoding="UTF-8"?> <ecore:EPackage xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="model1" nsURI="http://www.eclipse.org/emf/CDO/tests/model1/1.0.0" nsPrefix="model1"> <eClassifiers xsi:type="ecore:EClass" name="Address"> <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> <eStructuralFeatures xsi:type="ecore:EAttribute" name="street" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> <eStructuralFeatures xsi:type="ecore:EAttribute" name="city" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> </eClassifiers> <eClassifiers xsi:type="ecore:EClass" name="Company" eSuperTypes="#//Address"> <eStructuralFeatures xsi:type="ecore:EReference" name="categories" upperBound="-1" eType="#//Category" containment="true"/> <eStructuralFeatures xsi:type="ecore:EReference" name="suppliers" upperBound="-1" eType="#//Supplier" containment="true"/> <eStructuralFeatures xsi:type="ecore:EReference" name="customers" upperBound="-1" eType="#//Customer" containment="true"/> <eStructuralFeatures xsi:type="ecore:EReference" name="purchaseOrders" upperBound="-1" eType="#//PurchaseOrder" containment="true"/> <eStructuralFeatures xsi:type="ecore:EReference" name="salesOrders" upperBound="-1" eType="#//SalesOrder" containment="true"/> </eClassifiers> <eClassifiers xsi:type="ecore:EClass" name="Supplier" eSuperTypes="#//Address"> <eStructuralFeatures xsi:type="ecore:EReference" name="purchaseOrders" upperBound="-1" eType="#//PurchaseOrder" eOpposite="#//PurchaseOrder/supplier"/> </eClassifiers> <eClassifiers xsi:type="ecore:EClass" name="Customer" eSuperTypes="#//Address"> <eStructuralFeatures xsi:type="ecore:EReference" name="salesOrders" unique="false" upperBound="-1" eType="#//SalesOrder" eOpposite="#//SalesOrder/customer"/> </eClassifiers> <eClassifiers xsi:type="ecore:EClass" name="Order"> <eStructuralFeatures xsi:type="ecore:EReference" name="orderDetails" upperBound="-1" eType="#//OrderDetail" containment="true" eOpposite="#//OrderDetail/order"/> </eClassifiers> <eClassifiers xsi:type="ecore:EClass" name="OrderDetail"> <eStructuralFeatures xsi:type="ecore:EReference" name="order" lowerBound="1" eType="#//Order" eOpposite="#//Order/orderDetails"/> <eStructuralFeatures xsi:type="ecore:EReference" name="product" eType="#//Product" eOpposite="#//Product/orderDetails"/> <eStructuralFeatures xsi:type="ecore:EAttribute" name="price" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloat"/> </eClassifiers> <eClassifiers xsi:type="ecore:EClass" name="PurchaseOrder" eSuperTypes="#//Order"> <eStructuralFeatures xsi:type="ecore:EAttribute" name="date" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EDate"/> <eStructuralFeatures xsi:type="ecore:EReference" name="supplier" lowerBound="1" eType="#//Supplier" eOpposite="#//Supplier/purchaseOrders"/> </eClassifiers> <eClassifiers xsi:type="ecore:EClass" name="SalesOrder" eSuperTypes="#//Order"> <eStructuralFeatures xsi:type="ecore:EAttribute" name="id" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EInt"/> <eStructuralFeatures xsi:type="ecore:EReference" name="customer" lowerBound="1" eType="#//Customer" eOpposite="#//Customer/salesOrders"/> </eClassifiers> <eClassifiers xsi:type="ecore:EClass" name="Category"> <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> <eStructuralFeatures xsi:type="ecore:EReference" name="categories" upperBound="-1" eType="#//Category" containment="true"/> <eStructuralFeatures xsi:type="ecore:EReference" name="products" upperBound="-1" eType="#//Product" containment="true"/> </eClassifiers> <eClassifiers xsi:type="ecore:EClass" name="Product"> <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> <eStructuralFeatures xsi:type="ecore:EReference" name="orderDetails" upperBound="-1" eType="#//OrderDetail" eOpposite="#//OrderDetail/product"/> </eClassifiers> </ecore:EPackage>
Create the GenModel
The EMF generator model for your Ecore model is much like a usual Genodel except for three differences:
- The Feature Delegation property must be set to
Reflective
- The Root Extends Class property must be set to
org.eclipse.emf.internal.cdo.CDOObjectImpl
- The Root Extends Interface property can be set to
org.eclipse.emf.cdo.CDOObject
The XML form of this generator model is:
<?xml version="1.0" encoding="UTF-8"?> <genmodel:GenModel xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" xmlns:genmodel="http://www.eclipse.org/emf/2002/GenModel" modelDirectory="/org.eclipse.emf.cdo.tests.model1/src" modelPluginID="org.eclipse.emf.cdo.tests.model1" modelName="Model1" rootExtendsInterface="org.eclipse.emf.cdo.CDOObject" rootExtendsClass="org.eclipse.emf.internal.cdo.CDOObjectImpl" reflectiveDelegation="true" testsDirectory="" importerID="org.eclipse.emf.importer.ecore" featureDelegation="Reflective" complianceLevel="5.0"> <foreignModel>model1.ecore</foreignModel> <genPackages prefix="Model1" basePackage="org.eclipse.emf.cdo.tests" disposableProviderFactory="true" ecorePackage="model1.ecore#/"> <genClasses ecoreClass="model1.ecore#//Supplier"> <genFeatures createChild="false" ecoreFeature="ecore:EAttribute model1.ecore#//Supplier/name"/> </genClasses> <genClasses ecoreClass="model1.ecore#//PurchaseOrder"> <genFeatures createChild="false" ecoreFeature="ecore:EAttribute model1.ecore#//PurchaseOrder/date"/> <genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference model1.ecore#//PurchaseOrder/supplier"/> </genClasses> <genClasses ecoreClass="model1.ecore#//OrderDetail"> <genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference model1.ecore#//OrderDetail/product"/> <genFeatures createChild="false" ecoreFeature="ecore:EAttribute model1.ecore#//OrderDetail/price"/> </genClasses> <genClasses ecoreClass="model1.ecore#//Product"> <genFeatures createChild="false" ecoreFeature="ecore:EAttribute model1.ecore#//Product/name"/> <genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference model1.ecore#//Product/orderDetails"/> </genClasses> <genClasses ecoreClass="model1.ecore#//Category"> <genFeatures createChild="false" ecoreFeature="ecore:EAttribute model1.ecore#//Category/name"/> <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference model1.ecore#//Category/categories"/> <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference model1.ecore#//Category/products"/> </genClasses> <genClasses ecoreClass="model1.ecore#//Company"> <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference model1.ecore#//Company/categories"/> <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference model1.ecore#//Company/suppliers"/> <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference model1.ecore#//Company/purchaseOrders"/> <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference model1.ecore#//Company/customers"/> <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference model1.ecore#//Company/salesOrders"/> </genClasses> <genClasses ecoreClass="model1.ecore#//Customer"> <genFeatures createChild="false" ecoreFeature="ecore:EAttribute model1.ecore#//Customer/name"/> <genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference model1.ecore#//Customer/salesOrders"/> </genClasses> <genClasses ecoreClass="model1.ecore#//SalesOrder"> <genFeatures createChild="false" ecoreFeature="ecore:EAttribute model1.ecore#//SalesOrder/id"/> <genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference model1.ecore#//SalesOrder/customer"/> </genClasses> </genPackages> </genmodel:GenModel>
Generate The Model
Generate the Java code for your model like you are used to do it:
The result of the generation can look similar to this (some artifacts are hidden to declutter the Package Explorer):