有关另外一个WTP重要的数据模型IStructuredDocument已经在前面介绍过了,今天我们看一下另外一个核心的数据模型IStructuredModel。在继续下面的内容之前,请确保当前工作区中已经导入(无论是源码方式导入还是二进制方式导入)了如下工程: 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的具体实现其实就是JFace Text Framework中IDocument接口的具体实现,其核心作用也集中在将特定文本按照特定的语法规则进行区域划分,提供相应的位置信息,这为WTP页面资源编辑器建立了核心数据模型。但是,单纯拥有偏重于语法的IStrucuturedDocument是不够的,我们同时还需要另外一套偏重于语义的数据模型,这就是IStructuredModel和其背后的WTP xml DOM实现(说明:对于CSS模型,是完全由WTP自己实现的,和本系列文章关系不大,本篇中不做详细介绍)。 注意:IStructuredModel以IStrucuturedDocument为基础构建,IStructuredDocument并不知道IStructuredModel,但是IStructuredModel知道该模型对应的IStrucuturedDocument!!! 现在先大致猜测一下原因,如果是直接将特定页面资源的内容直接转换为IStructuredModel肯定不容易,因为我们页面资源中的内容往往不是那么规则,那转化的过程中肯定避免不了自己去做大量的解析,导致构建IStructuredModel构建过程异常复杂;如果利用已有的IStrucuturedDocument构建机制,先将特定的内容解析为IStrucuturedDocument完成语法划分,再基于高度结构化的IStrucuturedDocument去构建IStrucuturedModel,那肯定会大大简化构建过程,某种程度上就可以将构建过程理解为把IStrucuturedDocument中节点列表转换为IStrucuturedModel持有的Document对应的节点列表了。IStructuredModel构建过程大致示意如下: 【IStructuredModel:句柄】 为什么说IStucturedModel是句柄呢,其实模型本身的信息并不是IStucturedModel角色在承担,而是每个IStructuredModel都持有对应的一个document。上图显示了IStrucuturedModel有两种实现:IDOMModel和ICSSModel,IDOMModel持有的是一个IDOMDocument,而ICSSModel持有的是一个ICSSDocument。真正持有模型节点信息的是IDOMDocument或者ICSSDocument,所以很大程度上我们可以将IStucturedModel理解为句柄(也不完全是这样,大致这么理解是为了更好的搞清楚这几者之间的关系^_^)。 【IStructuredModel构建过程进一步分析】 有了上面的解释我们应该清楚了,我们是基于IStructuredDocument语法划分的基础上建立起了对应的IDOMDocument或者ICSSDoucment,IStructuredModel持有对应的IDOMDocument或者ICSSDocument(当然,同时也会持有对应的IStructuredDocument)。所以到这里,我们可以稍微修正一下上面IStructuredModel构造流程图: 通过上面两幅图,语法Document(IStructuredDocument)、语义Document(IDOMDocument或者ICSSDocument)、WTP模型(IStructuredModel)三者的关系应该更加清楚了吧^_^,后门我会再抽一节来总结和分析一下之间的关系。在我们的真是应用中,语义Document(IDOMDocument或者ICSSDocument)一般在分析模型信息的时候才会用到,平时不会直接接触到,所以我前面将IStructuredDocument称之为WTP Document,将IStructuredModel称之为WTP Model,压根就没提IDOMDocument或者ICSSDocument。 【IStructuredModel提供的核心操作】 1、模型管理相关的操作(十分重要): getModelManager:获取模型管理器(关于这个概念的信息阐述,到会放到后门的章节中) getReferenceCount:获取被模型的引用计数(和IModelManager的引用计数管理相关) getReferenceCountForEdit:获取可写方式的引用计数 getReferenceCountForRead:获取只读方式的引用计数 isShared:判断该模型是否被IModelManager托管了,就是是否共享了 isSharedForEdit:本质上是判断该模型的只读引用计数是否为零,是否被以只读方式引用了 isSharedForRead:本质上是判断该模型的可写引用计数是否为零,是否被以可写方式引用了 releaseFromRead:减少只读方式的引用计数 releaseFromEdit:减少可写方式的引用计数 以上这些操作都是和一个重要的角色IModelManger相关,后门的章节中会详细阐述!!! 2、相关监听器操作(IModelStateListener非常常用): addModelLifecycleListener:我们使用较少,处理模型生命周期事件,详细信息参见org.eclipse.wst.sse.core.internal.model.ModelLifecycleEvent和org.eclipse.wst.sse.core.internal.provisional.IModelLifecycleListener addModelStateListener:我们使用较多,用于模型状态变化监听,我们下一节在开发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):根据位置定位对应语义Document(IDOMDocument或者ICSSDocument)中对应的节点,返回结果是一个IDOMNode或者ICSSNode 4、自身状态相关操作(也较为常用): 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则不是,要注意其中的区别!!! ...其他的几个以后用到的时候再说!!! 6、recording相关操作,我们后面不会直接用到此特性,不做阐述 【IDOMModel核心操作】 IDOMDocument getDocument就是它的核心操作,上面已经说过。 【IndexedRegion:WTP语义Document的Node】 如果将IStructuredDocument视为WTP的语法Document,则可以将IStructuredModel视为WTP模型,IDOMDocument或ICSSDocument视为WTP语义Document。而这个语义Document的中节点的超类型则就是IndexedRegion(org.eclipse.wst.sse.core.internal.provisional.IndexedRegion),IDOMDocument或ICSSDocument不过是其中两种节点类型(这个熟悉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在实现dom node系列时,借助于org.w3c.dom节点体系,这也是我们后面接触最多的;WTP在实现css node的时候,则和org.w3c.dom没有任何关系,完全是自己构建节点体系。 【IndexedRegion接口主要操作】 上面看了IndexedRegion主要分为两类,那么我们再回过头看一下IndexedRegion提供的核心操作: 我们看到IndexedRegion提供的核心操作都是关于位置信息的。这可能会产生一些疑问,例如位置信息的计算是不是挺繁琐的呢?怎么实现的呢? 我们回顾一下前面在分析IStructuredDocument的时候,我们ITextRegion接口(IStructuredDocument中节点的超类型)提供的核心操作之一就是提供位置信息。如果我们的每个IndexRegion节点都持有相关的ITextRegion节点不就可以了???确实是这么做的。这和我们这篇文章开头说的是一直的,基于语义的IStructuredModel(实际上是构造背后的IDOMDocument和ICSSDocument)构建的基础是基于语法的IStructuredDocument。 那么现在如果我们有了位置信息(例如编辑器中的光标的offset),我们就可以把WTP Doucment中的ITextRegion和WTP Model中的IndexedRegion(IDOMNode、ICSSNode)联系起来了。 【IDOMNode:IndexRegion的XML DOM实现】 绝大部分页面资源的语义Document都是基于IDOMNode的,我们就介绍它^_^。首先来看一副图片,可以和前面第三节介绍IStructuredDocument时用的图片做一个比较: 可以看到,IStructuredDocument的text region的划分是基于语法的,只要是一个闭合区域就是一个IStructuredDocumentRegion;IDOMDocument中的indexed region是基于语义划分的,看上图就可以看的出来,element之间都是有父子挂系的,再看一下一个dom attr区域是由三个text region组成的。 具体差异,后门的章节中会分析。 前面说过了,WTP model中的节点IndexedRegion有两种实现:一种是基于xml dom的IDOMNode,另外一种是WTP完全自己实现的ICSSNode,这里重点介绍IDOMNode(org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode)。有一点一定要记住:IDOMNode同时是一个w3c xml Node。 说明:既然遵守了w3c xml dom协议,那么我们的一个IDOMDocument本质上就是一个dom document,那这个dom对象肯定非常耗内存了。是的,IDOMDocument绝对是个重量级对象,但是选择dom还是有原因的:一可以提供较为丰富的语义;再者,一个页面资源的大小通常不会太大,也就是说一般不会产生非常巨大的DOM对象(例如大于10M)。 这其实和我们在日常应用中选择基于DOM的还是基于流的XML解析技术一样,要求语义是否丰富、对应的xml对象内存占用是两个重要的考虑。 为了dom对象耗内存的缺点降低到最低,和通常的解决办法一样,WTP也提供了模型缓存管理功能,也就是后面我们要说的IModelManager,对IStructuredModel进行引用计数管理(我们的IDOMDocument这个大dom对象会被IStructuredModel持有)。 【IDOMNode核心操作】 图中可以看的出来,我们的IDOMNode有两个超类型:IndexedRegion和org.w3c.dom.Node,我们的IDOMNode就提供了三类主要的操作: 1、IndexedRegion相关操作:提供位置相关信息的操作 2、org.w3c.dom.Node相关的操作:dom node相关操作(注意:有些dom node中规定的部分操作,WTP并没有实现,这些操作对WTP来说意义不大,毕竟一个页面资源并不完全是一个xml文件哈^_^) 3、IDOMNode接口自身定义的操作。这又可以大致分为三类: A、语法Document(IStructuredDocument)相关操作 IStructuredDocument getStructuredDocument IStructuredDocumentRegion getStartStructuredDocumentRegion IStructuredDocumentRegion getEndStructuredDocumentRegion IStructuredDocumentRegion getFirstStructuredDocumentRegion IStructuredDocumentRegion getLastStructuredDocumentRegion 有了以上操作,我们就可以从语法和语义两个层面来综合分析一个节点了 B、获取WTP 模型(IDOMModel) IDOMModel getModel() C、内容设置相关操作 getSource:获取节点内容 setSource:设置节点内容 getValueSource:获取value内容 setValueSource:设置value内容 setEditable setDataEditable setChildEditable isDataEditable isChildEditable D、其他操作,不常用,就不列举了 【···说明···】 IDOMNode相关的子接口类型也是常用的,里面都有对应的操作,可以帮助我们更好地操作语义Document,进行语义层面的分析。相关要熟练了解使用的接口为: 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实现】 我们后面基本用不到,因为我们基本上不去单独分析css资源,就不在本系列文章中去讲了。如果要分析ICSSNode,则可以参照分析IDOMNode的实现,祝好运^_^ 【后记】 我们这一节分析了WTP语义Document(IDOMDocument)和WTP模型(IStructuredModel),下一节会首先来开发一个类似于上一节中的分析视图:DOM Document分析视图。然后会单独拿出一节来分析这些重要概念之间的关系,同时会突出强调org.eclipse.wst.sse.core.internal.provisional.IModelManager. 到这里,WTP最重要的数据模型已经介绍完毕了,如下: 语法Document:IStructuredDocument 语义Document:重点介绍了IDOMDocument WTP模型:IStructuredModel(重点介绍了IDOMModel) 【模块关系】 借住于上面的分析过程,到现在我们对开头提到的几个插件的体系结构应该有了一定的认识了: WTP我们常接触的是WST、JST、RDB三个组成部分,RDB是专门来处理数据库相关的,本系列文章中不做讨论。JST的基础是WST,看上图中就可以发现,JSP类型的模型都需要基于WST中各种类型的模型,能不是基础吗。从语义上也讲的通哈,没有css、html、javascript、xml这些东东,怎么能建立起jsp呢??? 再回顾文章开头我们列举的12个插件工程,结合Eclipse的“分层法则”,12个插件工程之间的关系应该很清楚了吧...
本博客中的所有文章、随笔除了标题中含有引用或者转载字样的,其他均为原创。转载请注明出处,谢谢!
posted on 2008-09-09 18:03 zhuxing 阅读(2928) 评论(3) 编辑 收藏 所属分类: Eclipse Plug-in & OSGI 、WTP(Web Tools Platform)
Powered by: BlogJava Copyright © zhuxing