★emf 運(yùn)行時(shí)編程
★通過(guò)package和factory我們可以非常方便的取得class的metamodel信息,并且創(chuàng)建class instance。
★EClass,EPackage,EFactory提供了一些通用的方法,由此派生而來(lái)的class,package,factory則提供了更多便利的方法以供我們使用。
★訪問(wèn)指定的class除了通過(guò)package的getXxxx()方法之外,還可以取得那些沒(méi)有g(shù)enerated的class,其用法是XxxxPackage.getEClassifier("Yyyyy")。
★通過(guò)package,我們可以遍歷訪問(wèn)所有的class(以及attribute,reference,operation),datatype,enumeration
★訪問(wèn)package中所有的類(lèi)使用EPackage.getEClassifiers()方法,遍歷EClass所有屬性用EClass.getEAttributes()方法,遍歷reference用EClass.getEReferences()方法
★通過(guò)package創(chuàng)建制定類(lèi)實(shí)例的幾種做法:第一種就是使用XxxxPackage.createYyyy();第二種則是先通過(guò)XxxxPackage.eINSTANCE.getYyyyy()這種方式得到相關(guān)的實(shí)例類(lèi),以及XxxxFactory.eINSTANCE得到factory實(shí)例,最后使用xxxxFactory.create(yyyyClass)創(chuàng)建實(shí)例。
★通過(guò)一個(gè)給定的class name和相關(guān)的package uri創(chuàng)建類(lèi)實(shí)例,一般為了得到類(lèi)實(shí)例,我們需要得到class以及factory,而這些都可以通過(guò)package取得(通過(guò)getEClassifier()和getEFactoryInstance()方法)
★EPackage是對(duì)ecore xml文件的一個(gè)序列化對(duì)象,因此可以直接使用resouce,從一個(gè)ecore文件得到package對(duì)象,實(shí)際上這是一種比較底層的做法,通常我們不這樣做,而是通過(guò)使用Package的Registry來(lái)映射到給定uri的package對(duì)象,Registry從java.util.Map繼承而來(lái),通過(guò)uri跟一個(gè)Package或者Package.Discriptor關(guān)聯(lián),這里的Discriptor主要在plugin模式下使用,除非真的需要Package,否則在初始化的時(shí)候?qū)iscriptor注冊(cè)到Registry中。在需要使用Package的時(shí)候,則通過(guò)Discriptor來(lái)取得(通過(guò)調(diào)用其getEPackage()方法),通過(guò)EPackage ePackage = EPackage.Registry.INSTANCE.getEPackage(packageNsURI)方法,我得到了package,接著得到class name和factory以及最終所需要的class instance就易如反掌了。
★emf presistence framework
★emf的持久化機(jī)制主要圍繞4個(gè)接口:Resource,ResourceSet,Resource.Factory, URIConvertor。通過(guò)這4個(gè)接口便可以實(shí)現(xiàn)emf model的加載和保存
★URI 統(tǒng)一資源標(biāo)識(shí)是一個(gè)標(biāo)識(shí)和定義各種類(lèi)型(文件、網(wǎng)絡(luò)、數(shù)據(jù)庫(kù)、文件對(duì)象以及數(shù)據(jù)流)資源開(kāi)放標(biāo)準(zhǔn)。一個(gè)URI由三部分組成:scheme,scheme-specific以及fragment(可選)。org.eclipse.emf.common.util.URI是對(duì)URI的一種封裝,scheme標(biāo)識(shí)訪問(wèn)resource協(xié)議,文件為file,jar為jar,eclipse為platform
★file:/c:/dir1/dir2/myfile.xml和file:///c:/dir1/dir2/myfile.xml表示的資源是同一個(gè),但是卻是不同的URI對(duì)象
★scheme-specific由authority,device以及其他的segment組成,authority由//打頭,device和segment都是以/打頭,uri中從#開(kāi)始往后都是fragment
★emf使用帶有fragment的URI就可以引用到指定的EObject
★URIConvertor 用來(lái)將一個(gè)uri跟一個(gè)實(shí)際的uri建立映射關(guān)系,比如將一個(gè)namespace uri(http:///com/example/epo2.ecore)映射為一個(gè)物理uri(platform:/resource/project/somemodel.ecore),它還有一個(gè)功能就是normalize,也就是convert的意思,沒(méi)明白這個(gè)機(jī)制
★URIConvertor提供createInputStream() and createOutputStream()兩個(gè)方法,用來(lái)在制定的uri上打開(kāi)兩個(gè)input和output stream。
★Resouce表示一個(gè)EObject集合的持久容器,可以通過(guò)URI來(lái)進(jìn)行定位,Resource.getContents()的add方法向一個(gè)Resource添加一個(gè)EObject,也可以通過(guò)給容器類(lèi)型的關(guān)聯(lián)添加一個(gè)引用來(lái)給Resource添加一個(gè)EObject,Resource比較重要的是save()和load()方法,這兩個(gè)方法定義了持久化的格式,還有g(shù)etEObject()和getURIFragment()方法則用來(lái)使用URI查找對(duì)象
★save和load方法的實(shí)現(xiàn)機(jī)制:首先使用URIConvertor將指定的uri進(jìn)行轉(zhuǎn)換,然后打開(kāi)相應(yīng)的stream,接著調(diào)用doSave和doLoad方法,這些方法交給子類(lèi)去實(shí)現(xiàn),在save和load兩個(gè)方法調(diào)用中會(huì)傳一個(gè)map參數(shù),這個(gè)參數(shù)用來(lái)控制save和load的行為
★Resource.Factory 用來(lái)創(chuàng)建resoruce對(duì)象的,所有的factory都使用一個(gè)map的registry來(lái)加以管理,跟package的registry一樣的做法,不同之處它是根據(jù)uri scheme以及extension來(lái)進(jìn)行分類(lèi)注冊(cè)的。在plugin中默認(rèn)情況下所有的emf model都使用XMIResourceFactoryImpl,如果要自定義factory,可以通過(guò)添加擴(kuò)展點(diǎn)org.eclipse.emf.ecore.extension_parser,并指定自己的factory實(shí)現(xiàn),一般情況下resource factory只是用來(lái)給resourceset來(lái)使用
★ResourceSet 用來(lái)管理已經(jīng)load和create的resource集合,主要使用createResource(),getResource(),getEObject()這幾個(gè)方法。createResource()用于在set中創(chuàng)建一個(gè)空的resource對(duì)象,getResource()也會(huì)先創(chuàng)建一個(gè)Resource,然后用指定的resource URI去加載指定的resource,getEObject()則在已有的resource(或者根據(jù)uri調(diào)用getResource()方法先加載resource)中根據(jù)需要加載EObject,
★除了可以直接通過(guò)new以及resource.factory的createResource()方法來(lái)創(chuàng)建resource對(duì)象之外,也可以通過(guò)調(diào)用ResourceSet的getResource() and createResource()方法來(lái)創(chuàng)建(其內(nèi)部會(huì)調(diào)用resource.factory的相應(yīng)方法),這樣做的一個(gè)重要原因是它能夠跟蹤某個(gè)uri是否已經(jīng)被打開(kāi),這樣可以避免內(nèi)存里面出現(xiàn)兩份一樣的resource,resource set還可以按需加載當(dāng)前resource對(duì)另外一個(gè)resource的引用
★使用ResourceSet的時(shí)候需要resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap().put(Resource.Factory.Registry.DEFAULT_EXTENSION,new XMIResourceFactoryImpl());這樣設(shè)置一把,否則會(huì)因?yàn)檎也坏絩sourceFactory而無(wú)法使用resource
★
★emf resource implementation
★在生成一對(duì)一的屬性的時(shí)候,會(huì)在當(dāng)前節(jié)點(diǎn)上以attribute的形式添加
★在生成一對(duì)多的屬性的時(shí)候,會(huì)在當(dāng)前節(jié)點(diǎn)中以子節(jié)點(diǎn)的方式添加屬性
★在生成包含關(guān)系的引用的時(shí)候,會(huì)在當(dāng)前節(jié)點(diǎn)中以子節(jié)點(diǎn)的方式添加引用節(jié)點(diǎn)
★在生成非包含關(guān)系的引用的時(shí)候,會(huì)在當(dāng)前節(jié)點(diǎn)中以attribute的形式引用子節(jié)點(diǎn)的fragment,但是如果設(shè)置在被包含引用的iD屬性的話,則采用id的方式加以引用。
★在創(chuàng)建交叉引用的時(shí)候需要把resource的save放在所有resource生成之后。交叉引用可以使用相對(duì)路徑也可以使用絕對(duì)路徑,但是相對(duì)路徑更好一些,因?yàn)榭梢浦残愿茫龅绞褂孟鄬?duì)路徑引用,則需要在創(chuàng)建resource的時(shí)候使用絕對(duì)uri路徑
★如果引用存在繼承關(guān)系,那么對(duì)于引用的具體子類(lèi),會(huì)在生成的xml中添加xmi:type屬性來(lái)表明具體引用的是哪個(gè)子類(lèi)
★
★xml輸出的定制
★OPTION_DECLARE_XML為false標(biāo)識(shí)沒(méi)有xml頭聲明
★OPTION_LINE_WIDTH好像沒(méi)有效果
★OPTION_USE_ENCODED_ATTRIBUTE_STYLE 為true則總是使用uri方式來(lái)進(jìn)行引用
★OPTION_SKIP_ESCAPE為true(默認(rèn)為true)表示針對(duì)轉(zhuǎn)義字符(<,>,&)進(jìn)行轉(zhuǎn)換
★OPTION_XML_MAP 用來(lái)將制定的節(jié)點(diǎn)內(nèi)容進(jìn)行轉(zhuǎn)換
★OPTION_ENCODING為xml設(shè)置字符集
★xml輸入定制
★OPTION_DISABLE_NOTIFY 為true取消觸發(fā)通知
★OPTION_XML_MAP 在save的時(shí)候使用了OPTION_XML_MAP,那么在load的時(shí)候也要使用
★
★adapter編程
★給一個(gè)model object添加一個(gè)adapter有三種方式:第一種通過(guò)model object的eAdapters屬性將一個(gè)adapter跟model關(guān)聯(lián)起來(lái);第二種通過(guò)adapter factory的adapt方法將一個(gè)adapter與一個(gè)model object關(guān)聯(lián)起來(lái);第三種通過(guò)擴(kuò)展已有的adapter factory創(chuàng)建制定類(lèi)型的adapter來(lái)與model object關(guān)聯(lián)。
★Notification用來(lái)封裝通知信息,這里除了getNotifier()方法返回通知的發(fā)送者之外,還包括通知的類(lèi)型,發(fā)生改變的feature(即 feature id),改動(dòng)前后的值,如果需要屏蔽掉非狀態(tài)改變的通知,則可以使用isTouch()方法來(lái)實(shí)現(xiàn)。
★通過(guò)adapter除了可以給一個(gè)model object添加一個(gè)監(jiān)聽(tīng)器之外,還可以用來(lái)給model object增加一些功能。其做法是先定義一個(gè)需要實(shí)現(xiàn)功能的接口,然后實(shí)現(xiàn)該接口并擴(kuò)展AdapterImpl實(shí)現(xiàn)一個(gè)Adapter,并創(chuàng)建一個(gè)adapter factory來(lái)負(fù)責(zé)創(chuàng)建該adapter,最后通過(guò)adapter factory的adapt()方法將model object與前面定義的接口關(guān)聯(lián)起來(lái),這樣model object就被擴(kuò)展成具有該接口的一些功能了。
★通過(guò)package和factory我們可以非常方便的取得class的metamodel信息,并且創(chuàng)建class instance。
★EClass,EPackage,EFactory提供了一些通用的方法,由此派生而來(lái)的class,package,factory則提供了更多便利的方法以供我們使用。
★訪問(wèn)指定的class除了通過(guò)package的getXxxx()方法之外,還可以取得那些沒(méi)有g(shù)enerated的class,其用法是XxxxPackage.getEClassifier("Yyyyy")。
★通過(guò)package,我們可以遍歷訪問(wèn)所有的class(以及attribute,reference,operation),datatype,enumeration
★訪問(wèn)package中所有的類(lèi)使用EPackage.getEClassifiers()方法,遍歷EClass所有屬性用EClass.getEAttributes()方法,遍歷reference用EClass.getEReferences()方法
★通過(guò)package創(chuàng)建制定類(lèi)實(shí)例的幾種做法:第一種就是使用XxxxPackage.createYyyy();第二種則是先通過(guò)XxxxPackage.eINSTANCE.getYyyyy()這種方式得到相關(guān)的實(shí)例類(lèi),以及XxxxFactory.eINSTANCE得到factory實(shí)例,最后使用xxxxFactory.create(yyyyClass)創(chuàng)建實(shí)例。
★通過(guò)一個(gè)給定的class name和相關(guān)的package uri創(chuàng)建類(lèi)實(shí)例,一般為了得到類(lèi)實(shí)例,我們需要得到class以及factory,而這些都可以通過(guò)package取得(通過(guò)getEClassifier()和getEFactoryInstance()方法)
★EPackage是對(duì)ecore xml文件的一個(gè)序列化對(duì)象,因此可以直接使用resouce,從一個(gè)ecore文件得到package對(duì)象,實(shí)際上這是一種比較底層的做法,通常我們不這樣做,而是通過(guò)使用Package的Registry來(lái)映射到給定uri的package對(duì)象,Registry從java.util.Map繼承而來(lái),通過(guò)uri跟一個(gè)Package或者Package.Discriptor關(guān)聯(lián),這里的Discriptor主要在plugin模式下使用,除非真的需要Package,否則在初始化的時(shí)候?qū)iscriptor注冊(cè)到Registry中。在需要使用Package的時(shí)候,則通過(guò)Discriptor來(lái)取得(通過(guò)調(diào)用其getEPackage()方法),通過(guò)EPackage ePackage = EPackage.Registry.INSTANCE.getEPackage(packageNsURI)方法,我得到了package,接著得到class name和factory以及最終所需要的class instance就易如反掌了。
★emf presistence framework
★emf的持久化機(jī)制主要圍繞4個(gè)接口:Resource,ResourceSet,Resource.Factory, URIConvertor。通過(guò)這4個(gè)接口便可以實(shí)現(xiàn)emf model的加載和保存
★URI 統(tǒng)一資源標(biāo)識(shí)是一個(gè)標(biāo)識(shí)和定義各種類(lèi)型(文件、網(wǎng)絡(luò)、數(shù)據(jù)庫(kù)、文件對(duì)象以及數(shù)據(jù)流)資源開(kāi)放標(biāo)準(zhǔn)。一個(gè)URI由三部分組成:scheme,scheme-specific以及fragment(可選)。org.eclipse.emf.common.util.URI是對(duì)URI的一種封裝,scheme標(biāo)識(shí)訪問(wèn)resource協(xié)議,文件為file,jar為jar,eclipse為platform
★file:/c:/dir1/dir2/myfile.xml和file:///c:/dir1/dir2/myfile.xml表示的資源是同一個(gè),但是卻是不同的URI對(duì)象
★scheme-specific由authority,device以及其他的segment組成,authority由//打頭,device和segment都是以/打頭,uri中從#開(kāi)始往后都是fragment
★emf使用帶有fragment的URI就可以引用到指定的EObject
★URIConvertor 用來(lái)將一個(gè)uri跟一個(gè)實(shí)際的uri建立映射關(guān)系,比如將一個(gè)namespace uri(http:///com/example/epo2.ecore)映射為一個(gè)物理uri(platform:/resource/project/somemodel.ecore),它還有一個(gè)功能就是normalize,也就是convert的意思,沒(méi)明白這個(gè)機(jī)制
★URIConvertor提供createInputStream() and createOutputStream()兩個(gè)方法,用來(lái)在制定的uri上打開(kāi)兩個(gè)input和output stream。
★Resouce表示一個(gè)EObject集合的持久容器,可以通過(guò)URI來(lái)進(jìn)行定位,Resource.getContents()的add方法向一個(gè)Resource添加一個(gè)EObject,也可以通過(guò)給容器類(lèi)型的關(guān)聯(lián)添加一個(gè)引用來(lái)給Resource添加一個(gè)EObject,Resource比較重要的是save()和load()方法,這兩個(gè)方法定義了持久化的格式,還有g(shù)etEObject()和getURIFragment()方法則用來(lái)使用URI查找對(duì)象
★save和load方法的實(shí)現(xiàn)機(jī)制:首先使用URIConvertor將指定的uri進(jìn)行轉(zhuǎn)換,然后打開(kāi)相應(yīng)的stream,接著調(diào)用doSave和doLoad方法,這些方法交給子類(lèi)去實(shí)現(xiàn),在save和load兩個(gè)方法調(diào)用中會(huì)傳一個(gè)map參數(shù),這個(gè)參數(shù)用來(lái)控制save和load的行為
★Resource.Factory 用來(lái)創(chuàng)建resoruce對(duì)象的,所有的factory都使用一個(gè)map的registry來(lái)加以管理,跟package的registry一樣的做法,不同之處它是根據(jù)uri scheme以及extension來(lái)進(jìn)行分類(lèi)注冊(cè)的。在plugin中默認(rèn)情況下所有的emf model都使用XMIResourceFactoryImpl,如果要自定義factory,可以通過(guò)添加擴(kuò)展點(diǎn)org.eclipse.emf.ecore.extension_parser,并指定自己的factory實(shí)現(xiàn),一般情況下resource factory只是用來(lái)給resourceset來(lái)使用
★ResourceSet 用來(lái)管理已經(jīng)load和create的resource集合,主要使用createResource(),getResource(),getEObject()這幾個(gè)方法。createResource()用于在set中創(chuàng)建一個(gè)空的resource對(duì)象,getResource()也會(huì)先創(chuàng)建一個(gè)Resource,然后用指定的resource URI去加載指定的resource,getEObject()則在已有的resource(或者根據(jù)uri調(diào)用getResource()方法先加載resource)中根據(jù)需要加載EObject,
★除了可以直接通過(guò)new以及resource.factory的createResource()方法來(lái)創(chuàng)建resource對(duì)象之外,也可以通過(guò)調(diào)用ResourceSet的getResource() and createResource()方法來(lái)創(chuàng)建(其內(nèi)部會(huì)調(diào)用resource.factory的相應(yīng)方法),這樣做的一個(gè)重要原因是它能夠跟蹤某個(gè)uri是否已經(jīng)被打開(kāi),這樣可以避免內(nèi)存里面出現(xiàn)兩份一樣的resource,resource set還可以按需加載當(dāng)前resource對(duì)另外一個(gè)resource的引用
★使用ResourceSet的時(shí)候需要resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap().put(Resource.Factory.Registry.DEFAULT_EXTENSION,new XMIResourceFactoryImpl());這樣設(shè)置一把,否則會(huì)因?yàn)檎也坏絩sourceFactory而無(wú)法使用resource
★
★emf resource implementation
★在生成一對(duì)一的屬性的時(shí)候,會(huì)在當(dāng)前節(jié)點(diǎn)上以attribute的形式添加
★在生成一對(duì)多的屬性的時(shí)候,會(huì)在當(dāng)前節(jié)點(diǎn)中以子節(jié)點(diǎn)的方式添加屬性
★在生成包含關(guān)系的引用的時(shí)候,會(huì)在當(dāng)前節(jié)點(diǎn)中以子節(jié)點(diǎn)的方式添加引用節(jié)點(diǎn)
★在生成非包含關(guān)系的引用的時(shí)候,會(huì)在當(dāng)前節(jié)點(diǎn)中以attribute的形式引用子節(jié)點(diǎn)的fragment,但是如果設(shè)置在被包含引用的iD屬性的話,則采用id的方式加以引用。
★在創(chuàng)建交叉引用的時(shí)候需要把resource的save放在所有resource生成之后。交叉引用可以使用相對(duì)路徑也可以使用絕對(duì)路徑,但是相對(duì)路徑更好一些,因?yàn)榭梢浦残愿茫龅绞褂孟鄬?duì)路徑引用,則需要在創(chuàng)建resource的時(shí)候使用絕對(duì)uri路徑
★如果引用存在繼承關(guān)系,那么對(duì)于引用的具體子類(lèi),會(huì)在生成的xml中添加xmi:type屬性來(lái)表明具體引用的是哪個(gè)子類(lèi)
★
★xml輸出的定制
★OPTION_DECLARE_XML為false標(biāo)識(shí)沒(méi)有xml頭聲明
★OPTION_LINE_WIDTH好像沒(méi)有效果
★OPTION_USE_ENCODED_ATTRIBUTE_STYLE 為true則總是使用uri方式來(lái)進(jìn)行引用
★OPTION_SKIP_ESCAPE為true(默認(rèn)為true)表示針對(duì)轉(zhuǎn)義字符(<,>,&)進(jìn)行轉(zhuǎn)換
★OPTION_XML_MAP 用來(lái)將制定的節(jié)點(diǎn)內(nèi)容進(jìn)行轉(zhuǎn)換
★OPTION_ENCODING為xml設(shè)置字符集
★xml輸入定制
★OPTION_DISABLE_NOTIFY 為true取消觸發(fā)通知
★OPTION_XML_MAP 在save的時(shí)候使用了OPTION_XML_MAP,那么在load的時(shí)候也要使用
★
★adapter編程
★給一個(gè)model object添加一個(gè)adapter有三種方式:第一種通過(guò)model object的eAdapters屬性將一個(gè)adapter跟model關(guān)聯(lián)起來(lái);第二種通過(guò)adapter factory的adapt方法將一個(gè)adapter與一個(gè)model object關(guān)聯(lián)起來(lái);第三種通過(guò)擴(kuò)展已有的adapter factory創(chuàng)建制定類(lèi)型的adapter來(lái)與model object關(guān)聯(lián)。
★Notification用來(lái)封裝通知信息,這里除了getNotifier()方法返回通知的發(fā)送者之外,還包括通知的類(lèi)型,發(fā)生改變的feature(即 feature id),改動(dòng)前后的值,如果需要屏蔽掉非狀態(tài)改變的通知,則可以使用isTouch()方法來(lái)實(shí)現(xiàn)。
★通過(guò)adapter除了可以給一個(gè)model object添加一個(gè)監(jiān)聽(tīng)器之外,還可以用來(lái)給model object增加一些功能。其做法是先定義一個(gè)需要實(shí)現(xiàn)功能的接口,然后實(shí)現(xiàn)該接口并擴(kuò)展AdapterImpl實(shí)現(xiàn)一個(gè)Adapter,并創(chuàng)建一個(gè)adapter factory來(lái)負(fù)責(zé)創(chuàng)建該adapter,最后通過(guò)adapter factory的adapt()方法將model object與前面定義的接口關(guān)聯(lián)起來(lái),這樣model object就被擴(kuò)展成具有該接口的一些功能了。
安徽新華電腦學(xué)校專(zhuān)業(yè)職業(yè)規(guī)劃師為你提供更多幫助【在線咨詢(xún)】