eclipshine

          Eclipse主題站

          EMF中ResourceSet和Resource等的用法。(The EMF Persistence API)

          (此文大部分翻譯整理自Eclipse Modeling Framework: A Developer's Guild的13.2章)

          EMF Persistence API中主要涉及到4個(gè)接口Resource, ResourceSet, Resource.Factory以及URIconverter。雖然EMF提供了這些接口的缺省的XML序列化的實(shí)現(xiàn),但是也可以用這些API來(lái)實(shí)現(xiàn)其他的序列化方式,不論其是否是基于XML的,或者基于流的。

           

          URI用來(lái)表示某一類型的數(shù)據(jù),由三個(gè)部分組成:scheme, scheme-specific part以及可選的fragmentEMF提供了自己的URI的實(shí)現(xiàn)(而沒(méi)有用JDKURL):org.eclipse.emf.common.util.URI

          scheme部分表示了存取resource的協(xié)議,可以使標(biāo)準(zhǔn)的file,或者是jar。在eclipse中,使用platform來(lái)存取在workspace中的resource。例如:platform:/resource/project/po.xmlEMF也提供了EcoreUtil.getPlatformResourceMap(),來(lái)將一個(gè)platformURI轉(zhuǎn)換成標(biāo)準(zhǔn)的基于本地文件系統(tǒng)file協(xié)議的URI

          scheme-specific part的解釋會(huì)根據(jù)具體的scheme不同而不同,但是在EMF中,使用了一種通用的層次格式,這種格式包括autority, device,以及一系列的segmentsauthority//打頭。其它均由/打頭。

          fragment表示一個(gè)resource內(nèi)部的的一個(gè)部分。使用#來(lái)同其他部分分離。例如:file:/c:/dir1/dir2/myfile.xml#locEMF使用帶有fragmentURI來(lái)對(duì)resource中的EObject進(jìn)行引用。每一個(gè)EMF resource都有一個(gè)唯一的URI,而每一個(gè)resource中的對(duì)象,都有一個(gè)唯一的fragement來(lái)標(biāo)志它。

           

          URIConverter將一個(gè)輸入的URI轉(zhuǎn)換成一個(gè)resource的真實(shí)地URI。可以用來(lái)將一個(gè)namespace URI轉(zhuǎn)換成一個(gè)物理文件的URI,或者重定向到另外的一個(gè)老的URI上。

           

          Resource表示一個(gè)EObject的序列化容器,其實(shí)際地址由其URI所指定。Resource接口最重要的方法是save(), load()getEObject()以及getURIFragment()方法。save()load()方法在ResourceImpl中并沒(méi)有具體的處理裝載與保存的實(shí)現(xiàn),具體的處理是由storage-specificresource的子類完成的。

           

          Resourceunload()方法在某些時(shí)候也會(huì)很有用。它會(huì)將Resource中的所有對(duì)象都轉(zhuǎn)換為代理對(duì)象,使得后續(xù)的調(diào)用變成ondemand的調(diào)用,這能夠讓你得到最新的數(shù)據(jù)。如果底層的文件發(fā)生了改變的話。

           

          ResourcegetEObject()方法能夠使用一個(gè)對(duì)象的fragment來(lái)存取一個(gè)EObject。例如:

          Item item = (Item)resource.getEObject("http://@orders.0/@items.2");

          要得到一個(gè)對(duì)象的fragment也很容易,使用getURIFragment()方法即可:

          String fragment = resource.getURIFragment(item);

           

          Resource.Factory是用來(lái)創(chuàng)建Resource的。Resource.Factory是由一個(gè)注冊(cè)庫(kù)Registry來(lái)管理,定位的。一個(gè)Resource.Factory對(duì)應(yīng)于一類URI,而不是某一特定的URI。例如,缺省的registry允許你為一類的URI scheme或者extension注冊(cè)一個(gè)Resource.FactoryResource.Factory可以通過(guò)一個(gè)定義在Resource.Factory內(nèi)部的Descriptor來(lái)進(jìn)行注冊(cè)。Descriptor提供了創(chuàng)建Factory的方法。這里也是一個(gè)插件的擴(kuò)展點(diǎn),可以用來(lái)向系統(tǒng)中注冊(cè)新的Descriptor

           

          Registry可以用過(guò)其靜態(tài)的INSTANCE字段來(lái)訪問(wèn)其一個(gè)實(shí)例,缺省實(shí)現(xiàn)是ResourceFactoryRegistryImpl。它首先會(huì)根據(jù)URIscheme來(lái)檢查protocolToFactoryMap中的Factory,如果沒(méi)有找到,則使用URI的文件的擴(kuò)展名來(lái)檢查extensionToFactoryMap中是否有,如果人染沒(méi)有找到,則查找extensionToFactoryMapDEFAULT_EXTENSION(也就是*)。如果仍然沒(méi)有找到,則調(diào)用delegatedGetFactory(),允許你裝載一個(gè)自己的Factory Registry。當(dāng)找到一個(gè)Descriptor之后,調(diào)用其createFactory()來(lái)創(chuàng)建一個(gè)Factory

          下面的這個(gè)擴(kuò)展點(diǎn)是定義在org.eclipse.emf.ecore.xmi插件中的:

          <extension point = "org.eclipse.emf.ecore.extension_parser">

            <parser type="*"

               class="org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl"/>

          </extension>

          可以看到,XMIResourceFactoryImpl被作為缺省的ResourceFactory注冊(cè)了,因此在沒(méi)有其它的Factory被注冊(cè)的時(shí)候,將缺省使用XMIResourceFactoryImpl。你也同樣可以創(chuàng)建新的Resource實(shí)現(xiàn),以及對(duì)應(yīng)的Factory,并通過(guò)上面的擴(kuò)展點(diǎn)來(lái)進(jìn)行注冊(cè)。

           

          當(dāng)EMF運(yùn)行在非Eclipse環(huán)境下時(shí),缺省的擴(kuò)展點(diǎn)沒(méi)有被注冊(cè),則需要手工的注冊(cè):

          Resource.Factory.Registry.INSTANCE.

            getExtensionToFactoryMap().put("*", new XMIResourceFactoryImpl());

          Resource.FactoryResourceSet所使用來(lái)創(chuàng)建Resource

           

          一個(gè)ResourceSet代表了一個(gè)Resource的集合。提供了createResource()getResource(),以及getEObject()方法。createResource()創(chuàng)建一個(gè)新的,空的resourcegetResource()方法也同樣創(chuàng)建一個(gè)resource,但是會(huì)使用給定的URI來(lái)裝載這個(gè)Resource。用戶應(yīng)該始終調(diào)用ResourceSet的這兩個(gè)方法,而不是Resource的構(gòu)造函數(shù)或者Resource.FactorycreateResource()方法來(lái)創(chuàng)建一個(gè)Resource。這是因?yàn)?/SPAN>ResourceSet會(huì)保證相同的URI所對(duì)應(yīng)的Resource不會(huì)被裝載多次,而導(dǎo)致內(nèi)存中有相同的副本,并且,ResourceSet能夠自動(dòng)處理跨文檔的引用,而Resource卻不行。

           

          EMF中資源的保存與讀取,可以通過(guò)下面的兩個(gè)簡(jiǎn)單的代碼片斷來(lái)例示:

          裝載:

          ResourceSet resourceSet2 = new ResourceSetImpl();

          URI fileURI2 = URI.createFileURI(filepath);

          //Attention, The second parameter must be trur to get the resource for the first time.

          Resource poResource2 = resourceSet2.getResource(fileURI2, true);

           

          保存也很簡(jiǎn)單:

          URI fileURI = URI.createFileURI(filepath);

          Resource poResource = resourceSet.createResource(fileURI);

          poResource.getContents().add(model);

          try {

                 poResource.save(null);

          } catch (IOException e) {

                 assertTrue("IOException: " + e.getMessage(), false);

          }

          posted on 2005-08-07 09:51 Living Not Striving 閱讀(4870) 評(píng)論(5)  編輯  收藏 所屬分類: EMF

          評(píng)論

          # re: EMF中ResourceSet和Resource等的用法。(The EMF Persistence API) 2005-12-24 12:41 Jet Geng

          唉,我也在寫這樣的一篇文章。不過(guò)看到你已經(jīng)寫了。我的東西就沒(méi)有必要發(fā)出來(lái)。呵呵。
          不過(guò)找到有人可以一起學(xué)習(xí),挺happy。

            回復(fù)  更多評(píng)論   

          # re: EMF中ResourceSet和Resource等的用法。(The EMF Persistence API) 2006-05-26 16:19 bobby

          很好,先謝過(guò)  回復(fù)  更多評(píng)論   

          # re: EMF中ResourceSet和Resource等的用法。(The EMF Persistence API) 2006-07-06 23:02 ncainiao

          我想把resource的內(nèi)容寫成我自己定義格式的xml,怎么做呢?我只知道大概是要實(shí)現(xiàn)自己的doSave方法,那豈不是也要同時(shí)定義doLoad方法?

          沒(méi)有更好更優(yōu)雅的方法嗎?

          你有沒(méi)有這方面的例子?再補(bǔ)充補(bǔ)充:)  回復(fù)  更多評(píng)論   

          # 怎樣從emf編輯器中讀取現(xiàn)有的Resource的內(nèi)容那? 2007-05-30 21:25 cansen

          怎樣從emf編輯器中讀取現(xiàn)有的Resource的內(nèi)容那?謝謝  回復(fù)  更多評(píng)論   

          # re: EMF中ResourceSet和Resource等的用法。(The EMF Persistence API) 2007-07-17 18:04 autumn_it@163.com

          @ncainiao
          不是重寫doSave(),而是要重寫XMLHelperImpl和XMLSaveImpl。
          你可以自己寫一個(gè)實(shí)現(xiàn)繼承原有的實(shí)現(xiàn)類,然后改寫里面的部分方法,比如要改一對(duì)多的composition聯(lián)就改saveContainedMany().
          另外還要定義你自己的Resource,并注冊(cè)你需要的后綴。
          研究一下那幾個(gè)類的代碼就知道了  回復(fù)  更多評(píng)論   

          主站蜘蛛池模板: 织金县| 寿光市| 沅陵县| 常州市| 黑河市| 安宁市| 乌兰浩特市| 镇赉县| 邛崃市| 平远县| 轮台县| 巴楚县| 牟定县| 镇康县| 阳西县| 永兴县| 郓城县| 祁东县| 娄底市| 松滋市| 南康市| 肥城市| 平定县| 天气| 鹤庆县| 玉环县| 霍林郭勒市| 闵行区| 湄潭县| 无为县| 灵山县| 临洮县| 锡林郭勒盟| 油尖旺区| 通山县| 永平县| 桃园县| 大化| 府谷县| 芒康县| 长顺县|