﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-xiaoxiaoleemin-随笔分类-EMF</title><link>http://www.blogjava.net/xiaoxiaoleemin/category/20295.html</link><description>天道酬勤，小小加油</description><language>zh-cn</language><lastBuildDate>Tue, 08 May 2007 03:17:10 GMT</lastBuildDate><pubDate>Tue, 08 May 2007 03:17:10 GMT</pubDate><ttl>60</ttl><item><title>EMF建模常见问题</title><link>http://www.blogjava.net/xiaoxiaoleemin/archive/2007/05/07/115626.html</link><dc:creator>xiaoxiaoleemin</dc:creator><author>xiaoxiaoleemin</author><pubDate>Mon, 07 May 2007 06:10:00 GMT</pubDate><guid>http://www.blogjava.net/xiaoxiaoleemin/archive/2007/05/07/115626.html</guid><wfw:comment>http://www.blogjava.net/xiaoxiaoleemin/comments/115626.html</wfw:comment><comments>http://www.blogjava.net/xiaoxiaoleemin/archive/2007/05/07/115626.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/xiaoxiaoleemin/comments/commentRss/115626.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/xiaoxiaoleemin/services/trackbacks/115626.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp; 我习惯于直接用ECore Editor建立ecore模型，如果装了GMF插件的话，在ecore文件上点击鼠标右键，通过菜单&#8220;Initialize ecore-diagram diagram file&#8221;可以生成类似类图的表示，这样可以从整体上看模型。而且在建模的过程中可以随时"Validate"以检查当前存在的错误。以下是一些常见的问题：<br>&nbsp;&nbsp;&nbsp; 1.Ecore Editor中根元素的直接子元素属性页中有&#8220;Ns Prefix"和"Ns URI"两项需要设置，前者可以设置为模型的名字，后者随便设置一个URI地址，如"http://"+模型名字。如果这两项不设置，那么当修改了ecore模型后，从genmodel上&#8220;Reload" ecore模型时出错。<br>&nbsp;&nbsp;&nbsp; 2.某个EReference如果多重性为"0...*",则在属性页中把lower bound设置为0，upper bound设置为-1。<br>&nbsp;&nbsp;&nbsp; 3.genmodel根元素的第一层子元素的属性页中，"All"类别中&#8220;prefix&#8221;属性值是指EMF生成的代码中Factory和Package等类的前缀，可以指定为模型名字，首字母大写以符合类名的习惯；&#8220;base package&#8221;属性值是生成的各个包的前缀，假设指定为&#8220;com.example"。然后有&#8220;Ecore&#8221;类别，其中的各个属性值是从ecore模型中读过来的，不可修改，其中&#8220;Package&#8221;类别下的"Name"属性值是包名的一部分（假设指定为model），接在前面的base package值之后，那么生成的Model 部分代码分别有三个包：com.example.model; com.example.model.impl; com.example.model.util.&nbsp;<br>&nbsp;&nbsp;&nbsp;btw：在有的GMF 版本中，如果包名存在首字母大写的单词，那么生成代码的时候会出错。<br><br>
<img src ="http://www.blogjava.net/xiaoxiaoleemin/aggbug/115626.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xiaoxiaoleemin/" target="_blank">xiaoxiaoleemin</a> 2007-05-07 14:10 <a href="http://www.blogjava.net/xiaoxiaoleemin/archive/2007/05/07/115626.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>如何显示PropertySheet视图</title><link>http://www.blogjava.net/xiaoxiaoleemin/archive/2007/05/06/115517.html</link><dc:creator>xiaoxiaoleemin</dc:creator><author>xiaoxiaoleemin</author><pubDate>Sun, 06 May 2007 09:24:00 GMT</pubDate><guid>http://www.blogjava.net/xiaoxiaoleemin/archive/2007/05/06/115517.html</guid><wfw:comment>http://www.blogjava.net/xiaoxiaoleemin/comments/115517.html</wfw:comment><comments>http://www.blogjava.net/xiaoxiaoleemin/archive/2007/05/06/115517.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/xiaoxiaoleemin/comments/commentRss/115517.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/xiaoxiaoleemin/services/trackbacks/115517.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要:      前面的几篇是读了《EMF：A Developer's Guide》一书前三章的读书笔记，我觉得这三章的内容是最重要的，介绍了EMF Framework的一些设计、结构以及实现的问题。但是这些只是一些原理性的东西，要熟练掌握EMF的方法是在项目中应用它，我们可以从修改EMF生成的代码入手。EMF生成的编辑器是MultiPageEditor，比较复杂，我们可以参考它自己写一个普通的Editor，在这个过程中可以熟悉哪些代码是用于实现哪些功能的。&nbsp;&nbsp;<a href='http://www.blogjava.net/xiaoxiaoleemin/archive/2007/05/06/115517.html'>阅读全文</a><img src ="http://www.blogjava.net/xiaoxiaoleemin/aggbug/115517.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xiaoxiaoleemin/" target="_blank">xiaoxiaoleemin</a> 2007-05-06 17:24 <a href="http://www.blogjava.net/xiaoxiaoleemin/archive/2007/05/06/115517.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>《EMF：A Developer's Guide》读书笔记第三章 ：Model Editing with EMF.Edit（下）</title><link>http://www.blogjava.net/xiaoxiaoleemin/archive/2007/05/05/115439.html</link><dc:creator>xiaoxiaoleemin</dc:creator><author>xiaoxiaoleemin</author><pubDate>Sat, 05 May 2007 12:44:00 GMT</pubDate><guid>http://www.blogjava.net/xiaoxiaoleemin/archive/2007/05/05/115439.html</guid><wfw:comment>http://www.blogjava.net/xiaoxiaoleemin/comments/115439.html</wfw:comment><comments>http://www.blogjava.net/xiaoxiaoleemin/archive/2007/05/05/115439.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/xiaoxiaoleemin/comments/commentRss/115439.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/xiaoxiaoleemin/services/trackbacks/115439.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要:    上一部分中，我们看到了如何通过content和label provider来显示EMF模型，这一部分介绍如何修改、编辑EMF模型。EMF.Edit支持基于Command的模型编辑方式，可以自动的undo和redo。EMF.Edit的Command Framework可以分为两部分，第一部分是common command framework，其中定义了一些基本的命令接口，实现了例如basic command stack,compound command等，虽然这些命令主要用于EMF.Edit,但是实际上可以独立于EMF.Edit使用；第二部分是EMF.Edit 命令，是指一些专门编辑EObject的命令。&nbsp;&nbsp;<a href='http://www.blogjava.net/xiaoxiaoleemin/archive/2007/05/05/115439.html'>阅读全文</a><img src ="http://www.blogjava.net/xiaoxiaoleemin/aggbug/115439.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xiaoxiaoleemin/" target="_blank">xiaoxiaoleemin</a> 2007-05-05 20:44 <a href="http://www.blogjava.net/xiaoxiaoleemin/archive/2007/05/05/115439.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>《EMF：A Developer's Guide》读书笔记第三章 ：Model Editing with EMF.Edit（上）</title><link>http://www.blogjava.net/xiaoxiaoleemin/archive/2007/05/05/115355.html</link><dc:creator>xiaoxiaoleemin</dc:creator><author>xiaoxiaoleemin</author><pubDate>Sat, 05 May 2007 10:08:00 GMT</pubDate><guid>http://www.blogjava.net/xiaoxiaoleemin/archive/2007/05/05/115355.html</guid><wfw:comment>http://www.blogjava.net/xiaoxiaoleemin/comments/115355.html</wfw:comment><comments>http://www.blogjava.net/xiaoxiaoleemin/archive/2007/05/05/115355.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/xiaoxiaoleemin/comments/commentRss/115355.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/xiaoxiaoleemin/services/trackbacks/115355.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp; 本书的第二章介绍了EMF产生的Model部分的代码，你可以使用EMF Edit Framework来为model构建功能强大的视图和编辑器。在EMF为你生成的编辑器里，可以编辑（复制，粘贴，拖拽等）、显示model，还可以无限的redo/undo。如果这个编辑器不能完全满足你的需求，你可以在此基础上做一些修改，肯定比从头开始写节约时间。<br>&nbsp;&nbsp;&nbsp; Eclipse通过JFace中的一些Viewer来显示结构化的数据，这些Viewer不直接从model中获取要显示的数据，而是通过ContentProvider和LabelProvider来取得要显示的内容、文本以及图标等信息。不同的Viewer需要不同的ContentProvider和LabelProvider：<br>&nbsp;&nbsp;&nbsp;
<table width=419 border=1>
    <tbody>
        <tr>
            <td vAlign=center align=left>&nbsp;Viewer</td>
            <td>ContentProvider</td>
            <td>LabelProvider<br></td>
        </tr>
        <tr>
            <td>&nbsp;ListViewer<br></td>
            <td vAlign=center align=left>IStructureContentProvider&nbsp; <br></td>
            <td>ILabelProvider<br></td>
        </tr>
        <tr>
            <td vAlign=center align=left>&nbsp;TreeViewer</td>
            <td vAlign=center align=left>ITreeContentProvider <br></td>
            <td vAlign=center align=left>ILabelProvider <br></td>
        </tr>
        <tr>
            <td vAlign=center align=left>&nbsp;TableViewer</td>
            <td vAlign=center align=left>IStructureContentProvider <br></td>
            <td vAlign=center align=left>ITableLabelProvider <br></td>
        </tr>
    </tbody>
</table>
&nbsp;&nbsp;&nbsp; 其中ILabelProvider有getText(Object)和getImage(Object)两个方法，ITableLabelProvider有getColumnText(Object, int)和getColumnImage(Object,int)两个方法，它们之间没有继承关系。IStructureContentProvider有getElements(Object)方法，返回一个Object数组，而ITreeContentProvider是其子类，另有自己的方法getChildren(Object),getParent(Object)和hasChildren(Objecct)三个方法。<br>&nbsp;&nbsp;&nbsp; EMF Edit是把Eclipse UI Framework（JFace）和EMF Framework连接起来的桥梁，包括两部分，其中org.eclipse.emf.edit是与UI无关的部分，org.eclipse.emf.edit.ui是与UI有关的部分。前一部分主要包括ItemProvider和Commmand。<br>&nbsp;&nbsp;&nbsp;<span style="FONT-WEIGHT: bold"> 1.Item Providers<br>&nbsp;&nbsp;&nbsp; </span>item provider,这个名字来源于它为模型中各个可编辑的"items"(对象）"provides"功能。它通常是EMF Adapters，但是也可以不是。They are used to adapt model objects so the model object can provide all of the interfaces that it needs to be viewed and edited.<br>&nbsp;&nbsp;&nbsp; item provider主要有四个功能：作为content和label provider； 为EMF对象提供property source； 担当Command Factory； 将EMF模型的变化通知发送给Viewer。每个item provider可以实现上述全部功能或者部分功能，通常情况下，item provider通过继承EMF Edit的基类<span style="FONT-WEIGHT: bold">ItemProviderAdapter</span>来实现全部的功能。下面分别介绍这四个功能各自需要哪些方法的支持：<br>&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; (1)<span style="FONT-STYLE: italic">Content and label item providers</span><br>&nbsp;&nbsp;&nbsp; EMF.Edit分别通过AdapterFactoryContentProvider和AdapterFactcoryLabelProvider来提供content provider和label provider的功能，这两个类的构造函数都需要一个adapter factory（EMF生成的edit部分代码中的**ItemProviderAdapterFactory，负责为特定的类型创建或者定位adapter），它们的很多方法都通过分发到相应的Item Provider来实现。比如getChildren()的实现如下：<br>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="COLOR: #000000">&nbsp;&nbsp;</span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">boolean</span><span style="COLOR: #000000">&nbsp;hasChildren(Object&nbsp;object)<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;Get&nbsp;the&nbsp;adapter&nbsp;from&nbsp;the&nbsp;factory.</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;ITreeItemContentProvider&nbsp;treeItemContentProvider&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(ITreeItemContentProvider)adapterFactory.adapt(object,&nbsp;ITreeItemContentProviderClass);<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;Either&nbsp;delegate&nbsp;the&nbsp;call&nbsp;or&nbsp;return&nbsp;nothing.</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;treeItemContentProvider&nbsp;</span><span style="COLOR: #000000">!=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">null</span><span style="COLOR: #000000">&nbsp;&nbsp;</span><span style="COLOR: #000000">&amp;&amp;</span><span style="COLOR: #000000">&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;treeItemContentProvider.hasChildren(object);<br>&nbsp;&nbsp;}</span></div>
&nbsp;&nbsp;&nbsp; EMF.Edit为模型中的每个类生成一个**ItemProvider类，负责为UI的显示提供具体的实现。每个类在默认情况下都实现了5个接口,其中的三个IStructuredItemContentProvider(为ListViewer和TableViewer提供contentProvider), ITreeItemContentProvider(为TreeViewer提供contentProvider),IItemLabelProvider(为TreeViewer和ListViewer提供labelProvider)是支持这一功能的.<br>&nbsp;&nbsp;&nbsp; 如果我们要用TableViewer显示订单（模型中对应PurchaseOrder类），那么应该修改PurchaseOrderItemProvider，使它实现ITableItemLabelProvider，同时实现方法getColumnText和getColumnImage。还要在为该模型生成的POItemProviderAdapterFactory类的构造函数中添加对ITableItemLabelProvider的支持：<br>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="COLOR: #000000">...<br>supportedTypes.add(ITableItemLabelProvider.</span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">);</span></div>
&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; (2)<span style="FONT-STYLE: italic">Item Property Source</span><br>&nbsp;&nbsp;&nbsp; 当打开PropertySheet时，AdapterFactoryContentProvider还是通过adapterFactory找到相应的实现了IItemPropertySource接口的item Provider。EMF.Edit中的PropertySource类实现了这一接口，因此AdapterFactoryContentProvider返回PropertySource的一个新创建的实例（作为被选中的item provider的wrapper）给PropertySheet，PropertySource把很多方法的实现分发给了itemPropertySource。其代码如下：<br>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">&nbsp;IPropertySource&nbsp;getPropertySource(Object&nbsp;object)<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;(object&nbsp;</span><span style="COLOR: #0000ff">instanceof</span><span style="COLOR: #000000">&nbsp;IPropertySource)<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;(IPropertySource)object;<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000"><br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IItemPropertySource&nbsp;itemPropertySource&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(IItemPropertySource)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(object&nbsp;</span><span style="COLOR: #0000ff">instanceof</span><span style="COLOR: #000000">&nbsp;EObject&nbsp;</span><span style="COLOR: #000000">&amp;&amp;</span><span style="COLOR: #000000">&nbsp;((EObject)object).eClass()&nbsp;</span><span style="COLOR: #000000">==</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">null</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">?</span><span style="COLOR: #000000"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">null</span><span style="COLOR: #000000">&nbsp;:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;adapterFactory.adapt(object,&nbsp;IItemPropertySourceClass));<br>&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;itemPropertySource&nbsp;</span><span style="COLOR: #000000">!=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">null</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">?</span><span style="COLOR: #000000">&nbsp;&nbsp;createPropertySource(object,&nbsp;itemPropertySource)&nbsp;:&nbsp;</span><span style="COLOR: #0000ff">null</span><span style="COLOR: #000000">;<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;</span><span style="COLOR: #0000ff">protected</span><span style="COLOR: #000000">&nbsp;IPropertySource&nbsp;createPropertySource(Object&nbsp;object,&nbsp;IItemPropertySource&nbsp;itemPropertySource)<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000">&nbsp;PropertySource(object,&nbsp;itemPropertySource);<br>&nbsp;&nbsp;}</span></div>
&nbsp;&nbsp;&nbsp; 自动生成的**ItemProvider实现的5个接口中的IItemPropertySource就是支持这一功能的， 其中getPropertyDescriptors()方法返回的列表决定了PropertySheet中显示的内容列表。<br>&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; (3)<span style="FONT-STYLE: italic">Command Factory</span><br>&nbsp;&nbsp;&nbsp; EMF.Edit提供了修改EMF对象（可以undo）的整套机制，并且提供了一些通用的命令。自动生成的**ItemProvider实现的5个接口中还没提到的IEditingDomainItemProvider就是支持这一功能的。EMF.Edit的Command Framework需要EditngDomain接口，其中类AdapterFactoryEditingDomain如同前面提到的AdapterFactoryContentProvider和AdapterFactoryLabelProvider，它负责把相应的方法(比如getChildren()，getParent()等）分发给实现了IEditingDomainItemProvider的Item Provider。<br>&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; (4)<span style="FONT-STYLE: italic">Change Notification</span><br>&nbsp;&nbsp;&nbsp; 当**ItemProvider所adapt的对象状态发生变化时，**ItemProvider会收到Notification，其NotifyChanged()会被调用。ItemProvider作为Observer负责过滤不相关的事件，然后把相关的事件传递给模型的central change notifier，通常是实现了IChangeNotifier接口的**ItemProviderAdapterFactory。<br>&nbsp;&nbsp;&nbsp; 当我们在PropertySheet中修改Item（订单项，在模型中对应Item类）的名字时，首先ItemPropertyDescriptor的setPropertyValue()方法被调用，它会通过SetCommand修改名字或者直接调用Item的eSet(),总之这两种方法都会调用到ItemImpl的setName()方法，该方法中判断是否需要发送通知，如果需要，则向所有监听item对象的adapter发送通知（即调用它们的notifyChanged()方法），这些adapter包括ItemItemProvide，它的notifyChanged()方法调用POItemProviderAdapterFactory（IChangeNotifier类型）的fireNotifyChanged()方法，然后再调用所有注册的listener的fireNotifyChanged()。这些listener可能是PropertySheet，Outline视图中的TreeViewer等，收到通知后，更新视图以反映model的变化。当有事件发生需要通知JFace的Viewer时，真正的listener并不是viewer本身，而是它的content provider。<br><br>&nbsp;&nbsp;&nbsp; EMF.Edit的另一部分重要内容Command Framework留到下一部分介绍。<br><br>
<img src ="http://www.blogjava.net/xiaoxiaoleemin/aggbug/115355.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xiaoxiaoleemin/" target="_blank">xiaoxiaoleemin</a> 2007-05-05 18:08 <a href="http://www.blogjava.net/xiaoxiaoleemin/archive/2007/05/05/115355.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>《EMF：A Developer's Guide》读书笔记第二章 ：EMF简介（下）</title><link>http://www.blogjava.net/xiaoxiaoleemin/archive/2007/05/04/115344.html</link><dc:creator>xiaoxiaoleemin</dc:creator><author>xiaoxiaoleemin</author><pubDate>Fri, 04 May 2007 13:44:00 GMT</pubDate><guid>http://www.blogjava.net/xiaoxiaoleemin/archive/2007/05/04/115344.html</guid><wfw:comment>http://www.blogjava.net/xiaoxiaoleemin/comments/115344.html</wfw:comment><comments>http://www.blogjava.net/xiaoxiaoleemin/archive/2007/05/04/115344.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/xiaoxiaoleemin/comments/commentRss/115344.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/xiaoxiaoleemin/services/trackbacks/115344.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp; EMF Framework提供了模型变化通知、持久化支持、操纵EMF对象的反射API等功能来帮助用户提高工作效率，下面分别详细介绍一下。<br>&nbsp;&nbsp;&nbsp; <span style="FONT-WEIGHT: bold">1.Notification and Adapter</span><br>&nbsp;&nbsp;&nbsp; EMF生成的每一个类还是一个Notifier类型，因此当它的属性或者引用改变的时候可以发出通知。这是一个很重要的性质，通过监听EObject的变化可以及时地更新视图或者与之相关联的对象。EMF中的Notification Observer（Listener）叫做Adapter，它除了监听事件以外，还可以扩展其它行为(extend behavior)等。一个Adapter可以通过如下的方式添加到任何一个EObject对象上（比如PurchaseOrder）：<br>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="COLOR: #000000">Adapter&nbsp;poObserver&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;<img src="http://www.blogjava.net/Images/dot.gif"><br>aPurchaseOrder.eAdapters().add(poObserver);</span></div>
&nbsp;&nbsp;&nbsp; 然后，当aPurchaseOrder的状态发生变化时（比如setBillTo方法发生了），poObserver的notifyChanged()方法会被调用。<br>&nbsp;&nbsp;&nbsp; <span style="FONT-WEIGHT: bold">EContentAdapter</span>,可以添加到一个根元素，一个资源或者一个resource set,它可以监听这些元素的任何子元素的状态变化.<br>&nbsp;&nbsp;&nbsp; Adapter在实现behavior extension(比如不通过继承来实现某个接口的功能）的功能时，是通过AdapterFactory来完成的。比如：
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="COLOR: #000000">POAdapter&nbsp;adapter&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;(POAdapter)somePOAdaterFactory.adapt(someObject,POAdapter.</span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">);<br></span></div>
&nbsp;&nbsp;&nbsp; 这样，POAdapter类型的adapter对象被添加到了对象someObject上。<br>&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;<span style="FONT-WEIGHT: bold">&nbsp; 2.Object Persistence</span><br>&nbsp;&nbsp;&nbsp; EMF对任何model的默认的序列化方式是XMI。有两个跟序列化相关的函数：eContainer()和eResource().下面通过例子来看这两个方法的作用：<br>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="COLOR: #000000">PurchaseOrder&nbsp;order&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;POFactory.eINSTANCE.createPurchaseOrder();<br>order.setBillTo("123 Maple Street");<br><br>Item item = POFactory.eINSTANCE.createItem();<br>item.setProductName("Apples");<br>item.setPrice(0.45);<br>item.setQuantity(20);<br><br>order.getItems.add(item);<br></span></div>
&nbsp;&nbsp;&nbsp; 这里PurchaseOrder和Item分别是模型中代表订单和订单项的类。这时如果调用item.eContainer()会返回order对象。但是如果调用order.eContainer()则会返回null，因为它没有被包含在任何元素里边。这时order和item的eResource()方法都会返回null。<br>&nbsp;&nbsp;&nbsp; 为了序列化这些对象，我们应该把它们加入到一个Resource里边。Resource是一个代表吴立存储位置（如文件）的接口。我们只需要把根元素加入到Resource中即可。<br>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="COLOR: #000000">Resource&nbsp;resource&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;<img src="http://www.blogjava.net/Images/dot.gif">;<br>resource.getContents().add(order);</span></div>
&nbsp;&nbsp;&nbsp;&nbsp; 这时order和item的eResource（）方法都会返回resource对象，其中item是通过order加入到resource中去的。这时调用resource.save(null)后两个对象就保存下来了。<br>&nbsp;&nbsp;&nbsp; 但是，如何取得resource呢？可以借助于EMF中的ResourceSet， 它是创建Resource的工厂，就是一系列resource的集合。<br>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="COLOR: #000000">ResourceSet&nbsp;resourceSet&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000">&nbsp;ResourceSetImpl();<br>URI fileURI = URI.createFileURI(new File("mypo.xml").getAbsolutePath());<br>Resource resource = resourceSet.createResource(fileURI);<br>resource.getContents().add(order);<br>resource.save(null); <br></span></div>
&nbsp;&nbsp;&nbsp; 保存完成之后，如何读取呢？
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="COLOR: #000000">PurchaseOrder&nbsp;order&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;(PurchaseOrder)resource.getContents().get(</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">);</span></div>
&nbsp;&nbsp;&nbsp; ResourceSet还支持跨文档的引用（cross-document reference)，当遇到跨文档的引用时，先用proxy对象来代替实际的对象，当第一次真正使用这个对象的时候才resolve成真正的对象。Proxy是一个关于目标类的一个未初始化的对象，但是它拥有实际对象的URI。<br>&nbsp;&nbsp; <br>&nbsp;&nbsp;<span style="FONT-WEIGHT: bold">&nbsp; 3.The Reflective EObject API <br>&nbsp;&nbsp;&nbsp; </span>EObject defines a generic,reflective API for manipulating instances.<br>&nbsp;&nbsp;&nbsp;
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="COLOR: #000000">EClass&nbsp;orderClass&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;POPackage.eINSTANCE.getPurchaseOrder();<br>EAttribute shipToAttribute = POPackage.eINSTANCE.getPurchaseOrder_shipTo();<br>orderClass.eSet(shipToAttribute, "123 street");<br>String shipTo = orderClass.eGet(shipToAttribute);<br></span></div>
&nbsp;&nbsp;&nbsp; 上面调用orderClass的eSet和eGet方法比直接调用order的setShipTo()和getShipTo()效率要低一些，因为它要switch做一些条件判断，但是它的优点是open up the model for completely generic access.EMF.Edit中的AddCommand，SetCommand等通用的命令就是通过这种方式实现的。<br>&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;<span style="FONT-WEIGHT: bold">&nbsp; 4.Dynamic EMF<br>&nbsp;&nbsp;&nbsp; </span>在没有生成模型中各个类的代码之前，我们也可以使用他们的对象，如下：<br>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="COLOR: #000000">EPackage&nbsp;</span><span style="COLOR: #0000ff">package</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;EcoreFactory.eINSTANCE.createEPackage();<br>EClass orderClass = EcoreFactory.eINSTANCE.createEClass();<br>orderClass.setName("PurchaseOrder");<br>package.getEClassifiers().add(orderClass);<br><br>EClass itemClass = </span><span style="COLOR: #000000">EcoreFactory.eINSTANCE.createEClass();<br>itemClass.setName("Item");<br>package.getEClassifiers().add(itemClass);<br><br>EAttribute shipToAttribute = EcoreFactory.eINSTANCE.createAttribute();<br>shipToAttribute.setName("shipTo");<br>shipToAttribute.setEType(EcorePackage.eINSTANCE.getEString());<br>orderClass.getEAttributes().add(shipToAttribute);<br>...<br></span></div>
&nbsp;&nbsp;&nbsp; 接下来，我们可以这样初始化这些类的对象：<br>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="COLOR: #000000">EFactory&nbsp; factory = package.getEFactoryInstance();<br>EObject order = factory.create(orderClass);<br>order.eSet(shipToAttribute, &#8220;123 street");<br></span></div>
&nbsp;&nbsp;&nbsp; 至此，EMF的基本知识就介绍完了，如果你只是需要EMF产生的Model Code，那么需要学习的东西就这么多了。如果你还需要EMF产生的Edit Code和Editor Code，那么还有另外的知识需要学习。<br>
<img src ="http://www.blogjava.net/xiaoxiaoleemin/aggbug/115344.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xiaoxiaoleemin/" target="_blank">xiaoxiaoleemin</a> 2007-05-04 21:44 <a href="http://www.blogjava.net/xiaoxiaoleemin/archive/2007/05/04/115344.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>《EMF：A Developer's Guide》读书笔记第二章 ：EMF简介（上）</title><link>http://www.blogjava.net/xiaoxiaoleemin/archive/2007/05/04/115251.html</link><dc:creator>xiaoxiaoleemin</dc:creator><author>xiaoxiaoleemin</author><pubDate>Fri, 04 May 2007 11:13:00 GMT</pubDate><guid>http://www.blogjava.net/xiaoxiaoleemin/archive/2007/05/04/115251.html</guid><wfw:comment>http://www.blogjava.net/xiaoxiaoleemin/comments/115251.html</wfw:comment><comments>http://www.blogjava.net/xiaoxiaoleemin/archive/2007/05/04/115251.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/xiaoxiaoleemin/comments/commentRss/115251.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/xiaoxiaoleemin/services/trackbacks/115251.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp; 1.<span style="FONT-WEIGHT: bold">EMF的元模型Ecore </span>&nbsp; <br>&nbsp;&nbsp;&nbsp; 我们通常所说的模型(Model)是指应用程序更高层次的描述，通过它可以生成部分甚至全部的实现代码，可以由UML等标准的方法来定义。EMF(Eclipse Modeling Framework)中的模型层次没有这么高，它和实现直接关联。<br>&nbsp;&nbsp;&nbsp; EMF是一个可以产生代码的框架，你可以通过UML类图、XML Schema、Java Interface等任何一种方式来定义EMF模型，而且可以由一种方式生成另外其它方式，在这里EMF 模型就是把这三者结合在一起的更高层次的一种表示。EMF模型本质上是UML类图的子集，它是关于应用的类和数据的简单模型。<br>&nbsp;&nbsp;&nbsp; 用来描述EMF模型的模型（元模型）叫做Ecore，Ecore本身也是一个EMF模型，因此它是自己的元模型，也可以说Ecore是一个元元模型。Ecore模型的主要组成部分有：<br>&nbsp;&nbsp;&nbsp; EClass：代表一个类，通常有自己的名字，0个或者多个属性、引用。&nbsp; &nbsp; <br>&nbsp;&nbsp;&nbsp; EAttribute:代表一个属性，有自己的名字和类型。<br>&nbsp;&nbsp;&nbsp; EReference:代表两个类之间的关联关系的一端。有名字，代表是否聚合的boolean类型的标志，以及目标类的类型。<br>&nbsp;&nbsp;&nbsp; EDataType：代表属性的类型，可以是int或者float等原子类型，也可以是java.util.Date等对象类型。<br>&nbsp;&nbsp;&nbsp; 当我们有了自己的具体应用时，我们会实例化Ecore的以上元素为这个具体的应用构造模型，称为core模型。core模型的序列化采用XMI(XML Metadata Interchange)，因为用来定义core模型的三种方式（Java Interface,XML Schema，UML)都有各自的缺点，不适合作为core模型的序列化形式。<br>&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; 2.<span style="FONT-WEIGHT: bold">目前生成Ecore模型的三种方法</span><br>&nbsp;&nbsp;&nbsp; （1）从UML生成: 直接用Ecore Editor或者Omondo提供的工具EclipseUML;也可以从EMF Project的Wizard中导入mdl文件；还可以从UML工具中导出。其中第一种方法可以自动的同步core模型与工具中编辑的模型（如EclipseUML编辑的ecd文件），而后两种方法当uml类图有了变化时需要重新导入或者导出才能使core模型与之同步。<br>&nbsp;&nbsp;&nbsp; （2）从Java Interface生成：在要建模的类或者方法前加&#8220;@model&#8221;注释，每个属性和引用对应一个get方法，不需要set方法。<br>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="COLOR: #008000">/**</span><span style="COLOR: #008000"><br>&nbsp;*@model<br>&nbsp;</span><span style="COLOR: #008000">*/</span><span style="COLOR: #000000"><br></span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">interface</span><span style="COLOR: #000000">&nbsp;PurchaseOrder<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">/**</span><span style="COLOR: #008000"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@model<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">*/</span><span style="COLOR: #000000"><br>&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;getShipTo();<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">/**</span><span style="COLOR: #008000"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@model<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">*/</span><span style="COLOR: #000000"><br>&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;getBillTo();<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">/**</span><span style="COLOR: #008000"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@model&nbsp;type="Item"&nbsp;containment="true"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">*/</span><span style="COLOR: #000000"><br>&nbsp;&nbsp;&nbsp;&nbsp;List&nbsp;getItems();<br>}</span></div>
<br>&nbsp;&nbsp;&nbsp; (3)从XML Schema生成：模型中的每个类用一个complex type表示，一个属性用一个内嵌的element表示，引用则用一个内嵌的属于另一个complex type的element表示。这样给定schema之后，模型实例的序列化根据它来进行。<br>&nbsp;&nbsp;&nbsp; 除了以上三种定义模型的方式之外，还存在其它的方式，比如说，目前EMF正在支持RDB Schema（Rational Database)的方式来定义模型。<br>&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; 3.<span style="FONT-WEIGHT: bold">代码生成</span><br>&nbsp;&nbsp;&nbsp; 模型到代码的自动生成是EMF重要的功能之一，大大提高了生产率，而且生成的代码简洁，高效。<br>&nbsp;&nbsp;&nbsp; Ecore中的每个类（EClass）会生成一个接口和一个实现类，EMF特意采用了这种实现与接口相分离的设计。其中的接口都会继承EObject这一EMF中的集接口，它如同java.lang.Object在Java中的地位，它主要提供了三个功能：eClass（）方法返回该对象的metaobject；eContainer（）和eResource（）反别返回包含该对象的对象和资源；另外eGet（）、eSet（）、eIsSet（）和eUnset（）等方法为访问该对象提供了API.EObject还继承了Notifier接口，当对象发生变化时（如成员变量的取值发生了变化）会发出通知（观察者设计模式）。比如改变Order对象的属性shipTo的set方法的实现如下所示:
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;setShipTo(String&nbsp;newShipTo)<br>{<br>&nbsp;&nbsp;&nbsp;String&nbsp;oldShipTo&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;shipTo;<br>&nbsp;&nbsp;&nbsp;shipTo&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;newShipTo;<br>&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">(eNotificationRequired())<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;eNotify(</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000">&nbsp;ENotificationImpl(</span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">,&nbsp;Notification.SET,&nbsp;POPackage.PURCHASE_ORDER_SHIP_TO,&nbsp;oldShipTO,&nbsp;shipTo));<br>}</span></div>
&nbsp;&nbsp; 其中eNotificationRequired()是BasicNotifierImpl类提供的方法，它返回是否需要调用eNofifier().<br>&nbsp;&nbsp; 除此以外，EMF还为每个模型分别生成一个factory和package对应的接口和实现类。其中**Factory继承于EFactory，为模型中每个类的创建提供create***方法，因此我们在EMF中一般不用new来创建对象。创建一个订单对象的代码如下：<br>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="COLOR: #000000">PurchaseOrder&nbsp;po&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;POFactory.eINSTANCE.createPurchaseOrder();</span></div>
&nbsp;&nbsp;&nbsp; 如果**Factory中没有为你想要的类型生成特定的create***（）方法，那么可以用基类EFactory的create（EClass class)方法，将要创建的类型作为参数传入即可。比如说，模型中用到Enumeration或者自定义的MapEntry，**Factory中就不会有直接创建这两个类型的对象的方法，我们可以用***Factory.eINSTANCE.create（**Package.eINSTANCE.getIntToIntEntry)来完成。<br>&nbsp;&nbsp; **Package使得我们可以访问模型中的Ecore元数据，模型中的每个类、每个属性、每个引用都在**Package中对应一个int值。<br>&nbsp;&nbsp; 生成的**AdapterFactory类可以为特定的类型创建Adapter。<br><br>&nbsp;&nbsp; 4.<span style="FONT-WEIGHT: bold">代码的重新生成与合并<br>&nbsp;&nbsp; </span>EMF生成的类、接口、方法、域前面都有&#8220;@generated"标记，如果改变该标记，那么在重新生成代码的时候，这个标记下的部分保持不变，不会重新生成。如果你修改了getName（）方法的实现，也相应的修改了该方法前面的"@generated"标记，但是你既想保留自己对这个方法的修改，又想看看EMF自动生成的这个方法是什么样子的，这时可以通过在该类文件中添加这样一个方法来实现：<br>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="COLOR: #008000">/**</span><span style="COLOR: #008000"><br>&nbsp;&nbsp;*@generated<br>&nbsp;&nbsp;</span><span style="COLOR: #008000">*/</span><span style="COLOR: #000000"><br></span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">&nbsp;String&nbsp;getNameGen()<br>{<br>}</span></div>
&nbsp;&nbsp; 这个方法名字的末尾加上了Gen后缀，这样EMF在生成代码的时候发现你把getName（）前面的&#8220;@generated"标记修改了，这时它会检查有没有getNameGen()方法存在，如果有，就把getName的默认实现添加在这个方法里边。重新生成代码后，发现EMF为getNameGen()方法添加了实现语句"return name".<br>&nbsp;&nbsp; EMF代码生成器是从generator model （.genmodel文件）而不是core model（.ecore文件）来生成代码的，这里的generator model是core model的Decorator，其中的GenClass修饰EClass， GenFeature修饰EAttribute和EReference等，另外它还包含生成代码的包名，生成的Package和Factory类的前缀名字等信息。<br>&nbsp;&nbsp; generator model和ecore model分离的好处是，Ecore元模型只保存模型信息，而独立于代码生成相关的一些额外信息。坏处是两个模型可能出于不一致的状态，因此修改了ecore模型后，应该在genmodel上重新导入ecore模型，以保持两个模型的一致性。<br>&nbsp;&nbsp;&nbsp; <br>
<img src ="http://www.blogjava.net/xiaoxiaoleemin/aggbug/115251.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xiaoxiaoleemin/" target="_blank">xiaoxiaoleemin</a> 2007-05-04 19:13 <a href="http://www.blogjava.net/xiaoxiaoleemin/archive/2007/05/04/115251.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>《EMF：A Developer's Guide》读书笔记第一章：Eclipse概述</title><link>http://www.blogjava.net/xiaoxiaoleemin/archive/2007/03/03/101612.html</link><dc:creator>xiaoxiaoleemin</dc:creator><author>xiaoxiaoleemin</author><pubDate>Sat, 03 Mar 2007 05:26:00 GMT</pubDate><guid>http://www.blogjava.net/xiaoxiaoleemin/archive/2007/03/03/101612.html</guid><wfw:comment>http://www.blogjava.net/xiaoxiaoleemin/comments/101612.html</wfw:comment><comments>http://www.blogjava.net/xiaoxiaoleemin/archive/2007/03/03/101612.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/xiaoxiaoleemin/comments/commentRss/101612.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/xiaoxiaoleemin/services/trackbacks/101612.html</trackback:ping><description><![CDATA[<h2></h2>
<p>Eclipse是一个开源软件项目，它的目标是提供最好的工具集成平台。Eclipse软件具有Common Public License，就是说你可以使用、修改其中的代码，可以重新发布为free版本，也可以作为私有项目的一部分。<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; Eclipse项目分为三个子项目：Eclipse项目，Tools项目和Technology 项目。<br>&nbsp;&nbsp;&nbsp; &nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Eclipse项目：主要包括Eclipse开发的核心组件，即Eclipse SDK，它用于支持平台或者框架的开发。Eclipse本身是用Java开发的，但是它可以用于实现其它语言的开发工具。Eclipse项目又分为三个子项目：Platform，JDT（Java Development Tools),PDE(Plugin Development Tools).基于这三个子项目足以任意扩展Eclpse框架或者开发其它工具。<br></p>
<ul>
    <li>Platform：Eclpse的核心组件。它提供了插件开发和工具集成所需要的框架和服务，比如标准的工作台用户界面，项目、文件和文件夹的管理机制等。
    <li>JDT是Java的集成开发环境，甚至可以用于开发Eclipse本身。
    <li>PDE为Eclipse插件提供view和editor。PDE建立在JDT的基础上并且进行了扩展，它支持一些非Java的插件开发活动，比如定义扩展点。 </li>
</ul>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Tools项目：Eclipse平台开发出来的各种为其它应用提供支持的工具。如CDT是一个实现C++集成开发环境的子项目，GEF是一个提供图形编辑功能的子项目，而EMF是一个由形式化模型定义转化为模型代码的子项目。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Technology项目：为关心Eclipse的研究员或者学术界人士提供机会。如XML Schema Infoset Model项目就是一个基于EMF的用于读取、操作XML Schema的库。<br>&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 下面介绍一下Eclipse项目的Platform子项目的几个重要特征：<br>&nbsp;&nbsp;&nbsp; （1）Plug-in体系结构：<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在Eclipse中，提供某个功能的基本单元或者构件成为插件（Plugin）。Eclipse平台以及在其上面扩展的其它一些工具都是由一系列插件组成。插件包括运行所需要的Java代码、图片文件、文本文件、名为Plugin.xml的Manifest文件等。plugin.xml声明了该插件与其它插件的关系：其中，Requires声明它的运行所依赖的其它插件；Exports声明它的公有类对其它插件的可见性；Extension Point声明了其它插件使用它的方式；Extensions声明它所使用的其它插件的扩展点。<br>&nbsp;&nbsp;&nbsp;&nbsp; Eclipse启动时先找到所有可用的插件，但是不全部启动。当真正需要某个插件的时候才为该插件分配自己的Class loader并运行插件，这种性质成为&#8220;Lazy Start&#8221;。<br>&nbsp;&nbsp;&nbsp; （2）工作台资源：<br>&nbsp;&nbsp;&nbsp; Eclipse中资源（resource）是指具有如下特性的任何文件或者文件夹：可以在上面注册Change Listener 以监听资源的变化；可以在上面添加错误信息或者TODO列表等Marker；可以跟踪其历史变化。Project是一类特殊的文件夹类型的资源，即文件系统中用户指定的一个文件夹。<br>&nbsp;&nbsp;&nbsp; （3）UI框架：<br>&nbsp;&nbsp;&nbsp; Eclipse的UI框架包括SWT和JFace，以及定义了整个EclipseIDE的整体结构的工作台界面。<br>
<ul>
    <li>&nbsp;SWT （Standard Widget Toolkit)是一个独立于操作系统的图形库，它尽可能多的调用操作系统的native widget。而Java的AWT只有List，Text Field和Button（各种操作系统下这些组件的外观类似）等底层组件是调用操作系统的，其它组件都是Swing自己模拟。所以AWT和Swing在不同的操作系统下开发出来的界面外观类似，导致与本地操作系统更个不协调。而SWT只有在操作系统没有native实现的情况下才自己模拟，因此开发的界面与本地操作系统风格一致。 <br>
    <li>&nbsp;JFace是用SWT实现的更高层次的工具集，负责图像字体的管理、对话框、向导、进度条等任务。JFace并没有像用户隐藏SWT的API，因此用户可以同时使用JFace和SWT。JFace的一个重要内容是提供标准的试图类，如 list，tree，table等组件的viewer，它们与SWT中的List，Tree，Table组件对应，只是从更高层次上显示数据。 Action Framework用来为菜单和工具条添加命令，是JFace的另一主要内容。
    <li>工作台是用户使用Eclipse的主窗口，由SWT和JFace实现。一个主窗口由一系列的view和editor组成。工作台上view和editor的位置可以自由排列，每种排列方式叫做一个Perspective。</li>
</ul>
<p>&#160;</p>
<h2></h2>
<img src ="http://www.blogjava.net/xiaoxiaoleemin/aggbug/101612.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xiaoxiaoleemin/" target="_blank">xiaoxiaoleemin</a> 2007-03-03 13:26 <a href="http://www.blogjava.net/xiaoxiaoleemin/archive/2007/03/03/101612.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>