Non-Changeable与Unsettable Attributes
public PurchaseOrder getPreviousOrder() ... {
if (previousOrder != null && previousOrder.eIsProxy()) ...{
PurchaseOrder oldPreviousOrder = previousOrder;
previousOrder =
(PurchaseOrder)EcoreUtil.resolve(previousOrder, this);
if (previousOrder != oldPreviousOrder) ...{
if (eNotificationRequired()) eNotify(
new ENotificationImpl(this, Notification.RESOLVE, ...));
}
}
return previousOrder;
}
EMF persistence framework 使用lazy loading机制,那么这个previousOrder很有可能直接指向了一个null,导致不可预料的结果.所以将previousOrder指向一个代理.eIsProxy()判断是否指向一个代理,resolve()将第一次去load这个refernced object's document.
一个order只能有一个customer.此外,bidirectional references要注意的是在set的时候,在reference的两端都要进行操作。
code:[PurchaseOrderImpl]
if (newCustomer != customer) ...{
NotificationChain msgs = null;
if (customer != null)
msgs = ((InternalEObject)customer).eInverseRemove(this, PurchaseOrderPackage.CUSTOMER__ORDERS, Customer.class, msgs);//调用的是customer的方法,在它们之间关系的另一端(customer)的order list去除这个order.
if (newCustomer != null)
msgs = ((InternalEObject)newCustomer).eInverseAdd(this, PurchaseOrderPackage.CUSTOMER__ORDERS, Customer.class, msgs);//再在新的customer里的order list加上这个order.
msgs = basicSetCustomer(newCustomer, msgs);//自己这一端
if (msgs != null) msgs.dispatch();
}
else if (eNotificationRequired())
eNotify(new ENotificationImpl(this, Notification.SET, PurchaseOrderPackage.PORDER_BIDIRECTION__CUSTOMER, newCustomer, newCustomer));
}
public NotificationChain basicSetCustomer(Customer newCustomer, NotificationChain msgs) ... {
Customer oldCustomer = customer;
customer = newCustomer; //设置customer,其他都是notify相关
if (eNotificationRequired()) ...{
ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, PurchaseOrderPackage.PORDER_BIDIRECTION__CUSTOMER, oldCustomer, newCustomer);
if (msgs == null) msgs = notification; else msgs.add(notification);
}
return msgs;
}
Multi References
对于multi reference(不仅仅是multi reference,只要某一端的关系是属于*),那么产生的代码中就没有set方法,只有单纯的get,如上面的PurchaseOrder,是“多对1”中的多,那么在Customer中只有getOrders():(如果定义一个multi Attribute 同样是只有一个getXXX())
if (orders == null) ...{
orders = new EObjectWithInverseResolvingEList(POrderBidirection.class, this, PurchaseOrderPackage.CUSTOMER__ORDERS, PurchaseOrderPackage.PORDER_BIDIRECTION__CUSTOMER);
}
return orders;
}
要添加什么的,直接对getOrders()返回的list进行add等操作。
Containment References
EObjectList的三个子类:EObjectContainmentEList,EObjectResolvingElist,EObjectWithInverseElist。先看几个图:
[implicitly]--
[explicitly]--
if (eContainerFeatureID != PurchaseOrderPackage.CONTAIN_ITEMS__ORDER) return null;
return (ContainPurchaseOrder)eContainer();
}
if (container instanceof PurchaseOrder)//保证类型能正确转换
purchaseOrder = (PurchaseOrder)container;// ok,转换为purchaseOrder
此外,Multi References的“多”端:getItems()返回的是EObjectWithInverseResolvingEList。
Map References
模型定义如下:注意改IntToOrderMapEntry的property sheet中的instance class name为java.util.Map$Entry.
生成代码后可以看到Map类型,表现在:
在indexImpl中对该map类型的使用
if (ordermaps == null) ...{
ordermaps = new EcoreEMap(PurchaseOrderPackage.Literals.INT_TO_ORDER_MAP_ENTRY, IntToOrderMapEntryImpl.class, this, PurchaseOrderPackage.INDEX__ORDERMAPS);
}
return ordermaps;
}