Live a simple life

沉默(zhu_xing@live.cn)
随笔 - 48, 文章 - 0, 评论 - 132, 引用 - 0
数据加载中……

【Eclipse插件开发】基于WTP开发自定义的JSP编辑器(三) :WTP Structured Document

        上一篇中我们已经基于WTP的StructuredTextEditor建立了自己的JSPEditor,这篇将介绍对于我们Editor最重要的数据模型之一:IStructuredDocument(org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument),下一篇将介绍另外一个IStructuredModel。看一下IStructuredDocument的类型体系如下:
        
        上图中,我们看到了IStructuredDocument的身影,是JFace Text Framework中IDocument接口实现,选中的JobSafeStructureedDocument就是我们要面对的IStructuredDocument实现。
        PS:从类型名称就可以猜测的出来,BasicStructuredDocument应该是一个类似于Default Adapter的角色,具体呢? 自己去看一下^_^


        【IStructuredDocument结构--Composite】
          只要是我们观察一下JSP就知道,其他本质上是一个树状结构的文档,怎么来建立这种文档呢? 很自然的做法是底层用xml来描述JSP,然后建立起这种xml模型,同时建立起我们的Document实现(说明:提到的WTP XML模型会在下一篇中介绍--》 IStructuredModel)。既然是树状的,那一般而言接口会按照Composite模式来写。我们先看一下一张IStructuredDocument接口示意图吧:
           
            现在,我们暂且需要记住:在WTP世界中,一个页面资源(JSP、html等)可以被描述为一个IStrucuturedDocument,这个document是由若干个IStructuredDocumentRegion组成,每个IStructuredDocumentRegion又会由多个ITextRegion组成。拿一个真实JSP示意一把:
            
            
          提到Composite模式,现在我们就看一下谁是里面的节点(Node)、谁又是树枝节点(Container Node)。到目前我们猜测ITextRegion应该是普通节点,IStructuredDocumentRegion应该是树枝节点,我们看一下IStructuredDocumentRegion的sub type图:
        
        更准确说:ITextRegion是节点,ITextRegionCollection是树枝节点(我们认为IStructuredDocumentRegion是树枝节点问题也不大^_^)。

        【IStructuredDocument创建和获取方式】
            如何来自己创建IStructuredDocument呢?常用的如下几种:
            1、IModelManager(org.eclipse.wst.sse.core.internal.provisional.IModelManager
                  createStructuredDocumentFor             
                  createNewStructuredDocumentFor     
            
            2、IStructuredModel(在已经存在strutured model的情况下,建议使用)
                  IStructuredModel.getStructuredDocument
                  或者IStructuredModel.getModelHandler().getDocumentLoader().createNewStructuredDocument  

            
3、IDocumentLoader.createNewStructuredDocument

                   
            4、通过IModelHandler()获取IDocumentLoader,然后创建Structured Document            
            5、。。。其他方式
            
            示例代码:   

 1 public void createStructuredDocument(IFile jspFile) {
 2         try {
 3             //获取org.eclipse.wst.sse.core.internal.provisional.IModelManager
 4             IModelManager manager = StructuredModelManager.getModelManager();
 5             manager.createNewStructuredDocumentFor(jspFile);
 6             manager.createStructuredDocumentFor(jspFile);  
 7             
 8             //通过IStructuredModel.getStructuredDocument()
 9             IStructuredModel structuredModel = manager.getModelForRead(jspFile);
10             structuredModel.getStructuredDocument();
11             
12             //根据文件类型计算对应的IModelHandler,然后获取IDocumentLoader
13             IModelHandler modelHandler = ModelHandlerRegistry.getInstance().getHandlerFor(jspFile);
14             IDocumentLoader documentLoader = modelHandler.getDocumentLoader();
15             documentLoader.createNewStructuredDocument(jspFile);
16             
17             //直接调用对应的IModelManager实现(例如解析一般的jsp)
18             new ModelHandlerForJSP().getDocumentLoader().createNewStructuredDocument(jspFile);
19             
20             //直接调用对应的IDocumentLoader实现(例如解析一般的jsp)
21             new JSPDocumentLoader().createNewStructuredDocument(jspFile);
22             
23             //其他途径
24         } catch (Exception e) {
25             //TODO:log exception
26         }
27     }

        
        注意:
        1、IStructuredDocument是相对比较重量级的对象,如果对应的IStructuredModel已经存在,则可以利用IStructuredModel中缓存的IStructuredDocument。(这个在后面介绍IStructuredModel的时候会详细介绍^_^)
        2、StructuredModelManager定义在公共包中,IModelManager反而定义在internal包中,它要干吗???^_^

       【ITextRegion相关】
       说明:不要将JFace Text Framework的IRegion和WTP的ITextRegion混淆,但是作用是类似的,核心作用都是提供位置信息。
      
我们首先来关注一下这个ITextRegion(org.eclipse.wst.sse.core.internal.provisional.text.ITextRegion),毕竟IStructuredDocument树中所有节点都是ITextRegion类型:
        
        我们看到,ITextRegion提供的最核心操作是:位置相关(start、text end、end),这里的所有位置信息是相对于其容器节点IStructuredDocumentRegion的,不是相对于IStructuredDocument(ITextRegionCollection)的;类型相关(getType()),返回region type。我们看到ITextRegion并没有提供获取文本的方法,有了相对于ITextRegionCollection的位置信息,借助于位置信息用ITextRegionCollection获取不就可以了~_~

        既然我们前面说过了,ITextRegion是节点顶级类型,ITextRegionCollection象征着树枝节点(例如IStructuredDocumentRegion),那么如果一种节点类型继承自ITextRegion同时又不是ITextRegionCollection的子类型,那么这种节点就是我们说的树叶节点了(没有孩子^_^):
        
        看一下上图,子类型名称已经清晰的告诉我们各个子类型是代表什么的了。我们拿几个实际的例子来看一下吧,例子干脆就取自上面图片中的JSP吧:
        示例:<html xmlns="http://www.w3.org/1999/xhtml">

        分析:TagOpenRegion          -->    "<"
                    TagNameRegion         -->    "html "
                    AttributeNameRegion  -->    "xmlns"
                    AttributeEqualsRegion -->    "="
                    AttributeValueRegion  -->    "http://www.w3.org/1999/xhtml"
                    TagOpenRegion          -->    ">"
        
        【分析ITextRegion具体子类的类型】
        看到上面的分析,我们可能会想,是否需要instanceof(例如 if (instanceof AttributeNameRegion ) .... )来判断具体叶子节点的类型呢?如果你喜欢,这当然可以;还有一种更方便的方法,那就是借助于ITextRegion.getType()返回接口来判断,示例分别如下:
 1 public boolean isTagNameRegion(ITextRegion region) {
 2         //实现方式一:instanceof判断
 3         if (region instanceof TagNameRegion)
 4             return true;
 5         
 6         //实现方式二:type信息判断
 7         if (DOMRegionContext.XML_TAG_NAME.equals(region.getType()))
 8             return true;
 9         
10         return false;
11     }
        
        DOMRegionContext(org.eclipse.wst.xml.core.internal.regions.DOMRegionContext)常量接口中枚举了所有的有关XML的text region类型常量: 
 1 package org.eclipse.wst.xml.core.internal.regions;
 2 
 3 public interface DOMRegionContext {
 4 
 5     public static final String BLOCK_TEXT = "BLOCK_TEXT"//$NON-NLS-1$
 6 
 7     public static final String UNDEFINED = "UNDEFINED"//$NON-NLS-1$
 8 
 9     public static final String WHITE_SPACE = "WHITE_SPACE"//$NON-NLS-1$
10     public static final String XML_ATTLIST_DECL_CLOSE = "XML_ATTLIST_DECL_CLOSE"//$NON-NLS-1$
11     public static final String XML_ATTLIST_DECL_CONTENT = "XML_ATTLIST_DECL_CONTENT"//$NON-NLS-1$
12     public static final String XML_ATTLIST_DECL_NAME = "XML_ATTLIST_DECL_NAME"//$NON-NLS-1$
13 
14     public static final String XML_ATTLIST_DECLARATION = "XML_ATTLIST_DECLARATION"//$NON-NLS-1$
15     public static final String XML_CDATA_CLOSE = "XML_CDATA_CLOSE"//$NON-NLS-1$
16     public static final String XML_CDATA_OPEN = "XML_CDATA_OPEN"//$NON-NLS-1$
17     public static final String XML_CDATA_TEXT = "XML_CDATA_TEXT"//$NON-NLS-1$
18     public static final String XML_CHAR_REFERENCE = "XML_CHAR_REFERENCE"//$NON-NLS-1$
19     public static final String XML_COMMENT_CLOSE = "XML_COMMENT_CLOSE"//$NON-NLS-1$
20 
21     public static final String XML_COMMENT_OPEN = "XML_COMMENT_OPEN"//$NON-NLS-1$
22     public static final String XML_COMMENT_TEXT = "XML_COMMENT_TEXT"//$NON-NLS-1$
23 
24     public static final String XML_CONTENT = "XML_CONTENT"//$NON-NLS-1$
25     public static final String XML_DECLARATION_CLOSE = "XML_DECLARATION_CLOSE"//$NON-NLS-1$
26 
27     public static final String XML_DECLARATION_OPEN = "XML_DECLARATION_OPEN"//$NON-NLS-1$
28 
29     public static final String XML_DOCTYPE_DECLARATION = "XML_DOCTYPE_DECLARATION"//$NON-NLS-1$
30     public static final String XML_DOCTYPE_DECLARATION_CLOSE = "XML_DOCTYPE_DECLARATION_CLOSE"//$NON-NLS-1$
31     public static final String XML_DOCTYPE_EXTERNAL_ID_PUBLIC = "XML_DOCTYPE_EXTERNAL_ID_PUBLIC"//$NON-NLS-1$
32     public static final String XML_DOCTYPE_EXTERNAL_ID_PUBREF = "XML_DOCTYPE_EXTERNAL_ID_PUBREF"//$NON-NLS-1$
33     public static final String XML_DOCTYPE_EXTERNAL_ID_SYSREF = "XML_DOCTYPE_EXTERNAL_ID_SYSREF"//$NON-NLS-1$
34     public static final String XML_DOCTYPE_EXTERNAL_ID_SYSTEM = "XML_DOCTYPE_EXTERNAL_ID_SYSTEM"//$NON-NLS-1$
35     public static final String XML_DOCTYPE_INTERNAL_SUBSET = "XML_DOCTYPE_INTERNAL_SUBSET"//$NON-NLS-1$
36     public static final String XML_DOCTYPE_NAME = "XML_DOCTYPE_NAME"//$NON-NLS-1$
37     public static final String XML_ELEMENT_DECL_CLOSE = "XML_ELEMENT_DECL_CLOSE"//$NON-NLS-1$
38     public static final String XML_ELEMENT_DECL_CONTENT = "XML_ELEMENT_DECL_CONTENT"//$NON-NLS-1$
39     public static final String XML_ELEMENT_DECL_NAME = "XML_ELEMENT_DECL_NAME"//$NON-NLS-1$
40 
41     public static final String XML_ELEMENT_DECLARATION = "XML_ELEMENT_DECLARATION"//$NON-NLS-1$
42     public static final String XML_EMPTY_TAG_CLOSE = "XML_EMPTY_TAG_CLOSE"//$NON-NLS-1$
43     public static final String XML_END_TAG_OPEN = "XML_END_TAG_OPEN"//$NON-NLS-1$
44     public static final String XML_ENTITY_REFERENCE = "XML_ENTITY_REFERENCE"//$NON-NLS-1$
45 
46     public static final String XML_PE_REFERENCE = "XML_PE_REFERENCE"//$NON-NLS-1$
47     public static final String XML_PI_CLOSE = "XML_PI_CLOSE"//$NON-NLS-1$
48     public static final String XML_PI_CONTENT = "XML_PI_CONTENT"//$NON-NLS-1$
49     public static final String XML_PI_OPEN = "XML_PI_OPEN"//$NON-NLS-1$
50     public static final String XML_TAG_ATTRIBUTE_EQUALS = "XML_TAG_ATTRIBUTE_EQUALS"//$NON-NLS-1$
51     public static final String XML_TAG_ATTRIBUTE_NAME = "XML_TAG_ATTRIBUTE_NAME"//$NON-NLS-1$
52     public static final String XML_TAG_ATTRIBUTE_VALUE = "XML_TAG_ATTRIBUTE_VALUE"//$NON-NLS-1$
53     public static final String XML_TAG_CLOSE = "XML_TAG_CLOSE"//$NON-NLS-1$
54     public static final String XML_TAG_NAME = "XML_TAG_NAME"//$NON-NLS-1$
55 
56     public static final String XML_TAG_OPEN = "XML_TAG_OPEN"//$NON-NLS-1$
57 }
            
             DOMJSPRegionContexts(org.eclipse.jst.jsp.core.internal.regions.DOMJSPRegionContexts)常量接口中枚举了所有的有关JSP的text region类型常量
 1 public interface DOMJSPRegionContexts extends DOMRegionContext {
 2     public static final String JSP_CLOSE = "JSP_CLOSE"//$NON-NLS-1$
 3     public static final String JSP_COMMENT_CLOSE = "JSP_COMMENT_CLOSE"//$NON-NLS-1$
 4 
 5     public static final String JSP_COMMENT_OPEN = "JSP_COMMENT_OPEN"//$NON-NLS-1$
 6     public static final String JSP_COMMENT_TEXT = "JSP_COMMENT_TEXT"//$NON-NLS-1$
 7 
 8     public static final String JSP_CONTENT = "JSP_CONTENT"//$NON-NLS-1$
 9     public static final String JSP_DECLARATION_OPEN = "JSP_DECLARATION_OPEN"//$NON-NLS-1$
10     public static final String JSP_DIRECTIVE_CLOSE = "JSP_DIRECTIVE_CLOSE"//$NON-NLS-1$
11     public static final String JSP_DIRECTIVE_NAME = "JSP_DIRECTIVE_NAME"//$NON-NLS-1$
12 
13     public static final String JSP_DIRECTIVE_OPEN = "JSP_DIRECTIVE_OPEN"//$NON-NLS-1$
14     public static final String JSP_EL_CLOSE = "JSP_EL_CLOSE"//$NON-NLS-1$
15     public static final String JSP_EL_CONTENT = "JSP_EL_CONTENT"//$NON-NLS-1$
16     public static final String JSP_EL_DQUOTE = "JSP_EL_DQUOTE"//$NON-NLS-1$
17 
18     public static final String JSP_EL_OPEN = "JSP_EL_OPEN"//$NON-NLS-1$
19     public static final String JSP_EL_QUOTED_CONTENT = "JSP_EL_QUOTED_CONTENT"//$NON-NLS-1$
20     public static final String JSP_EL_SQUOTE = "JSP_EL_SQUOTE"//$NON-NLS-1$
21     public static final String JSP_EXPRESSION_OPEN = "JSP_EXPRESSION_OPEN"//$NON-NLS-1$
22 
23     public static final String JSP_ROOT_TAG_NAME = "JSP_ROOT_TAG_NAME"//$NON-NLS-1$
24 
25     public static final String JSP_SCRIPTLET_OPEN = "JSP_SCRIPTLET_OPEN"//$NON-NLS-1$
26     public static final String JSP_VBL_CLOSE = "JSP_VBL_CLOSE"//$NON-NLS-1$
27     public static final String JSP_VBL_CONTENT = "JSP_VBL_CONTENT"//$NON-NLS-1$
28     public static final String JSP_VBL_DQUOTE = "JSP_VBL_DQUOTE"//$NON-NLS-1$
29     public static final String JSP_VBL_OPEN = "JSP_VBL_OPEN"//$NON-NLS-1$
30     public static final String JSP_VBL_QUOTED_CONTENT = "JSP_VBL_QUOTED_CONTENT"//$NON-NLS-1$
31     public static final String JSP_VBL_SQUOTE = "JSP_VBL_SQUOTE"//$NON-NLS-1$
32     public static final String XML_TAG_ATTRIBUTE_VALUE_DQUOTE = "XML_TAG_ATTRIBUTE_VALUE_DQUOTE"//$NON-NLS-1$
33 
34     public static final String XML_TAG_ATTRIBUTE_VALUE_SQUOTE = "XML_TAG_ATTRIBUTE_VALUE_SQUOTE"//$NON-NLS-1$
35 }
36 
            
            CSSRegionContextsorg.eclipse.wst.css.core.internal.parserz.CSSRegionContexts)常量接口中枚举了所有的有关CSS的text region类型常量: 
 1 public interface CSSRegionContexts {
 2     public static final String CSS_COMMENT = "COMMENT"//$NON-NLS-1$
 3     public static final String CSS_CDO = "CDO"//$NON-NLS-1$
 4     public static final String CSS_CDC = "CDC"//$NON-NLS-1$
 5     public static final String CSS_S = "S"//$NON-NLS-1$
 6 
 7     public static final String CSS_DELIMITER = "DELIMITER"//$NON-NLS-1$
 8     public static final String CSS_LBRACE = "LBRACE"//$NON-NLS-1$
 9     public static final String CSS_RBRACE = "RBRACE"//$NON-NLS-1$
10 
11     public static final String CSS_IMPORT = "IMPORT"//$NON-NLS-1$
12     public static final String CSS_PAGE = "PAGE"//$NON-NLS-1$
13     public static final String CSS_MEDIA = "MEDIA"//$NON-NLS-1$
14     public static final String CSS_FONT_FACE = "FONT_FACE"//$NON-NLS-1$
15     public static final String CSS_CHARSET = "CHARSET"//$NON-NLS-1$
16     public static final String CSS_ATKEYWORD = "ATKEYWORD"//$NON-NLS-1$
17 
18     public static final String CSS_STRING = "STRING"//$NON-NLS-1$
19     public static final String CSS_URI = "URI"//$NON-NLS-1$
20     public static final String CSS_MEDIUM = "MEDIUM"//$NON-NLS-1$
21     public static final String CSS_MEDIA_SEPARATOR = "MEDIA_SEPARATOR"//$NON-NLS-1$
22 
23     public static final String CSS_CHARSET_NAME = "CHARSET_NAME"//$NON-NLS-1$
24 
25     public static final String CSS_PAGE_SELECTOR = "CSS_PAGE_SELECTOR"//$NON-NLS-1$
26 
27     public static final String CSS_SELECTOR_ELEMENT_NAME = "SELECTOR_ELEMENT_NAME"//$NON-NLS-1$
28     public static final String CSS_SELECTOR_UNIVERSAL = "SELECTOR_UNIVERSAL"//$NON-NLS-1$
29     public static final String CSS_SELECTOR_PSEUDO = "SELECTOR_PSEUDO"//$NON-NLS-1$
30     public static final String CSS_SELECTOR_CLASS = "SELECTOR_CLASS"//$NON-NLS-1$
31     public static final String CSS_SELECTOR_ID = "SELECTOR_ID"//$NON-NLS-1$
32     public static final String CSS_SELECTOR_COMBINATOR = "SELECTOR_COMBINATOR"//$NON-NLS-1$
33     public static final String CSS_SELECTOR_SEPARATOR = "SELECTOR_SEPARATOR"//$NON-NLS-1$
34 
35     public static final String CSS_SELECTOR_ATTRIBUTE_START = "SELECTOR_ATTRIBUTE_START"//$NON-NLS-1$
36     public static final String CSS_SELECTOR_ATTRIBUTE_END = "SELECTOR_ATTRIBUTE_END"//$NON-NLS-1$
37     public static final String CSS_SELECTOR_ATTRIBUTE_NAME = "SELECTOR_ATTRIBUTE_NAME"//$NON-NLS-1$
38     public static final String CSS_SELECTOR_ATTRIBUTE_VALUE = "SELECTOR_ATTRIBUTE_VALUE"//$NON-NLS-1$
39     public static final String CSS_SELECTOR_ATTRIBUTE_OPERATOR = "SELECTOR_ATTRIBUTE_OPERATOR"//$NON-NLS-1$
40 
41     public static final String CSS_DECLARATION_PROPERTY = "DECLARATION_PROPERTY"//$NON-NLS-1$
42     public static final String CSS_DECLARATION_SEPARATOR = "DECLARATION_SEPARATOR"//$NON-NLS-1$
43     public static final String CSS_DECLARATION_DELIMITER = "DECLARATION_DELIMITER"//$NON-NLS-1$
44     public static final String CSS_DECLARATION_VALUE_IDENT = "DECLARATION_VALUE_IDENT"//$NON-NLS-1$
45     public static final String CSS_DECLARATION_VALUE_DIMENSION = "DECLARATION_VALUE_DIMENSION"//$NON-NLS-1$
46     public static final String CSS_DECLARATION_VALUE_PERCENTAGE = "DECLARATION_VALUE_PERCENTAGE"//$NON-NLS-1$
47     public static final String CSS_DECLARATION_VALUE_NUMBER = "DECLARATION_VALUE_NUMBER"//$NON-NLS-1$
48     public static final String CSS_DECLARATION_VALUE_FUNCTION = "DECLARATION_VALUE_FUNCTION"//$NON-NLS-1$
49     public static final String CSS_DECLARATION_VALUE_PARENTHESIS_CLOSE = "DECLARATION_VALUE_PARENTHESIS_CLOSE"//$NON-NLS-1$
50     public static final String CSS_DECLARATION_VALUE_STRING = "DECLARATION_VALUE_STRING"//$NON-NLS-1$
51     public static final String CSS_DECLARATION_VALUE_URI = "DECLARATION_VALUE_URI"//$NON-NLS-1$
52     public static final String CSS_DECLARATION_VALUE_HASH = "DECLARATION_VALUE_HASH"//$NON-NLS-1$
53     public static final String CSS_DECLARATION_VALUE_UNICODE_RANGE = "DECLARATION_VALUE_UNICODE_RANGE"//$NON-NLS-1$
54     public static final String CSS_DECLARATION_VALUE_IMPORTANT = "CSS_DECLARATION_VALUE_IMPORTANT"//$NON-NLS-1$
55     public static final String CSS_DECLARATION_VALUE_OPERATOR = "DECLARATION_VALUE_OPERATOR"//$NON-NLS-1$
56     public static final String CSS_DECLARATION_VALUE_S = "DECLARATION_VALUE_S"//$NON-NLS-1$
57 
58     public static final String CSS_UNKNOWN = "UNKNOWN"//$NON-NLS-1$
59 
60     // For null object : CSSTokenizer never set this value
61     public static final String CSS_UNDEFINED = "UNDEFINED"//$NON-NLS-1$
62     /**
63       * currently provided this field but may be removed in future.
64      */
65     public static final String CSS_FOREIGN_ELEMENT = "FOREIGN_ELEMENT"//$NON-NLS-1$
66 }
            
            JSPedCSSRegionContextsorg.eclipse.jst.jsp.css.core.internal.parserz.JSPedCSSRegionContexts)常量接口中枚举了所有的有关JSP和CSS嵌套情况下的text region类型常量: 
 1 public interface JSPedCSSRegionContexts extends CSSRegionContexts {    
 2     public static final String CSS_JSP_EXP = "CSS_JSP_EXP"//$NON-NLS-1$
 3     public static final String CSS_JSP_EL = CSSRegionContexts.CSS_FOREIGN_ELEMENT; //$NON-NLS-1$
 4     public static final String CSS_JSP_SCRIPTLET = "CSS_JSP_SCRIPTLET"//$NON-NLS-1$
 5     public static final String CSS_JSP_DIRECTIVE = "CSS_JSP_DIRECTIVE"//$NON-NLS-1$
 6     public static final String CSS_JSP_DECL = "CSS_JSP_DECL"//$NON-NLS-1$
 7     public static final String CSS_JSP_END = "CSS_JSP_END"//$NON-NLS-1$
 8     public static final String CSS_EL_END = "CSS_EL_END"//$NON-NLS-1$
 9     public static final String CSS_JSP_COMMENT_END = "CSS_JSP_COMMENT_END"//$NON-NLS-1$
10     public static final String CSS_JSP_COMMENT = "CSS_JSP_COMMENT"//$NON-NLS-1$
11 }


            说明:建议使用ITextRegion.getType()和DOMRegionContext(DOMJSPRegionContexts、CSSRegionContexts、JSPedCSSRegionContexts)做text region的类型分析。为什么呢?像TagNameRegion...其实是ITextRegion的内部实现类型,不应该视为对外暴露的类型,基于接口编程的原则建议我们使用ITextRegion^_^;WTP在为每种ITextRegion的内部实现设定了一个型别码,这使得我们用ITextRegion超类型来判断其具体的实际实现类型成为可能^_^    (PS:有兴趣的哥们,可以看一下有关子类型和类型型别码的资料,这是一个我们经常要面对的东西,隐藏了设计技巧^_^)

        【IStructuredDocumentRegion相关】
            
            我们看到,IStructuredDocumentRegion继承自ITextRegionCollection,是一种特殊的树枝节点。上图中的XMLStructuredDocumentRegion是我们最常用的IStructuredDocumentRegion实现。
            
            首先看一下ITextRegionCollection提供的核心操作:
            
            看的出来,提供的核心操作基本上是围绕子text region展开的,具体请翻阅对应的wtp源码!!!常用的如下:
        1、getRegions():返回组成当前text region collection的text region列表
        2、getText(ITextRegion)、getFullText(ITextRegion):获取特定子text region的文本,前者不包含空格
        3、getRegionAtCharacterOffset(int):返回指定位置(相对于collection的位置)的子text region
            
            接着看一下,IStructuredDocumentRegion接口提供的操作:
            
            看的出来,IStructuredDocumentRegion提供了如下几类操作:
            1、遍历相关:getParentDocument()、getPrevious()、getNext(),非常常用!!!  对应set...
            2、修改内容操作:addRegion...

            【IStructuredDocument核心操作】
          IStructuredDocument提供的核心操作基本为三类类:
               1、定位IStructuredDocumentRegion:前面说过IStructuredDocument是由一系列IStructuredDocumentRegion组成,由树状结构的顶点获取一级节点这是很应该的^_^   常用操作如下:
                    IStructuredDocumentRegion[] getStructuredDocumentRegions();
                    IStructuredDocumentRegion getFirstStructuredDocumentRegion();
                    IStructuredDocumentRegion  getLastStructuredDocumentRegion();
                    IStructuredDocumentRegion getRegionAtCharacterOffset(int offset);
                    IStructuredDocumentRegion[] getStructuredDocumentRegions(int offset, int length);

               2、修改document文本内容:类似于JFace中IDocument.replace(int offset, int length, String text)。

               3、Document Listener相关:这个特性这边不做详细阐述,后面到我们进一步定制WTP JSP编辑器的时候再讨论如何使用它。很显然,和JFace中的IDocumentListener机制原理类似,是一个典型的Obsever实现,将Document自身核心逻辑和Document变化处理逻辑进行松耦合处理。

            【后记】
            在这篇随笔中,我们详细地讨论了WTP中的JFace IDocument实现 --》  IStructuredDocument!!!现在我们再看文章开头的两幅图,应该比较清楚了吧^_^    再回顾一下吧:
            1、IStructuredDocument结构分析,Composite实现,并着重分析里里面的节点、叶子节点、树枝节点
            2、如果创建和获取IStructuredDocument实例,并强调了其重量级对象的特性
            3、相关接口的核心操作说明,例如遍历,通过IStructuredDocument可以拿到你想要的IStructuredDocumentRegion,通过IStructuredDocumentRegion可以拿到你想要的ITextRegion,还说明了如何分析ITextRegion的类型。

            题目:给定一个工作区中的jsp文件,让你分析该jsp文件,然后打印出来里面涉及到的所有tag name
            办法:
            1、通过IFile构造对应的IStructuredDocument实例
            2、遍历IStructuredDocument, 获取IStructuredDocumentRegion列表
            3、分析IStructuredDocumentRegion,获取其含有的ITextRegion列表
            4、找出类型为DOMRegionContext.XML_TAG_NAME的text region,然后通过ITextRegionCollection.getText(ITextRegion containedRegion)获取标签名称

        ^_^,了解了WTP IStructuredDocument实现,是不是觉得看WTP中的页面资源文件更透彻些了呢?如果再了解一下后门的IStructuredModel,你会觉得更透彻^_^

        PS:在下一篇中,我们将开发一个Structured Document分析视图。有关WTP Editor定制的具体细节还要再放置到更后门的篇幅去讲,个人觉得如果对WTP IStructuredDocument和IStructuredModel这两个核心数据模型不够熟悉,你想定制WTP的已有功能....举步维艰!


本博客中的所有文章、随笔除了标题中含有引用或者转载字样的,其他均为原创。转载请注明出处,谢谢!

posted on 2008-09-08 16:01 zhuxing 阅读(4139) 评论(6)  编辑  收藏 所属分类: Eclipse Plug-in & OSGIWTP(Web Tools Platform)

评论

# re: 【Eclipse插件开发】基于WTP开发自定义的JSP编辑器(三) :WTP Structured Document  回复  更多评论   

我靠,受益扉浅啊.真长见识. 你说的很有道理,我之前想定制编辑器只关注Editor部分,结果愣没搞明白. 这个数据模型的处理,也很重要. 学习了. 请允许我继续期待后续篇章.

BTW, 您这一篇的第一句话有点迷惑我: "上一篇中我们已经基于WTP的StructuredTextEditor建立了自己的JSPEditor", 上一篇有讲过建立自己的JSPEditor吗~~
2008-09-09 09:22 | srdrm

# re: 【Eclipse插件开发】基于WTP开发自定义的JSP编辑器(三) :WTP Structured Document  回复  更多评论   

占个位置慢慢看。
2008-09-09 14:03 | zhanggj

# re: 【Eclipse插件开发】基于WTP开发自定义的JSP编辑器(三) :WTP Structured Document  回复  更多评论   

挺好的。继续!
2008-10-16 15:59 | Alf

# re: 【Eclipse插件开发】基于WTP开发自定义的JSP编辑器(三) :WTP Structured Document  回复  更多评论   

DOMJSPRegionContexts中的常量能否解释一下
2009-04-07 17:12 | fjibj

# re: 【Eclipse插件开发】基于WTP开发自定义的JSP编辑器(三) :WTP Structured Document  回复  更多评论   

感谢楼主无私的风险,我这两天都在学习你的东西
2010-06-25 17:51 | htallen

# re: 【Eclipse插件开发】基于WTP开发自定义的JSP编辑器(三) :WTP Structured Document  回复  更多评论   

好文,多看几遍才能有深刻理解啊~
2012-09-19 11:33 | imu2008

只有注册用户登录后才能发表评论。


网站导航: