【Eclipse插件開發(fā)】基于WTP開發(fā)自定義的JSP編輯器(六):IStructuredModel(DOM Document)分析視圖
前面的幾節(jié)中,我們都已經(jīng)完整的介紹過了WTP最核心的幾個(gè)數(shù)據(jù)模型:語(yǔ)法Document(IStructuredDocument)、語(yǔ)義Document(IDOMDocument、ICSSDocument)和WTP模型(IStructuredModel)。IStructuredModel在某種程度上可以看作是語(yǔ)義Document和語(yǔ)法Document的門面,三者關(guān)系再羅唆一下:

前面在講完WTP 語(yǔ)法Document(IStructuredDocument)的時(shí)候,我們開發(fā)過一個(gè)Structured Document分析視圖,我想通過那個(gè)視圖可以加深對(duì)IStructuredDocument的理解。在本節(jié)中,我們?cè)陂_發(fā)一個(gè)視圖,來分析一下WTP的語(yǔ)義Document(我們只分析最常用的IDOMDocument),希望也有類似的作用。
PS:這兩個(gè)視圖其實(shí)可以作為一個(gè)工具來用,對(duì)于想修改或者定制WTP源碼(當(dāng)然也包括基于WTP開發(fā)一些工具)的開發(fā)者可以做一個(gè)工具,當(dāng)寫代碼分析IStructuredDocument(Text Region)和IDOMDocument(Indexed Region)遇到障礙的時(shí)候,這兩個(gè)視圖應(yīng)該做為一個(gè)助手^_^。而且通過這兩個(gè)視圖內(nèi)容顯示的比較,應(yīng)該會(huì)明白為什么IStructuredDocument是語(yǔ)法Document,為什么IDOMDocument(ICSSDocument)是語(yǔ)義Document。
開發(fā)本IStructuredModel(DOM Document)分析視圖很多地方和前面的Structured Document分析視圖類似,有不明白的地方(涉及到技術(shù)實(shí)現(xiàn)的地方),可以參考一下前面的第四節(jié)。
【需求】
和前面的Structured Document分析視圖需求比較類似,大致如下:
1、提供一個(gè)Structured Model分析視圖,以樹狀方式將當(dāng)前編輯器中的IDOMDocument展示出來
2、交互(編輯器 ---> Structured Model分析視圖):
激活WTP JSP編輯器(或者是我們前面自己定制的編輯器),即時(shí)更新Structured Model分析視圖
當(dāng)用戶光在編輯器中標(biāo)移動(dòng)時(shí),自動(dòng)選中Structured Model分析視圖中對(duì)應(yīng)的節(jié)點(diǎn)
當(dāng)編輯器中的內(nèi)容改變時(shí),即時(shí)更新Structured Model分析視圖
當(dāng)前激活編輯器關(guān)閉時(shí),清空Structured Model分析視圖內(nèi)容
3、交互(Structured Model分析視圖 ---> 編輯器)
雙擊視圖中樹狀控件中特定節(jié)點(diǎn),對(duì)應(yīng)內(nèi)容在編輯器中被選中
4、顯示內(nèi)容:
因?yàn)槊總€(gè)節(jié)點(diǎn)都是IDOMNode,則分別顯示其實(shí)現(xiàn)類名稱、位置信息和文本內(nèi)容
【效果預(yù)覽】

上面顯示的效果是,雙擊視圖中對(duì)應(yīng)的IDOMNode,對(duì)應(yīng)的文本內(nèi)容在編輯器中被選中。
【實(shí)現(xiàn)摘要(文章后門會(huì)附上對(duì)應(yīng)的源碼)】
1、創(chuàng)建插件工程wtp.stucturedmodel,創(chuàng)建視圖。視圖IViewPart對(duì)應(yīng)實(shí)現(xiàn)類為StructuredModelView,這個(gè)和前面講過的Structured Document分析視圖類似,這邊就不細(xì)講了。
2、利用workbench中的選擇服務(wù)(seleciton service)。前面需求中說過,我們要監(jiān)聽光標(biāo)在編輯器中的位置選擇,所以使用此服務(wù),所以我們的StructuredModelView要實(shí)現(xiàn)org.eclipse.ui.ISelectionListener接口。
注冊(cè)、銷毀selection listener和前面開發(fā)Structured Document分析視圖是一樣的,在視圖實(shí)現(xiàn)類init方法中注冊(cè),在dispose方法中銷毀。
我們看一下selection事件的處理代碼:
1、如果當(dāng)前選擇事件來自TextEditor類型的編輯器中(文本編輯器的共同超類),則去獲取編輯器對(duì)應(yīng)的IDocument,如果是IStrucuturedDocument則判斷是否需要更新;如果不是,則不是我們的菜^_^
2、利用WTP提供的模型管理器IModelManager(這個(gè)在下一節(jié)會(huì)詳細(xì)講,很重要^_^)獲取和以上IStructuredDocument對(duì)應(yīng)的IStructuredModel(通過IStructuredModel,可以獲取到對(duì)應(yīng)的語(yǔ)義Document--IDOMDocument,前面說過的^_^)。然后判斷是否需要刷新模型tree viewer,判斷的依據(jù)是看tree viewer中現(xiàn)有的input和本IStructuredModel是否一致。
PS:這邊有兩點(diǎn)需要注意:一是IModelStateListener的注冊(cè);二是IModelManager的使用。
3、處理text selection(參見org.eclipse.jface.text.ITexSelection),定位對(duì)應(yīng)的dom node。大致過程為:首先判根據(jù)IStructuredModel.getIndexedRegion獲取對(duì)應(yīng)的節(jié)點(diǎn)(注意這邊只能定位到對(duì)應(yīng)的IDOMElement元素,并不能定到對(duì)應(yīng)的IDOMAttr或者IDOMText);其次判斷光標(biāo)是否位于節(jié)點(diǎn)的attribute中,如果是,則定位到dom attr(具體可以參見代碼)
3、處理視圖中tree viewer雙擊,定位編輯器中對(duì)應(yīng)內(nèi)容。
4、利用IModelStateListener同步更新視圖。我們?cè)谏弦还?jié)在介紹IStructuredModel的時(shí)候,提到過WTP提供了一個(gè)IModelStateListener來允許用戶監(jiān)聽I(yíng)StructuredModel的狀態(tài)變化,IStructuredModel本身又作為一個(gè)target,接受用戶注冊(cè)IModelStateListener實(shí)現(xiàn)。我們的IModelStateListener實(shí)現(xiàn)非常簡(jiǎn)單,只在目標(biāo)IStructuredModel變化了之后,刷新視圖中的tree viewer
5、處理編輯器關(guān)閉行為,利用workbench的part service特性。當(dāng)關(guān)聯(lián)編輯器關(guān)閉時(shí),削減目標(biāo)IStructuredModel的引用計(jì)數(shù),并注銷之前注冊(cè)的IModelStateListener,清空視圖中的tree viewer。
6、tree viewer對(duì)應(yīng)的content provider實(shí)現(xiàn)。(其實(shí)和我們遍歷一個(gè)普通的xml dom document很類似)
以上基本上就是本視圖的主要代碼了,開發(fā)這個(gè)視圖代碼基本上也是300行左右。
本插件工程需要依賴的插件列表為:
org.eclipse.ui,
org.eclipse.core.runtime,
org.eclipse.core.resources,
org.eclipse.wst.sse.core,
org.eclipse.wst.xml.core,
org.eclipse.wst.sse.ui,
org.eclipse.jface.text,
org.eclipse.ui.workbench.texteditor
【源碼下載】
源碼為實(shí)際工程以Export ---> Archive File方式導(dǎo)出的,下載鏈接:Structured Model(Dom Document)分析視圖源碼
前面在講完WTP 語(yǔ)法Document(IStructuredDocument)的時(shí)候,我們開發(fā)過一個(gè)Structured Document分析視圖,我想通過那個(gè)視圖可以加深對(duì)IStructuredDocument的理解。在本節(jié)中,我們?cè)陂_發(fā)一個(gè)視圖,來分析一下WTP的語(yǔ)義Document(我們只分析最常用的IDOMDocument),希望也有類似的作用。
PS:這兩個(gè)視圖其實(shí)可以作為一個(gè)工具來用,對(duì)于想修改或者定制WTP源碼(當(dāng)然也包括基于WTP開發(fā)一些工具)的開發(fā)者可以做一個(gè)工具,當(dāng)寫代碼分析IStructuredDocument(Text Region)和IDOMDocument(Indexed Region)遇到障礙的時(shí)候,這兩個(gè)視圖應(yīng)該做為一個(gè)助手^_^。而且通過這兩個(gè)視圖內(nèi)容顯示的比較,應(yīng)該會(huì)明白為什么IStructuredDocument是語(yǔ)法Document,為什么IDOMDocument(ICSSDocument)是語(yǔ)義Document。
開發(fā)本IStructuredModel(DOM Document)分析視圖很多地方和前面的Structured Document分析視圖類似,有不明白的地方(涉及到技術(shù)實(shí)現(xiàn)的地方),可以參考一下前面的第四節(jié)。
【需求】
和前面的Structured Document分析視圖需求比較類似,大致如下:
1、提供一個(gè)Structured Model分析視圖,以樹狀方式將當(dāng)前編輯器中的IDOMDocument展示出來
2、交互(編輯器 ---> Structured Model分析視圖):
激活WTP JSP編輯器(或者是我們前面自己定制的編輯器),即時(shí)更新Structured Model分析視圖
當(dāng)用戶光在編輯器中標(biāo)移動(dòng)時(shí),自動(dòng)選中Structured Model分析視圖中對(duì)應(yīng)的節(jié)點(diǎn)
當(dāng)編輯器中的內(nèi)容改變時(shí),即時(shí)更新Structured Model分析視圖
當(dāng)前激活編輯器關(guān)閉時(shí),清空Structured Model分析視圖內(nèi)容
3、交互(Structured Model分析視圖 ---> 編輯器)
雙擊視圖中樹狀控件中特定節(jié)點(diǎn),對(duì)應(yīng)內(nèi)容在編輯器中被選中
4、顯示內(nèi)容:
因?yàn)槊總€(gè)節(jié)點(diǎn)都是IDOMNode,則分別顯示其實(shí)現(xiàn)類名稱、位置信息和文本內(nèi)容
【效果預(yù)覽】
上面顯示的效果是,雙擊視圖中對(duì)應(yīng)的IDOMNode,對(duì)應(yīng)的文本內(nèi)容在編輯器中被選中。
【實(shí)現(xiàn)摘要(文章后門會(huì)附上對(duì)應(yīng)的源碼)】
1、創(chuàng)建插件工程wtp.stucturedmodel,創(chuàng)建視圖。視圖IViewPart對(duì)應(yīng)實(shí)現(xiàn)類為StructuredModelView,這個(gè)和前面講過的Structured Document分析視圖類似,這邊就不細(xì)講了。
public class StructuredModelView extends ViewPart implements ISelectionListener{
private TreeViewer viewer;
private ITreeContentProvider contentProvider;
private ILabelProvider labelProvider;
//
}
private TreeViewer viewer;
private ITreeContentProvider contentProvider;
private ILabelProvider labelProvider;
//

}
2、利用workbench中的選擇服務(wù)(seleciton service)。前面需求中說過,我們要監(jiān)聽光標(biāo)在編輯器中的位置選擇,所以使用此服務(wù),所以我們的StructuredModelView要實(shí)現(xiàn)org.eclipse.ui.ISelectionListener接口。
注冊(cè)、銷毀selection listener和前面開發(fā)Structured Document分析視圖是一樣的,在視圖實(shí)現(xiàn)類init方法中注冊(cè),在dispose方法中銷毀。
1 /* (non-Javadoc)
2 * @see org.eclipse.ui.part.ViewPart#init(org.eclipse.ui.IViewSite)
3 */
4 public void init(IViewSite site) throws PartInitException {
5 super.init(site);
6
7 this.getSite().getPage().getWorkbenchWindow().getSelectionService().addPostSelectionListener(this);
8 this.getSite().getPage().getWorkbenchWindow().getPartService().addPartListener(partListener);
9 }
2 * @see org.eclipse.ui.part.ViewPart#init(org.eclipse.ui.IViewSite)
3 */
4 public void init(IViewSite site) throws PartInitException {
5 super.init(site);
6
7 this.getSite().getPage().getWorkbenchWindow().getSelectionService().addPostSelectionListener(this);
8 this.getSite().getPage().getWorkbenchWindow().getPartService().addPartListener(partListener);
9 }
我們看一下selection事件的處理代碼:
1 /* (non-Javadoc)
2 * @see org.eclipse.ui.ISelectionListener#selectionChanged(org.eclipse.ui.IWorkbenchPart, org.eclipse.jface.viewers.ISelection)
3 */
4 public void selectionChanged(IWorkbenchPart part, ISelection selection) {
5 if (part instanceof TextEditor) {
6 IEditorInput editorInput = ((TextEditor)part).getEditorInput();
7 IDocument document = ((TextEditor)part).getDocumentProvider().getDocument(editorInput);
8
9 //判斷是否是IStructuredDocument
10 if (!(document instanceof IStructuredDocument)) {
11 this.viewer.setInput(new Object[0]);
12 return ;
13 }
14
15 //對(duì)于editor使用的IStructuredModel,是用IModelManager來管理的
16 IModelManager modelManager = StructuredModelManager.getModelManager();
17 IStructuredModel structuredModel = modelManager.getModelForRead((IStructuredDocument)document);
18 if (structuredModel == null)
19 return ;
20
21 //根據(jù)判斷是否需要更新tree vier輸入做不同處理
22 if (this.needUpdateInput(structuredModel)) {
23 //減少old model的引用計(jì)數(shù),并注銷對(duì)應(yīng)的model listener
24 if (this.viewer.getInput() instanceof IStructuredModel) {
25 IStructuredModel oldStructuredModel = ((IStructuredModel)this.viewer.getInput());
26
27 oldStructuredModel.removeModelStateListener(modelStateListener);
28 oldStructuredModel.releaseFromRead();
29 }
30
31 //設(shè)置輸入,并注冊(cè)模型狀態(tài)監(jiān)聽器
32 structuredModel.addModelStateListener(this.modelStateListener);
36 }
37 else {
38 //如果不需要此structuredModel作為輸入,則將此structuredModel的引用計(jì)數(shù)復(fù)原
39 structuredModel.releaseFromRead();
40 }
41
42 //根據(jù)編輯器中選擇定位到model tree viewer中相應(yīng)節(jié)點(diǎn)
43 if (selection instanceof ITextSelection)
44 this.processTextSelection((ITextSelection)selection, structuredModel);
45
46 this.sourcePart = part;
47 }
48 }
49
50 /**
51 * 判斷當(dāng)前structuredModel和tree viewer中已有的structured model是否一致(判斷是否==,而非equals)
52 *
53 * @param structuredModel
54 * @return
55 */
56 private boolean needUpdateInput(IStructuredModel structuredModel) {
57 if (this.viewer.getInput() != null)
58 return this.viewer.getInput() != structuredModel;
59
60 return true;
61 }
看的出來,我們的selection處理邏輯如下:2 * @see org.eclipse.ui.ISelectionListener#selectionChanged(org.eclipse.ui.IWorkbenchPart, org.eclipse.jface.viewers.ISelection)
3 */
4 public void selectionChanged(IWorkbenchPart part, ISelection selection) {
5 if (part instanceof TextEditor) {
6 IEditorInput editorInput = ((TextEditor)part).getEditorInput();
7 IDocument document = ((TextEditor)part).getDocumentProvider().getDocument(editorInput);
8
9 //判斷是否是IStructuredDocument
10 if (!(document instanceof IStructuredDocument)) {
11 this.viewer.setInput(new Object[0]);
12 return ;
13 }
14
15 //對(duì)于editor使用的IStructuredModel,是用IModelManager來管理的
16 IModelManager modelManager = StructuredModelManager.getModelManager();
17 IStructuredModel structuredModel = modelManager.getModelForRead((IStructuredDocument)document);
18 if (structuredModel == null)
19 return ;
20
21 //根據(jù)判斷是否需要更新tree vier輸入做不同處理
22 if (this.needUpdateInput(structuredModel)) {
23 //減少old model的引用計(jì)數(shù),并注銷對(duì)應(yīng)的model listener
24 if (this.viewer.getInput() instanceof IStructuredModel) {
25 IStructuredModel oldStructuredModel = ((IStructuredModel)this.viewer.getInput());
26
27 oldStructuredModel.removeModelStateListener(modelStateListener);
28 oldStructuredModel.releaseFromRead();
29 }
30
31 //設(shè)置輸入,并注冊(cè)模型狀態(tài)監(jiān)聽器
32 structuredModel.addModelStateListener(this.modelStateListener);
36 }
37 else {
38 //如果不需要此structuredModel作為輸入,則將此structuredModel的引用計(jì)數(shù)復(fù)原
39 structuredModel.releaseFromRead();
40 }
41
42 //根據(jù)編輯器中選擇定位到model tree viewer中相應(yīng)節(jié)點(diǎn)
43 if (selection instanceof ITextSelection)
44 this.processTextSelection((ITextSelection)selection, structuredModel);
45
46 this.sourcePart = part;
47 }
48 }
49
50 /**
51 * 判斷當(dāng)前structuredModel和tree viewer中已有的structured model是否一致(判斷是否==,而非equals)
52 *
53 * @param structuredModel
54 * @return
55 */
56 private boolean needUpdateInput(IStructuredModel structuredModel) {
57 if (this.viewer.getInput() != null)
58 return this.viewer.getInput() != structuredModel;
59
60 return true;
61 }
1、如果當(dāng)前選擇事件來自TextEditor類型的編輯器中(文本編輯器的共同超類),則去獲取編輯器對(duì)應(yīng)的IDocument,如果是IStrucuturedDocument則判斷是否需要更新;如果不是,則不是我們的菜^_^
2、利用WTP提供的模型管理器IModelManager(這個(gè)在下一節(jié)會(huì)詳細(xì)講,很重要^_^)獲取和以上IStructuredDocument對(duì)應(yīng)的IStructuredModel(通過IStructuredModel,可以獲取到對(duì)應(yīng)的語(yǔ)義Document--IDOMDocument,前面說過的^_^)。然后判斷是否需要刷新模型tree viewer,判斷的依據(jù)是看tree viewer中現(xiàn)有的input和本IStructuredModel是否一致。
PS:這邊有兩點(diǎn)需要注意:一是IModelStateListener的注冊(cè);二是IModelManager的使用。
3、處理text selection(參見org.eclipse.jface.text.ITexSelection),定位對(duì)應(yīng)的dom node。大致過程為:首先判根據(jù)IStructuredModel.getIndexedRegion獲取對(duì)應(yīng)的節(jié)點(diǎn)(注意這邊只能定位到對(duì)應(yīng)的IDOMElement元素,并不能定到對(duì)應(yīng)的IDOMAttr或者IDOMText);其次判斷光標(biāo)是否位于節(jié)點(diǎn)的attribute中,如果是,則定位到dom attr(具體可以參見代碼)
3、處理視圖中tree viewer雙擊,定位編輯器中對(duì)應(yīng)內(nèi)容。
this.viewer.addDoubleClickListener(new IDoubleClickListener() {
public void doubleClick(DoubleClickEvent event) {
TreeSelection selection = (TreeSelection)event.getSelection();
//樹上的每個(gè)節(jié)點(diǎn)都是indexed region
IndexedRegion indexedRegion = (IndexedRegion)selection.getFirstElement();
//處理編輯器選中
int selectionOffset = indexedRegion.getStartOffset();
int length = indexedRegion.getEndOffset() - selectionOffset;
((StructuredTextEditor)sourcePart).getTextViewer().setSelectedRange(selectionOffset, length);
}
});
上面我們根據(jù)tree viewer中選中的indexed region對(duì)應(yīng)的坐標(biāo),直接通過ITextViewer.setSelectedRange(int offset, int length)接口來進(jìn)行文本選中。(PS:WTP提供的StructuredText本身就是一種ISourceViewer,ISourceViewer本身又是一種ITextViewer^_^)public void doubleClick(DoubleClickEvent event) {
TreeSelection selection = (TreeSelection)event.getSelection();
//樹上的每個(gè)節(jié)點(diǎn)都是indexed region
IndexedRegion indexedRegion = (IndexedRegion)selection.getFirstElement();
//處理編輯器選中
int selectionOffset = indexedRegion.getStartOffset();
int length = indexedRegion.getEndOffset() - selectionOffset;
((StructuredTextEditor)sourcePart).getTextViewer().setSelectedRange(selectionOffset, length);
}
});
4、利用IModelStateListener同步更新視圖。我們?cè)谏弦还?jié)在介紹IStructuredModel的時(shí)候,提到過WTP提供了一個(gè)IModelStateListener來允許用戶監(jiān)聽I(yíng)StructuredModel的狀態(tài)變化,IStructuredModel本身又作為一個(gè)target,接受用戶注冊(cè)IModelStateListener實(shí)現(xiàn)。我們的IModelStateListener實(shí)現(xiàn)非常簡(jiǎn)單,只在目標(biāo)IStructuredModel變化了之后,刷新視圖中的tree viewer
private class ModelStateListener implements IModelStateListener {
/* (non-Javadoc)
* @see org.eclipse.wst.sse.core.internal.provisional.IModelStateListener#modelChanged(org.eclipse.wst.sse.core.internal.provisional.IStructuredModel)
*/
public void modelChanged(IStructuredModel model) {
viewer.refresh();
}
//只覆寫了該方法,其他方法代碼省略
}
/* (non-Javadoc)
* @see org.eclipse.wst.sse.core.internal.provisional.IModelStateListener#modelChanged(org.eclipse.wst.sse.core.internal.provisional.IStructuredModel)
*/
public void modelChanged(IStructuredModel model) {
viewer.refresh();
}
//只覆寫了該方法,其他方法代碼省略
}
5、處理編輯器關(guān)閉行為,利用workbench的part service特性。當(dāng)關(guān)聯(lián)編輯器關(guān)閉時(shí),削減目標(biāo)IStructuredModel的引用計(jì)數(shù),并注銷之前注冊(cè)的IModelStateListener,清空視圖中的tree viewer。
private class PartListener implements IPartListener {
public void partActivated(IWorkbenchPart part) {
// TODO Auto-generated method stub
}
public void partBroughtToTop(IWorkbenchPart part) {
// TODO Auto-generated method stub
}
/*
* 如果被關(guān)閉的workbench part是提供structured model信息的source part,則:
* 1、削減該structured model的引用計(jì)數(shù)(因?yàn)橐呀?jīng)不再引用)
* 2、注銷之前注冊(cè)的IModelStateListener
* 3、清空tree viewer
*
* @see org.eclipse.ui.IPartListener#partClosed(org.eclipse.ui.IWorkbenchPart)
*/
public void partClosed(IWorkbenchPart part) {
//削減引用計(jì)數(shù),并注銷對(duì)應(yīng)的model listener
if (part == StructuredModelView.this) {
if (viewer.getInput() instanceof IStructuredModel) {
IStructuredModel structuredModel = ((IStructuredModel)viewer.getInput());
structuredModel.releaseFromRead();
structuredModel.removeModelStateListener(modelStateListener);
}
}
//update model tree viewer
if (sourcePart == part) {
sourcePart = null;
viewer.setInput(null);
}
}
public void partDeactivated(IWorkbenchPart part) {
// TODO Auto-generated method stub
}
public void partOpened(IWorkbenchPart part) {
// TODO Auto-generated method stub
}
}
public void partActivated(IWorkbenchPart part) {
// TODO Auto-generated method stub
}
public void partBroughtToTop(IWorkbenchPart part) {
// TODO Auto-generated method stub
}
/*
* 如果被關(guān)閉的workbench part是提供structured model信息的source part,則:
* 1、削減該structured model的引用計(jì)數(shù)(因?yàn)橐呀?jīng)不再引用)
* 2、注銷之前注冊(cè)的IModelStateListener
* 3、清空tree viewer
*
* @see org.eclipse.ui.IPartListener#partClosed(org.eclipse.ui.IWorkbenchPart)
*/
public void partClosed(IWorkbenchPart part) {
//削減引用計(jì)數(shù),并注銷對(duì)應(yīng)的model listener
if (part == StructuredModelView.this) {
if (viewer.getInput() instanceof IStructuredModel) {
IStructuredModel structuredModel = ((IStructuredModel)viewer.getInput());
structuredModel.releaseFromRead();
structuredModel.removeModelStateListener(modelStateListener);
}
}
//update model tree viewer
if (sourcePart == part) {
sourcePart = null;
viewer.setInput(null);
}
}
public void partDeactivated(IWorkbenchPart part) {
// TODO Auto-generated method stub
}
public void partOpened(IWorkbenchPart part) {
// TODO Auto-generated method stub
}
}
6、tree viewer對(duì)應(yīng)的content provider實(shí)現(xiàn)。(其實(shí)和我們遍歷一個(gè)普通的xml dom document很類似)
public class ModelTreeContentProvider implements ITreeContentProvider {
/*
* IStructuredModel分為兩種:IDOMModel和ICSSModel,對(duì)應(yīng)的document實(shí)現(xiàn)分別為IDOMDocument和ICSSDocument。
* 我們只分析IDOMModel(IDOMDocument)的情況,對(duì)于ICSSModel(ICSSDocument)的分析留給大家吧^_^
*
* @see org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java.lang.Object)
*/
public Object[] getChildren(Object parentElement) {
if (parentElement == null)
return new Object[0];
//如果是IDOMModel,則獲取對(duì)應(yīng)的IDOMDocument
if (parentElement instanceof IDOMModel) {
IDOMDocument domDocument = ((IDOMModel)parentElement).getDocument();
return new Object[]{domDocument};
}
//對(duì)于遵守xml dom規(guī)范的node,則按照xml node的結(jié)構(gòu)來遍歷
if (parentElement instanceof IDOMNode) {
List children = new ArrayList();
NamedNodeMap attributes = ((IDOMNode)parentElement).getAttributes();
if (attributes != null) {
for (int i = 0; i < attributes.getLength(); i++) {
children.add(attributes.item(i));
}
}
NodeList childNodes = ((IDOMNode)parentElement).getChildNodes();
for (int i = 0; i < childNodes.getLength(); i++) {
children.add(childNodes.item(i));
}
return children.toArray();
}
return new Object[0];
}
//其他方法省略
}
/*
* IStructuredModel分為兩種:IDOMModel和ICSSModel,對(duì)應(yīng)的document實(shí)現(xiàn)分別為IDOMDocument和ICSSDocument。
* 我們只分析IDOMModel(IDOMDocument)的情況,對(duì)于ICSSModel(ICSSDocument)的分析留給大家吧^_^
*
* @see org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java.lang.Object)
*/
public Object[] getChildren(Object parentElement) {
if (parentElement == null)
return new Object[0];
//如果是IDOMModel,則獲取對(duì)應(yīng)的IDOMDocument
if (parentElement instanceof IDOMModel) {
IDOMDocument domDocument = ((IDOMModel)parentElement).getDocument();
return new Object[]{domDocument};
}
//對(duì)于遵守xml dom規(guī)范的node,則按照xml node的結(jié)構(gòu)來遍歷
if (parentElement instanceof IDOMNode) {
List children = new ArrayList();
NamedNodeMap attributes = ((IDOMNode)parentElement).getAttributes();
if (attributes != null) {
for (int i = 0; i < attributes.getLength(); i++) {
children.add(attributes.item(i));
}
}
NodeList childNodes = ((IDOMNode)parentElement).getChildNodes();
for (int i = 0; i < childNodes.getLength(); i++) {
children.add(childNodes.item(i));
}
return children.toArray();
}
return new Object[0];
}
//其他方法省略
}
以上基本上就是本視圖的主要代碼了,開發(fā)這個(gè)視圖代碼基本上也是300行左右。
本插件工程需要依賴的插件列表為:
org.eclipse.ui,
org.eclipse.core.runtime,
org.eclipse.core.resources,
org.eclipse.wst.sse.core,
org.eclipse.wst.xml.core,
org.eclipse.wst.sse.ui,
org.eclipse.jface.text,
org.eclipse.ui.workbench.texteditor
【源碼下載】
源碼為實(shí)際工程以Export ---> Archive File方式導(dǎo)出的,下載鏈接:Structured Model(Dom Document)分析視圖源碼
本博客中的所有文章、隨筆除了標(biāo)題中含有引用或者轉(zhuǎn)載字樣的,其他均為原創(chuàng)。轉(zhuǎn)載請(qǐng)注明出處,謝謝!
posted on 2008-09-17 16:24 zhuxing 閱讀(2440) 評(píng)論(3) 編輯 收藏 所屬分類: Eclipse Plug-in & OSGI 、WTP(Web Tools Platform)