上一篇中我們已經(jīng)基于WTP的StructuredTextEditor建立了自己的JSPEditor,這篇將介紹對(duì)于我們Editor最重要的數(shù)據(jù)模型之一:IStructuredDocument(org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument),下一篇將介紹另外一個(gè)IStructuredModel。看一下IStructuredDocument的類型體系如下:

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

現(xiàn)在,我們暫且需要記住:在WTP世界中,一個(gè)頁(yè)面資源(JSP、html等)可以被描述為一個(gè)IStrucuturedDocument,這個(gè)document是由若干個(gè)IStructuredDocumentRegion組成,每個(gè)IStructuredDocumentRegion又會(huì)由多個(gè)ITextRegion組成。拿一個(gè)真實(shí)JSP示意一把:

提到Composite模式,現(xiàn)在我們就看一下誰(shuí)是里面的節(jié)點(diǎn)(Node)、誰(shuí)又是樹(shù)枝節(jié)點(diǎn)(Container Node)。到目前我們猜測(cè)ITextRegion應(yīng)該是普通節(jié)點(diǎn),IStructuredDocumentRegion應(yīng)該是樹(shù)枝節(jié)點(diǎn),我們看一下IStructuredDocumentRegion的sub type圖:

更準(zhǔn)確說(shuō):ITextRegion是節(jié)點(diǎn),ITextRegionCollection是樹(shù)枝節(jié)點(diǎn)(我們認(rèn)為IStructuredDocumentRegion是樹(shù)枝節(jié)點(diǎn)問(wèn)題也不大^_^)。
【IStructuredDocument創(chuàng)建和獲取方式】
如何來(lái)自己創(chuàng)建IStructuredDocument呢?常用的如下幾種:
1、IModelManager(org.eclipse.wst.sse.core.internal.provisional.IModelManager)
createStructuredDocumentFor
createNewStructuredDocumentFor
2、IStructuredModel(在已經(jīng)存在strutured model的情況下,建議使用)
IStructuredModel.getStructuredDocument
或者IStructuredModel.getModelHandler().getDocumentLoader().createNewStructuredDocument
3、IDocumentLoader.createNewStructuredDocument

4、通過(guò)IModelHandler()獲取IDocumentLoader,然后創(chuàng)建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 //通過(guò)IStructuredModel.getStructuredDocument()
9 IStructuredModel structuredModel = manager.getModelForRead(jspFile);
10 structuredModel.getStructuredDocument();
11
12 //根據(jù)文件類型計(jì)算對(duì)應(yīng)的IModelHandler,然后獲取IDocumentLoader
13 IModelHandler modelHandler = ModelHandlerRegistry.getInstance().getHandlerFor(jspFile);
14 IDocumentLoader documentLoader = modelHandler.getDocumentLoader();
15 documentLoader.createNewStructuredDocument(jspFile);
16
17 //直接調(diào)用對(duì)應(yīng)的IModelManager實(shí)現(xiàn)(例如解析一般的jsp)
18 new ModelHandlerForJSP().getDocumentLoader().createNewStructuredDocument(jspFile);
19
20 //直接調(diào)用對(duì)應(yīng)的IDocumentLoader實(shí)現(xiàn)(例如解析一般的jsp)
21 new JSPDocumentLoader().createNewStructuredDocument(jspFile);
22
23 //其他途徑
24 } catch (Exception e) {
25 //TODO:log exception
26 }
27 }
注意:
1、IStructuredDocument是相對(duì)比較重量級(jí)的對(duì)象,如果對(duì)應(yīng)的IStructuredModel已經(jīng)存在,則可以利用IStructuredModel中緩存的IStructuredDocument。(這個(gè)在后面介紹IStructuredModel的時(shí)候會(huì)詳細(xì)介紹^_^)
2、StructuredModelManager定義在公共包中,IModelManager反而定義在internal包中,它要干嗎???^_^
【ITextRegion相關(guān)】
說(shuō)明:不要將JFace Text Framework的IRegion和WTP的ITextRegion混淆,但是作用是類似的,核心作用都是提供位置信息。
我們首先來(lái)關(guān)注一下這個(gè)ITextRegion(org.eclipse.wst.sse.core.internal.provisional.text.ITextRegion),畢竟IStructuredDocument樹(shù)中所有節(jié)點(diǎn)都是ITextRegion類型:

我們看到,ITextRegion提供的最核心操作是:位置相關(guān)(start、text end、end),這里的所有位置信息是相對(duì)于其容器節(jié)點(diǎn)IStructuredDocumentRegion的,不是相對(duì)于IStructuredDocument(ITextRegionCollection)的;類型相關(guān)(getType()),返回region type。我們看到ITextRegion并沒(méi)有提供獲取文本的方法,有了相對(duì)于ITextRegionCollection的位置信息,借助于位置信息用ITextRegionCollection獲取不就可以了~_~
既然我們前面說(shuō)過(guò)了,ITextRegion是節(jié)點(diǎn)頂級(jí)類型,ITextRegionCollection象征著樹(shù)枝節(jié)點(diǎn)(例如IStructuredDocumentRegion),那么如果一種節(jié)點(diǎn)類型繼承自ITextRegion同時(shí)又不是ITextRegionCollection的子類型,那么這種節(jié)點(diǎn)就是我們說(shuō)的樹(shù)葉節(jié)點(diǎn)了(沒(méi)有孩子^_^):

看一下上圖,子類型名稱已經(jīng)清晰的告訴我們各個(gè)子類型是代表什么的了。我們拿幾個(gè)實(shí)際的例子來(lái)看一下吧,例子干脆就取自上面圖片中的JSP吧:
示例:<html xmlns="http://www.w3.org/1999/xhtml">
分析:
TagOpenRegion --> "<"
TagNameRegion --> "html "
AttributeNameRegion --> "xmlns"
AttributeEqualsRegion --> "="
AttributeValueRegion --> "http://www.w3.org/1999/xhtml"
TagOpenRegion --> ">"
【分析ITextRegion具體子類的類型】
看到上面的分析,我們可能會(huì)想,是否需要instanceof(例如 if (instanceof AttributeNameRegion ) .... )來(lái)判斷具體葉子節(jié)點(diǎn)的類型呢?如果你喜歡,這當(dāng)然可以;還有一種更方便的方法,那就是借助于ITextRegion.getType()返回接口來(lái)判斷,示例分別如下:
1 public boolean isTagNameRegion(ITextRegion region) {
2 //實(shí)現(xiàn)方式一:instanceof判斷
3 if (region instanceof TagNameRegion)
4 return true;
5
6 //實(shí)現(xiàn)方式二: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)常量接口中枚舉了所有的有關(guān)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)常量接口中枚舉了所有的有關(guān)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)常量接口中枚舉了所有的有關(guān)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)常量接口中枚舉了所有的有關(guān)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 }
說(shuō)明:建議使用ITextRegion.getType()和DOMRegionContext(DOMJSPRegionContexts、CSSRegionContexts、JSPedCSSRegionContexts)做text region的類型分析。為什么呢?像TagNameRegion...其實(shí)是ITextRegion的內(nèi)部實(shí)現(xiàn)類型,不應(yīng)該視為對(duì)外暴露的類型,基于接口編程的原則建議我們使用ITextRegion^_^;WTP在為每種ITextRegion的內(nèi)部實(shí)現(xiàn)設(shè)定了一個(gè)型別碼,這使得我們用ITextRegion超類型來(lái)判斷其具體的實(shí)際實(shí)現(xiàn)類型成為可能^_^ (PS:有興趣的哥們,可以看一下有關(guān)子類型和類型型別碼的資料,這是一個(gè)我們經(jīng)常要面對(duì)的東西,隱藏了設(shè)計(jì)技巧^_^)
【IStructuredDocumentRegion相關(guān)】

我們看到,IStructuredDocumentRegion繼承自ITextRegionCollection,是一種特殊的樹(shù)枝節(jié)點(diǎn)。上圖中的XMLStructuredDocumentRegion是我們最常用的IStructuredDocumentRegion實(shí)現(xiàn)。
首先看一下ITextRegionCollection提供的核心操作:

看的出來(lái),提供的核心操作基本上是圍繞子text region展開(kāi)的,具體請(qǐng)翻閱對(duì)應(yīng)的wtp源碼!!!常用的如下:
1、getRegions():返回組成當(dāng)前text region collection的text region列表
2、getText(ITextRegion)、getFullText(ITextRegion):獲取特定子text region的文本,前者不包含空格
3、getRegionAtCharacterOffset(int):返回指定位置(相對(duì)于collection的位置)的子text region
接著看一下,IStructuredDocumentRegion接口提供的操作:

看的出來(lái),IStructuredDocumentRegion提供了如下幾類操作:
1、遍歷相關(guān):getParentDocument()、getPrevious()、getNext(),非常常用!!! 對(duì)應(yīng)set...
2、修改內(nèi)容操作:addRegion...
【IStructuredDocument核心操作】
IStructuredDocument提供的核心操作基本為三類類:
1、定位IStructuredDocumentRegion:前面說(shuō)過(guò)IStructuredDocument是由一系列IStructuredDocumentRegion組成,由樹(shù)狀結(jié)構(gòu)的頂點(diǎn)獲取一級(jí)節(jié)點(diǎn)這是很應(yīng)該的^_^ 常用操作如下:
IStructuredDocumentRegion[] getStructuredDocumentRegions();
IStructuredDocumentRegion getFirstStructuredDocumentRegion();
IStructuredDocumentRegion getLastStructuredDocumentRegion();
IStructuredDocumentRegion getRegionAtCharacterOffset(int offset);
IStructuredDocumentRegion[] getStructuredDocumentRegions(int offset, int length);
2、修改document文本內(nèi)容:類似于JFace中IDocument.replace(int offset, int length, String text)。
3、Document Listener相關(guān):這個(gè)特性這邊不做詳細(xì)闡述,后面到我們進(jìn)一步定制WTP JSP編輯器的時(shí)候再討論如何使用它。很顯然,和JFace中的IDocumentListener機(jī)制原理類似,是一個(gè)典型的Obsever實(shí)現(xiàn),將Document自身核心邏輯和Document變化處理邏輯進(jìn)行松耦合處理。
【后記】
在這篇隨筆中,我們?cè)敿?xì)地討論了WTP中的JFace IDocument實(shí)現(xiàn) --》 IStructuredDocument!!!現(xiàn)在我們?cè)倏次恼麻_(kāi)頭的兩幅圖,應(yīng)該比較清楚了吧^_^ 再回顧一下吧:
1、IStructuredDocument結(jié)構(gòu)分析,Composite實(shí)現(xiàn),并著重分析里里面的節(jié)點(diǎn)、葉子節(jié)點(diǎn)、樹(shù)枝節(jié)點(diǎn)
2、如果創(chuàng)建和獲取IStructuredDocument實(shí)例,并強(qiáng)調(diào)了其重量級(jí)對(duì)象的特性
3、相關(guān)接口的核心操作說(shuō)明,例如遍歷,通過(guò)IStructuredDocument可以拿到你想要的IStructuredDocumentRegion,通過(guò)IStructuredDocumentRegion可以拿到你想要的ITextRegion,還說(shuō)明了如何分析ITextRegion的類型。
題目:給定一個(gè)工作區(qū)中的jsp文件,讓你分析該jsp文件,然后打印出來(lái)里面涉及到的所有tag name
辦法:
1、通過(guò)IFile構(gòu)造對(duì)應(yīng)的IStructuredDocument實(shí)例
2、遍歷IStructuredDocument, 獲取IStructuredDocumentRegion列表
3、分析IStructuredDocumentRegion,獲取其含有的ITextRegion列表
4、找出類型為DOMRegionContext.XML_TAG_NAME的text region,然后通過(guò)ITextRegionCollection.getText(ITextRegion containedRegion)獲取標(biāo)簽名稱
^_^,了解了WTP IStructuredDocument實(shí)現(xiàn),是不是覺(jué)得看WTP中的頁(yè)面資源文件更透徹些了呢?如果再了解一下后門(mén)的IStructuredModel,你會(huì)覺(jué)得更透徹^_^
PS:在下一篇中,我們將開(kāi)發(fā)一個(gè)Structured Document分析視圖。有關(guān)WTP Editor定制的具體細(xì)節(jié)還要再放置到更后門(mén)的篇幅去講,個(gè)人覺(jué)得如果對(duì)WTP IStructuredDocument和IStructuredModel這兩個(gè)核心數(shù)據(jù)模型不夠熟悉,你想定制WTP的已有功能....舉步維艱!
本博客中的所有文章、隨筆除了標(biāo)題中含有引用或者轉(zhuǎn)載字樣的,其他均為原創(chuàng)。轉(zhuǎn)載請(qǐng)注明出處,謝謝!