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 閱讀(4158) 評論(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
          主站蜘蛛池模板: 岳西县| 清水河县| 金坛市| 黄骅市| 日照市| 北宁市| 资中县| 全州县| 张掖市| 贵溪市| 咸宁市| 沙田区| 金山区| 孙吴县| 长兴县| 德庆县| 潢川县| 广丰县| 黑龙江省| 香港| 崇阳县| 新干县| 汽车| 南部县| 靖宇县| 宁蒗| 射洪县| 石景山区| 金平| 武定县| 阿城市| 咸丰县| 青神县| 中西区| 乐清市| 菏泽市| 淮阳县| 临澧县| 防城港市| 铜梁县| 四川省|