有關(guān)另外一個WTP重要的數(shù)據(jù)模型IStructuredDocument已經(jīng)在前面介紹過了,今天我們看一下另外一個核心的數(shù)據(jù)模型IStructuredModel。在繼續(xù)下面的內(nèi)容之前,請確保當前工作區(qū)中已經(jīng)導入(無論是源碼方式導入還是二進制方式導入)了如下工程: org.eclipse.jst.jsp.core org.eclipse.jst.jsp.ui org.eclipse.wst.css.core org.eclipse.wst.css.ui org.eclipse.wst.html.core org.eclipse.wst.html.ui org.eclipse.wst.javascript.core org.eclipse.wst.javascript.ui org.eclipse.wst.sse.core org.eclipse.wst.sse.ui org.eclipse.wst.xml.core org.eclipse.wst.xml.ui 在前面介紹IStructuredDocument的時候,我們知道IStructuredDocument的具體實現(xiàn)其實就是JFace Text Framework中IDocument接口的具體實現(xiàn),其核心作用也集中在將特定文本按照特定的語法規(guī)則進行區(qū)域劃分,提供相應的位置信息,這為WTP頁面資源編輯器建立了核心數(shù)據(jù)模型。但是,單純擁有偏重于語法的IStrucuturedDocument是不夠的,我們同時還需要另外一套偏重于語義的數(shù)據(jù)模型,這就是IStructuredModel和其背后的WTP xml DOM實現(xiàn)(說明:對于CSS模型,是完全由WTP自己實現(xiàn)的,和本系列文章關(guān)系不大,本篇中不做詳細介紹)。 注意:IStructuredModel以IStrucuturedDocument為基礎(chǔ)構(gòu)建,IStructuredDocument并不知道IStructuredModel,但是IStructuredModel知道該模型對應的IStrucuturedDocument!!! 現(xiàn)在先大致猜測一下原因,如果是直接將特定頁面資源的內(nèi)容直接轉(zhuǎn)換為IStructuredModel肯定不容易,因為我們頁面資源中的內(nèi)容往往不是那么規(guī)則,那轉(zhuǎn)化的過程中肯定避免不了自己去做大量的解析,導致構(gòu)建IStructuredModel構(gòu)建過程異常復雜;如果利用已有的IStrucuturedDocument構(gòu)建機制,先將特定的內(nèi)容解析為IStrucuturedDocument完成語法劃分,再基于高度結(jié)構(gòu)化的IStrucuturedDocument去構(gòu)建IStrucuturedModel,那肯定會大大簡化構(gòu)建過程,某種程度上就可以將構(gòu)建過程理解為把IStrucuturedDocument中節(jié)點列表轉(zhuǎn)換為IStrucuturedModel持有的Document對應的節(jié)點列表了。IStructuredModel構(gòu)建過程大致示意如下: 【IStructuredModel:句柄】 為什么說IStucturedModel是句柄呢,其實模型本身的信息并不是IStucturedModel角色在承擔,而是每個IStructuredModel都持有對應的一個document。上圖顯示了IStrucuturedModel有兩種實現(xiàn):IDOMModel和ICSSModel,IDOMModel持有的是一個IDOMDocument,而ICSSModel持有的是一個ICSSDocument。真正持有模型節(jié)點信息的是IDOMDocument或者ICSSDocument,所以很大程度上我們可以將IStucturedModel理解為句柄(也不完全是這樣,大致這么理解是為了更好的搞清楚這幾者之間的關(guān)系^_^)。 【IStructuredModel構(gòu)建過程進一步分析】 有了上面的解釋我們應該清楚了,我們是基于IStructuredDocument語法劃分的基礎(chǔ)上建立起了對應的IDOMDocument或者ICSSDoucment,IStructuredModel持有對應的IDOMDocument或者ICSSDocument(當然,同時也會持有對應的IStructuredDocument)。所以到這里,我們可以稍微修正一下上面IStructuredModel構(gòu)造流程圖: 通過上面兩幅圖,語法Document(IStructuredDocument)、語義Document(IDOMDocument或者ICSSDocument)、WTP模型(IStructuredModel)三者的關(guān)系應該更加清楚了吧^_^,后門我會再抽一節(jié)來總結(jié)和分析一下之間的關(guān)系。在我們的真是應用中,語義Document(IDOMDocument或者ICSSDocument)一般在分析模型信息的時候才會用到,平時不會直接接觸到,所以我前面將IStructuredDocument稱之為WTP Document,將IStructuredModel稱之為WTP Model,壓根就沒提IDOMDocument或者ICSSDocument。 【IStructuredModel提供的核心操作】 1、模型管理相關(guān)的操作(十分重要): getModelManager:獲取模型管理器(關(guān)于這個概念的信息闡述,到會放到后門的章節(jié)中) getReferenceCount:獲取被模型的引用計數(shù)(和IModelManager的引用計數(shù)管理相關(guān)) getReferenceCountForEdit:獲取可寫方式的引用計數(shù) getReferenceCountForRead:獲取只讀方式的引用計數(shù) isShared:判斷該模型是否被IModelManager托管了,就是是否共享了 isSharedForEdit:本質(zhì)上是判斷該模型的只讀引用計數(shù)是否為零,是否被以只讀方式引用了 isSharedForRead:本質(zhì)上是判斷該模型的可寫引用計數(shù)是否為零,是否被以可寫方式引用了 releaseFromRead:減少只讀方式的引用計數(shù) releaseFromEdit:減少可寫方式的引用計數(shù) 以上這些操作都是和一個重要的角色IModelManger相關(guān),后門的章節(jié)中會詳細闡述!!! 2、相關(guān)監(jiān)聽器操作(IModelStateListener非常常用): addModelLifecycleListener:我們使用較少,處理模型生命周期事件,詳細信息參見org.eclipse.wst.sse.core.internal.model.ModelLifecycleEvent和org.eclipse.wst.sse.core.internal.provisional.IModelLifecycleListener addModelStateListener:我們使用較多,用于模型狀態(tài)變化監(jiān)聽,我們下一節(jié)在開發(fā)Structured Model分析視圖時候就會用到。詳細信息參加org.eclipse.wst.sse.core.internal.provisional.IModelStateListener 3、訪問語法Document和語義Document(很常用!!!): IStructuredDocument getStructuredDocument:獲取語法Document IDOMDocument getDocument:定義在IStructuredModel的子類型IDOMModel中 ICSSDocument getDocument:定義在IStructuredModel的子類型ICSSModel中 IndexedRegion getIndexedRegion(int offset):根據(jù)位置定位對應語義Document(IDOMDocument或者ICSSDocument)中對應的節(jié)點,返回結(jié)果是一個IDOMNode或者ICSSNode 4、自身狀態(tài)相關(guān)操作(也較為常用): isDirty() isSaveNeeded() save() save(EncodingRule encodingRule) save(IFile iFile) save(IFile iFile, EncodingRule encodingRule) save(OutputStream outputStream) IStructuredModel reinit() IStructuredModel reload(InputStream inputStream) 5、其他幾個重要操作 String getBaseLocation():獲取本模型對應資源的位置信息。注意:某種程度上,IStructuredModel是面向資源文件的,而語法Doucment或者語義Document則不是,要注意其中的區(qū)別!!! ...其他的幾個以后用到的時候再說!!! 6、recording相關(guān)操作,我們后面不會直接用到此特性,不做闡述 【IDOMModel核心操作】 IDOMDocument getDocument就是它的核心操作,上面已經(jīng)說過。 【IndexedRegion:WTP語義Document的Node】 如果將IStructuredDocument視為WTP的語法Document,則可以將IStructuredModel視為WTP模型,IDOMDocument或ICSSDocument視為WTP語義Document。而這個語義Document的中節(jié)點的超類型則就是IndexedRegion(org.eclipse.wst.sse.core.internal.provisional.IndexedRegion),IDOMDocument或ICSSDocument不過是其中兩種節(jié)點類型(這個熟悉xml的朋友肯定知道了,xml Document本身就是一個xml Node)。首先來看一下IndexedRegion的類型體系圖: 說明:IDOMNode繼承自IndexedRegion接口,而ICSSNode并不是,看起來有點不自然^_^。那我們就把他們合并起來吧,來個全家福: 從上面的類型體系我們可以看的出來,IndexedRegion主要分為兩類:一類是dom node(org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode),另一類是css node(org.eclipse.wst.css.core.internal.provisional.document.ICSSNode,這邊用接口更舒服點^_^)。WTP在實現(xiàn)dom node系列時,借助于org.w3c.dom節(jié)點體系,這也是我們后面接觸最多的;WTP在實現(xiàn)css node的時候,則和org.w3c.dom沒有任何關(guān)系,完全是自己構(gòu)建節(jié)點體系。 【IndexedRegion接口主要操作】 上面看了IndexedRegion主要分為兩類,那么我們再回過頭看一下IndexedRegion提供的核心操作: 我們看到IndexedRegion提供的核心操作都是關(guān)于位置信息的。這可能會產(chǎn)生一些疑問,例如位置信息的計算是不是挺繁瑣的呢?怎么實現(xiàn)的呢? 我們回顧一下前面在分析IStructuredDocument的時候,我們ITextRegion接口(IStructuredDocument中節(jié)點的超類型)提供的核心操作之一就是提供位置信息。如果我們的每個IndexRegion節(jié)點都持有相關(guān)的ITextRegion節(jié)點不就可以了???確實是這么做的。這和我們這篇文章開頭說的是一直的,基于語義的IStructuredModel(實際上是構(gòu)造背后的IDOMDocument和ICSSDocument)構(gòu)建的基礎(chǔ)是基于語法的IStructuredDocument。 那么現(xiàn)在如果我們有了位置信息(例如編輯器中的光標的offset),我們就可以把WTP Doucment中的ITextRegion和WTP Model中的IndexedRegion(IDOMNode、ICSSNode)聯(lián)系起來了。 【IDOMNode:IndexRegion的XML DOM實現(xiàn)】 絕大部分頁面資源的語義Document都是基于IDOMNode的,我們就介紹它^_^。首先來看一副圖片,可以和前面第三節(jié)介紹IStructuredDocument時用的圖片做一個比較: 可以看到,IStructuredDocument的text region的劃分是基于語法的,只要是一個閉合區(qū)域就是一個IStructuredDocumentRegion;IDOMDocument中的indexed region是基于語義劃分的,看上圖就可以看的出來,element之間都是有父子掛系的,再看一下一個dom attr區(qū)域是由三個text region組成的。 具體差異,后門的章節(jié)中會分析。 前面說過了,WTP model中的節(jié)點IndexedRegion有兩種實現(xiàn):一種是基于xml dom的IDOMNode,另外一種是WTP完全自己實現(xiàn)的ICSSNode,這里重點介紹IDOMNode(org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode)。有一點一定要記住:IDOMNode同時是一個w3c xml Node。 說明:既然遵守了w3c xml dom協(xié)議,那么我們的一個IDOMDocument本質(zhì)上就是一個dom document,那這個dom對象肯定非常耗內(nèi)存了。是的,IDOMDocument絕對是個重量級對象,但是選擇dom還是有原因的:一可以提供較為豐富的語義;再者,一個頁面資源的大小通常不會太大,也就是說一般不會產(chǎn)生非常巨大的DOM對象(例如大于10M)。 這其實和我們在日常應用中選擇基于DOM的還是基于流的XML解析技術(shù)一樣,要求語義是否豐富、對應的xml對象內(nèi)存占用是兩個重要的考慮。 為了dom對象耗內(nèi)存的缺點降低到最低,和通常的解決辦法一樣,WTP也提供了模型緩存管理功能,也就是后面我們要說的IModelManager,對IStructuredModel進行引用計數(shù)管理(我們的IDOMDocument這個大dom對象會被IStructuredModel持有)。 【IDOMNode核心操作】 圖中可以看的出來,我們的IDOMNode有兩個超類型:IndexedRegion和org.w3c.dom.Node,我們的IDOMNode就提供了三類主要的操作: 1、IndexedRegion相關(guān)操作:提供位置相關(guān)信息的操作 2、org.w3c.dom.Node相關(guān)的操作:dom node相關(guān)操作(注意:有些dom node中規(guī)定的部分操作,WTP并沒有實現(xiàn),這些操作對WTP來說意義不大,畢竟一個頁面資源并不完全是一個xml文件哈^_^) 3、IDOMNode接口自身定義的操作。這又可以大致分為三類: A、語法Document(IStructuredDocument)相關(guān)操作 IStructuredDocument getStructuredDocument IStructuredDocumentRegion getStartStructuredDocumentRegion IStructuredDocumentRegion getEndStructuredDocumentRegion IStructuredDocumentRegion getFirstStructuredDocumentRegion IStructuredDocumentRegion getLastStructuredDocumentRegion 有了以上操作,我們就可以從語法和語義兩個層面來綜合分析一個節(jié)點了 B、獲取WTP 模型(IDOMModel) IDOMModel getModel() C、內(nèi)容設置相關(guān)操作 getSource:獲取節(jié)點內(nèi)容 setSource:設置節(jié)點內(nèi)容 getValueSource:獲取value內(nèi)容 setValueSource:設置value內(nèi)容 setEditable setDataEditable setChildEditable isDataEditable isChildEditable D、其他操作,不常用,就不列舉了 【···說明···】 IDOMNode相關(guān)的子接口類型也是常用的,里面都有對應的操作,可以幫助我們更好地操作語義Document,進行語義層面的分析。相關(guān)要熟練了解使用的接口為: org.eclipse.wst.xml.core.internal.provisional.document.IDOMAttr org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement org.eclipse.wst.xml.core.internal.provisional.document.IDOMText 如果不了解XML DOM的,最好也稍微了解一下,對操作語義Document有很大幫助。 【ICSSNode:IndexRegion的CSS實現(xiàn)】 我們后面基本用不到,因為我們基本上不去單獨分析css資源,就不在本系列文章中去講了。如果要分析ICSSNode,則可以參照分析IDOMNode的實現(xiàn),祝好運^_^ 【后記】 我們這一節(jié)分析了WTP語義Document(IDOMDocument)和WTP模型(IStructuredModel),下一節(jié)會首先來開發(fā)一個類似于上一節(jié)中的分析視圖:DOM Document分析視圖。然后會單獨拿出一節(jié)來分析這些重要概念之間的關(guān)系,同時會突出強調(diào)org.eclipse.wst.sse.core.internal.provisional.IModelManager. 到這里,WTP最重要的數(shù)據(jù)模型已經(jīng)介紹完畢了,如下: 語法Document:IStructuredDocument 語義Document:重點介紹了IDOMDocument WTP模型:IStructuredModel(重點介紹了IDOMModel) 【模塊關(guān)系】 借住于上面的分析過程,到現(xiàn)在我們對開頭提到的幾個插件的體系結(jié)構(gòu)應該有了一定的認識了: WTP我們常接觸的是WST、JST、RDB三個組成部分,RDB是專門來處理數(shù)據(jù)庫相關(guān)的,本系列文章中不做討論。JST的基礎(chǔ)是WST,看上圖中就可以發(fā)現(xiàn),JSP類型的模型都需要基于WST中各種類型的模型,能不是基礎(chǔ)嗎。從語義上也講的通哈,沒有css、html、javascript、xml這些東東,怎么能建立起jsp呢??? 再回顧文章開頭我們列舉的12個插件工程,結(jié)合Eclipse的“分層法則”,12個插件工程之間的關(guān)系應該很清楚了吧...
本博客中的所有文章、隨筆除了標題中含有引用或者轉(zhuǎn)載字樣的,其他均為原創(chuàng)。轉(zhuǎn)載請注明出處,謝謝!
posted on 2008-09-09 18:03 zhuxing 閱讀(2939) 評論(3) 編輯 收藏 所屬分類: Eclipse Plug-in & OSGI 、WTP(Web Tools Platform)
Powered by: BlogJava Copyright © zhuxing