白玉成的專欄

          Eclipse,讓我歡喜讓我憂!

            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
            17 隨筆 :: 0 文章 :: 6 評論 :: 0 Trackbacks
          在項目中用到EMF積累的一些基礎知識,希望對大家有所幫助。

            1. EMF core 除了生成modelmodel implementation外,至少還生成兩個接口:*Factory*Package。其中, Factory:生成實例的工廠;Package:提供一些靜態的constants(例如:被用來生成方法的feature constants     )和一些訪問模型元數據的公用方法。

           

          2. EMF生成的方法都帶有“@generated”標簽。EMF重新生成代碼時不會覆蓋用戶添加的方法(不帶有@generated)。

           

          3. 關于URIUniform Resource Identifier

          EMF 中是通過URI來標識package的,并且通過URI來唯一的確定resourcesURI包括三個部分:a scheme, a scheme-specific partan optional fragmentscheme主要決定了訪問

          資源的協議;比如:Platform:/resource/……中的platformscheme-specific part包含一些authority, device和一些segments,如file:/c:/dir1/dir2/myfile.xmlfile是協議,沒有authorityc:device,剩下的3個是segmentsURI fragment 標識了resource內部的某個具體的內容。如:file:/c:/dir1/dir2/myfile.xml#loc中的#loc EMF通過帶有fragmentURI來訪問資源中的EObjects

           

          4. 關于URIConverter

          URIConverter的作用是normalize一個輸入URI,使之成為一個實際的針對某個resourceURI。它可以把namespace URIs(比如:http:///com/example/epo2.ecore)映射到物理文件的URIs, 或者重定向舊的(或別名)的URI參考到一個具體的實際的location。一個URIConverter維護一個URIURI的映射集合。比如,把一個命名空間URI映射到物理文件:

          URIConverter converter = new URIConverterImpl();

          URI uri1 = URI.createURI("http:///somemodel.ecore");

          URI uri2 =URI.createURI("platform:/resource/project/somemodel.ecore");

          converter.getURIMap().put(uri1, uri2);

          在如下面代碼:

          URI normalized = converter.normalize(uri1);

          System.out.println(normalized);

          打印的結果是:platform:/resource/project/somemodel.ecore

          URIConverter.normalize()方法只是簡單的通過映射的mapkey替換成了相應的value

          URIConverter的最原始是應用在resource sets,用來定位resources.

           

          5. 關于ResourceResourceSet

          Resource 表示一個持久化的EOjbects的容器;ResourceSet表示一組Resource的集合,集合中的Resource同時創建或加載。Resource中比較重要的就是saveload方法,還有通過URI fragments訪問資源中的Object的機制,如:

          Resource resource =…

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

          Item item =…

          String fragment = resource.getURIFragment(item);

          上面代碼中的兩個方法,getEObject通過帶有fregmentURI獲得一個EObject,與之相反的方法getURIFragment()通過EObject獲得相應的fragment path

          ResourceSet中有些重要的方法:

          createResource()創建一個空的Resource

          getResource()通過resourceURI來創建Resource

          getEObject(),通過URI中的fregment來獲得具體的EObject對象。

           

          6. 關于Resource.Factory

          用來創建Resourceresource factory 要注冊到Registry實例中。一個factory 可以通過多種方式的URIs來注冊,包括URI scheme或者URIextension。在插件方式的應用中,通過擴展點的方式在插件加載的時候注冊descriptor。下面是Resource的源代碼

          public interface Resource extends Notifier

          {

          interface Factory

          {

          Resource createResource(URI uri);

          interface Descriptor

          {

          Factory createFactory();

          }

          interface Registry

          {

          Factory getFactory(URI uri);

          Map getProtocolToFactoryMap();

          String DEFAULT_EXTENSION = "*";

          Map getExtensionToFactoryMap();

          Registry INSTANCE = new ResourceFactoryRegistryImpl

          ();

          }

          }

          }

          下面是Registry中的getFactory()方法的算法(引用原文):

          1. Check for a factory in the protocolToFactoryMap, using

          the scheme of the URI.

          2. If nothing was found, check the extensionToFactoryMap

          using the file extension of the URI.

          3. If still nothing was found, check the

          extensionToFactoryMap using the DEFAULT_EXTENSION

          (that is, the wildcard character "*").

          4. If no extension match was found, call the

          delegatedGetFactory() method. This allows you to supply

          your own factory registry, with its own lookup

          criteria.

          5. If a descriptor was found, instead of an actual

          factory, call the createFactory() method on the

          descriptor to create the factory.

          6. Finally, return the factory if one was found, or null.

          tipemf缺省的序列化方式是XMI。因此,如果沒有找到相應注冊的factory缺省的就會返回以*注冊的缺省的factory,這個factory是針對XMIfactory,即XMIResourceFactoryImpl。如,對于XMIResourceFactoryImpl的擴展點聲明:

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

          <parser type="*" class="org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl"/>

          </extension>

          當非插件應用的時候,可以通過手工的方式來注冊factory,如:

          Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().put

          ("*", new XMIResourceFactoryImpl());

           

          7. Resource通過兩種方式實現XMLXMI

          1) XML

          實現Resource存儲的重要方法是save, 只有在方法eIsSet()返回true時,相關的屬性和引用才會被序列化到xml中。對于存儲的xml文件的格式可以通過設置OPTION_XML_MAP屬性來完成,如下面原文:

          There are several reasons why you might want to use OPTION_XML_MAP when saving a resource:

          1. You want to save your data so that it conforms to a particular XML Schema.

          2. You have changed your model, and you want the resource to produce XML documents that will work with the old version of the model.

          3. You want to design your own XML format without changing your model.

          2) XMI

          XMIXML基本相同,XMIResourceImpl就是

          XMLResourceImpl的簡單繼承,只是在引用objects時使用XMI IDs

          posted on 2008-11-25 22:26 白玉成 閱讀(521) 評論(0)  編輯  收藏 所屬分類: EMF

          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 龙海市| 贡山| 依兰县| 新建县| 永登县| 漠河县| 全州县| 遵义市| 麦盖提县| 三河市| 寻甸| 汉源县| 当雄县| 长武县| 当阳市| 分宜县| 山阴县| 普兰县| 林甸县| 高平市| 扶沟县| 阿瓦提县| 揭东县| 昌平区| 邛崃市| 墨竹工卡县| 广州市| 中宁县| 灵璧县| 郴州市| 台北县| 湖州市| 莱芜市| 什邡市| 韶关市| 大余县| 镇江市| 靖州| 壶关县| 汉阴县| 临邑县|