Non-Changeable与Unsettable Attributes
Non-Changeable Attributes:没有相应的set方法,不能externly修改其value.
Unsettable Attributes:一个attribute具有unset状态.unset的用途,比如:item的一个attribute:shipDate,那么shipDate是unset,那么表示该item还没ship出去,自然不会有shipDate;shipDate是null,就表示这个item是不可ship的.
Reference
One-Way references
生成的model code有一段:
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.
Bidirectional References

一个order只能有一个customer.此外,bidirectional references要注意的是在set的时候,在reference的两端都要进行操作。
code:[PurchaseOrderImpl]

public void setCustomer(Customer newCustomer) ...
{

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())
public
EList getOrders()
...
{

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]--
Containment References的“多”端:1)explicitly:getItems()返回的是EObjectContainmentWithInverseEList,并且在关系的另一端的setOrder不再使用proxy,而是eContainer。
public
ContainPurchaseOrder getOrder()
...
{
if (eContainerFeatureID != PurchaseOrderPackage.CONTAIN_ITEMS__ORDER) return null;
return (ContainPurchaseOrder)eContainer();
}
2)implicitly:getItems()返回的是EObjectContainmentEList,在item端里面没有其他的方法。在Item里面有个eContainer,返回的就是这个containment关系中的container,亦即ContainImplicityPurchaseOrder.使用方法如下:
EObject container = item.eContainer();//定义一个container,从item里面获得它的container
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类型,表现在:


public class IntToOrderMapEntryImpl extends EObjectImpl implements BasicEMap.Entry ...{
在indexImpl中对该map类型的使用

public EMap getOrdermaps() ...
{

if (ordermaps == null) ...{
ordermaps = new EcoreEMap(PurchaseOrderPackage.Literals.INT_TO_ORDER_MAP_ENTRY, IntToOrderMapEntryImpl.class, this, PurchaseOrderPackage.INDEX__ORDERMAPS);
}
return ordermaps;
}