上一篇中我們已經基于WTP的StructuredTextEditor建立了自己的JSPEditor,這篇將介紹對于我們Editor最重要的數據模型之一:IStructuredDocument(org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument),下一篇將介紹另外一個IStructuredModel??匆幌翴StructuredDocument的類型體系如下:

上圖中,我們看到了IStructuredDocument的身影,是JFace Text Framework中IDocument接口實現,選中的JobSafeStructureedDocument就是我們要面對的IStructuredDocument實現。
PS:從類型名稱就可以猜測的出來,BasicStructuredDocument應該是一個類似于Default Adapter的角色,具體呢? 自己去看一下^_^
【IStructuredDocument結構--Composite】
只要是我們觀察一下JSP就知道,其他本質上是一個樹狀結構的文檔,怎么來建立這種文檔呢? 很自然的做法是底層用xml來描述JSP,然后建立起這種xml模型,同時建立起我們的Document實現(說明:提到的WTP XML模型會在下一篇中介紹--》 IStructuredModel)。既然是樹狀的,那一般而言接口會按照Composite模式來寫。我們先看一下一張IStructuredDocument接口示意圖吧:

現在,我們暫且需要記?。涸赪TP世界中,一個頁面資源(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
CSSRegionContexts(org.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 }
JSPedCSSRegionContexts(org.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!?。‖F在我們再看文章開頭的兩幅圖,應該比較清楚了吧^_^ 再回顧一下吧:
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的已有功能....舉步維艱!
本博客中的所有文章、隨筆除了標題中含有引用或者轉載字樣的,其他均為原創。轉載請注明出處,謝謝!