command framework


Company comp = ...
EditingDomain ed = ...
RemoveCommand cmd =
new RemoveCommand(ed,comp,CompanyPackage.eINSTANCE.getCompany_Departments(),dep);
ed.getCommandStack().execute(cmd);
Object target = extractDropTarget(event.item);
command = DragAndDropCommand.create(domain, target, getLocation(event), event.operations, originalOperation, source);//domain就是上面的editingDomain
public static Command create(EditingDomain domain, Object owner, float location, int operations, int operation, Collection collection)
...{
return domain.createCommand
(DragAndDropCommand.class, new CommandParameter(owner, new Detail(location, operations, operation), collection));/*domain的具体类型是?由于前面说过AdapterFactoryEditingDomain委派给实现IEditingDomainItemProvider接口的item provider,那么就是YYYItemProvider.*/
}
else if (commandClass == DragAndDropCommand.class)
...{
DragAndDropCommand.Detail detail = (DragAndDropCommand.Detail)commandParameter.getFeature();
result = createDragAndDropCommand
(domain, commandParameter.getOwner(), detail.location, detail.operations, detail.operation, commandParameter.getCollection());
}
protected Command createDragAndDropCommand
(EditingDomain domain, Object owner, float location, int operations, int operation, Collection collection)
...{
return new DragAndDropCommand(domain, owner, location, operations, operation, collection);
}Change Notification

Adapter [] adapters = (Adapter [])eAdapters.data();
for (int i = 0; i < size; ++i)
...{
adapters[i].notifyChanged(notification);//给list中每个注册了的adapter发送notification.
}
switch (notification.getFeatureID(PurchaseOrder.class)) ...{
case PurchasePackage.PURCHASE_ORDER__TO_SHIP:
case PurchasePackage.PURCHASE_ORDER__TO_BILL:
fireNotifyChanged(new ViewerNotification(notification, notification.getNotifier(), false, true));
return;
case PurchasePackage.PURCHASE_ORDER__ITEMS:
fireNotifyChanged(new ViewerNotification(notification, notification.getNotifier(), true, false));
return;
}
super.notifyChanged(notification);总共3个case子句,前2个是改变purchaseOrder的两个attribute,后1个是改变子对象Item.看看ViewerNotification的后两个参数.

说明前两个case导致label update,后一个case导致content refresh.
3.而这个fireNotifyChanged是调用父类ItemProviderAdapter的,用来把notification转交给adapter factory(YYYItemProviderAdapterFactory),再由factory发给各个listener.
[ItemProviderAdapter.fireNotifyChanged()]
if (adapterFactory instanceof IChangeNotifier)
...{
IChangeNotifier changeNotifier = (IChangeNotifier)adapterFactory;
changeNotifier.fireNotifyChanged(notification);
}adapterFactory就是YYYItemProviderAdapterFactory.
跟踪如下:
在YYYItemProvider(父类就是ItemProviderAdapter)构造函数里调用了super(adapterFactory),而XXXAdapterFacotry调用了子类(XXXItemProviderAdapterFactory).createPurchaseOrderAdapter,createPurchaseOrderAdapter里面调用了new PurchaseOrderItemProvider(this).那么这个this也就是后来一直传递的adapterFactory,亦即XXXItemProviderAdapterFactory.
4.[YYYItemProviderAdapterFactory.fireNotifyChanged()]
changeNotifier.fireNotifyChanged(notification);
if (parentAdapterFactory != null) ...{
parentAdapterFactory.fireNotifyChanged(notification);
}注意到XXXItemProviderAdapterFactory).adapterFatory维持了一张自己的notifier list(changeNotifier)(生成的代码中这个似乎为null,难道没用?比如在set***引发的事件当中,这个list是空),把notification传递给这个list中的每一个notifier,让他们再进一步notify 它们自己的listerner.
对于parentAdapterFatory(ComposedAdapterFactory类型),如果非空,那么把notification传递过去.再传递notification下去(比如传给AdapterFactoryContentProvider-->viewer结束)
补充:
1.在XXXEditor的constructor中:
factories.add(new ResourceItemProviderAdapterFactory());
factories.add(new PurchaseItemProviderAdapterFactory());
factories.add(new ReflectiveItemProviderAdapterFactory());
将editingDomain注册几个能被delegate的adapter Factory.
在XXXEditor.createModel()中
editingDomain是AdapterFactoryEditingDomain类型,getResourceSet()返回一个ResourceSet接口类型的对象,ResourceSet继承了Notifier接口,editingDomain.getResourceSet().eAdapters()得到一个ResourceSet(notifier)的adapters(监听这个notifier的),并再加一个adapter--problemIndicationAdapter.
2. 在EMF.EDIT中包含的一些常用command
SetCommand sets the value of an attribute or reference on an EObject. AddCommand adds one or more objects to a multiplicity-many feature of an EObject. RemoveCommand removes one or more objects from a multiplicity-many feature of an EObject. MoveCommand moves an object within a multiplicity-many feature of an EObject. ReplaceCommand replaces an object in a multiplicity-many feature of an EObject.
本文深入探讨了EMF中的CommandFramework工作原理,包括AdapterFactoryEditingDomain如何通过ItemProviders提供编辑域服务,以及各种命令如DragAndDropCommand的工作流程。此外,还讲解了ChangeNotification机制以及如何在ItemProvider中进行定制。
1115





