在本小節(jié)中,無論如何先把自己的編輯器給搞出來,為我們后面對wtp提供的JSP編輯器進(jìn)行定制。
【開發(fā)環(huán)境準(zhǔn)備】
1、Eclipse 3.2 + WTP 1.5
2、對應(yīng)的GEF(3.2.1)、EMF(2.2.1)系列插件
3、將必要插件導(dǎo)入到工作區(qū),導(dǎo)入插件列表如下:
因?yàn)槲覀儠簳r(shí)只是閱讀并不打算修改wtp源碼,所以就先以二進(jìn)制方式導(dǎo)入,以上導(dǎo)入的6個(gè)插件以后要和我們常打交道~_~。
說明:
Eclipse 3.3、3.4也可以,wtp 2.0版本也可以,只要是有對應(yīng)版本的gef和emf與之配套
【JFace Text Framework & Eclipse Editor Framework】
我們知道Eclipse為我們提供了一個(gè)文本編輯器框架,個(gè)人覺得最核心的角色是:IEditorPart、IDocumentProvider和SourceViewerConfiguration。
【角色介紹】
1、
org.eclipse.ui.IEditorPart:
IWorkbenchPart的一種擴(kuò)展實(shí)現(xiàn)(另一種是IViewPart),編輯器的真正主體,需要和IEditorSite、IWorkbenchPage等協(xié)作。Eclipse為我們準(zhǔn)備了默認(rèn)的文本編輯器實(shí)現(xiàn)(AbstractTextEditor),繼承體系如下:

上圖中的StructuredTextEditor就是我們wtp提供的JSP編輯器實(shí)現(xiàn),看得出來是一種文本編輯器實(shí)現(xiàn)。
和IEditorPart密切相關(guān)的是如何定制和本編輯器類型相關(guān)的工作臺(tái)工具欄和菜單:一個(gè)是
org.eclipse.ui.IEditorActionBarContributor接口,和編輯器擴(kuò)展點(diǎn)org.eclipse.ui.editors配合使用;另一個(gè)是
org.eclipse.ui.editorActions擴(kuò)展點(diǎn)。WTP提供了相應(yīng)的IEditorActionBarContributor實(shí)現(xiàn):

ISourceViewerActionBarContributor類型及其子類型都是由WTP提供,有興趣可以看一下。
注意點(diǎn):IEditorActionBarContributor實(shí)現(xiàn)是和編輯器類型綁定的,在多個(gè)編輯器實(shí)例間共享。
2、
org.eclipse.ui.texteditor.IDocumentProvider:
核心作用就是提供JFace Text Framework中org.eclipse.jface.text.IDocument實(shí)現(xiàn)。

上圖中的StructuredModelDocumentProvider和StorageModelModelProvider就是WTP提供的兩個(gè)IDocumentProvider實(shí)現(xiàn)。
文本編輯器公共父類中提供了配置IDocumentProvider實(shí)現(xiàn)的方法:org.eclipse.ui.texteditor.AbstractDecoratedTextEditor.setDocumentProvider(IEditorInput)。
3、
org.eclipse.jface.text.source.SourceViewerConfiguration:這是JFace Text Framework提供的一個(gè)重要概念,用來對SourceViewer(一般是用來顯示編輯source code,全名為
org.eclipse.jface.text.source.SourceViewer)進(jìn)行配置。可以配置的內(nèi)容包括:自動(dòng)提示策略、自動(dòng)編輯器策略等等。SourceViewer中提供了對應(yīng)的配置行為接口:
SourceViewer.configure(SourceViewerConfiguration configuration),這個(gè)配置過程一般發(fā)生在IEditorPart.createPartControl過程中,因?yàn)閟ource viewer實(shí)例的創(chuàng)建包含在IEditorPart.createPartControl過程中。

上圖中的StructuredTextViewer就是WTP提供的編輯器各種頁面資源代碼(包括jsp、html等)所使用的SourceViewer實(shí)現(xiàn)。如果我們進(jìn)行定制,那么就給StructuredTextViewer配置一個(gè)我們自己的SourceViewerConfiguration ^_^

上圖中的StructuredTextViewerConfigurationJSP就是WTP針對JSP文件類型提供的SourceViewerConfiguration實(shí)現(xiàn)。
【角色之間的關(guān)系】
1、org.eclipse.ui.editors擴(kuò)展和IEditorPart之間的關(guān)系
一個(gè)org.eclipse.ui.editors擴(kuò)展會(huì)指定一個(gè)對應(yīng)的IEditorPart實(shí)現(xiàn),一個(gè)IEditorPart實(shí)現(xiàn)可以被用在多個(gè)org.eclipse.ui.editors擴(kuò)展中,也就是說IEditorPart相對于org.eclipse.ui.editors擴(kuò)展是1:N的關(guān)系。
例如WTP提供的StructuredTextEditor是一個(gè)文本類型editor part實(shí)現(xiàn),其在org.eclipse.jst.jsp.ui、org.eclipse.wst.html.ui等多個(gè)插件中被注冊,它被WTP用來編輯jsp、html等多種資源。例如:
<!-- 摘自org.eclipse.jst.jsp.ui插件plugin.xml -->
<editor
name="%JSP_Source_Page_Editor.name"
icon="$nl$/icons//full/obj16/sourceEditor.gif"
extensions="jsp, jsf, jspf, jspx, tag, tagf"
contributorClass="org.eclipse.jst.jsp.ui.internal.editor.ActionContributorJSP"
class="org.eclipse.wst.sse.ui.StructuredTextEditor"
symbolicFontName="org.eclipse.wst.sse.ui.textfont"
id="org.eclipse.jst.jsp.core.jspsource.source">
<contentTypeBinding
contentTypeId="org.eclipse.jst.jsp.core.jspsource" />
</editor>
<!-- 摘自org.eclipse.wst.html.ui插件plugin.xml -->
<editor
name="%HTML_Source_Page_Editor.name"
icon="$nl$/icons/full/obj16/sourceEditor.gif"
contributorClass="org.eclipse.wst.html.ui.internal.edit.ui.ActionContributorHTML"
class="org.eclipse.wst.sse.ui.StructuredTextEditor"
symbolicFontName="org.eclipse.wst.sse.ui.textfont"
id="org.eclipse.wst.html.core.htmlsource.source">
<contentTypeBinding
contentTypeId="org.eclipse.wst.html.core.htmlsource" />
</editor>
2、IEditorPart和IEditorActionBarContributor之間的關(guān)系
上面已經(jīng)說過,多個(gè)IEditorPart實(shí)例共享同一個(gè)IEditorActionBarContributor實(shí)例。結(jié)合具體場景講,例如用同一種類型的JSP編輯器打開了10個(gè)JSP文件,每次都會(huì)產(chǎn)生一個(gè)新的該類型IEditorPart實(shí)例,但是對應(yīng)的是同一個(gè)IEditorActionBarContributor實(shí)例。
一個(gè)IEditorPart實(shí)現(xiàn)可以被注冊多次(上面第一個(gè)點(diǎn)說過),每次可以配置不同類型的IEditorActionBarContributor實(shí)現(xiàn)。
<!-- 摘自org.eclipse.jst.jsp.ui插件plugin.xml -->
<editor
name="%JSP_Source_Page_Editor.name"
icon="$nl$/icons//full/obj16/sourceEditor.gif"
extensions="jsp, jsf, jspf, jspx, tag, tagf"
contributorClass="org.eclipse.jst.jsp.ui.internal.editor.ActionContributorJSP"
class="org.eclipse.wst.sse.ui.StructuredTextEditor"
symbolicFontName="org.eclipse.wst.sse.ui.textfont"
id="org.eclipse.jst.jsp.core.jspsource.source">
<contentTypeBinding
contentTypeId="org.eclipse.jst.jsp.core.jspsource" />
</editor>
<!-- 摘自org.eclipse.wst.html.ui插件plugin.xml -->
<editor
name="%HTML_Source_Page_Editor.name"
icon="$nl$/icons/full/obj16/sourceEditor.gif"
contributorClass="org.eclipse.wst.html.ui.internal.edit.ui.ActionContributorHTML"
class="org.eclipse.wst.sse.ui.StructuredTextEditor"
symbolicFontName="org.eclipse.wst.sse.ui.textfont"
id="org.eclipse.wst.html.core.htmlsource.source">
<contentTypeBinding
contentTypeId="org.eclipse.wst.html.core.htmlsource" />
</editor>
上面可以看出來,當(dāng)StructuredTextEditor被配置用來綁定jsp文件類型的時(shí)候,給它配置的是ActionContributorJSP,當(dāng)StructuredTextEditor被配置用來綁定html文件類型的時(shí)候,給它配置的是ActionContributorHTML。那就是說,當(dāng)我們用StructuredTextEditor分別開發(fā)jsp和html的時(shí)候,工作臺(tái)工具欄和菜單欄可能會(huì)有所不同^_^
3、SourceViewer和SourceViewerConfiguration 之間的關(guān)系
SourceViewer的很多行為是由SourceViewerConfiguration制定的,前者承擔(dān)的可以認(rèn)為是source viewer的核心行為,例如綁定document、annotation model等等,后者可以認(rèn)為是前者對應(yīng)的服務(wù)接口,提供額外服務(wù)。對于同一個(gè)SourceViewer實(shí)例,可以用不同類型SourceViewerConfiguration進(jìn)行配置,以達(dá)到定制的效果,外在行為則看起來就會(huì)有所不同。
上面說過,WTP在編輯jsp、html等頁面資源類型的時(shí)候其實(shí)對應(yīng)都是StructuredTextEditor,但是使用過的就會(huì)知道,自動(dòng)提示等等行為還是有所不同的。StructuredTextEditor持有的是同種類型的SourceViewer實(shí)現(xiàn):org.eclipse.wst.sse.ui.internal.StructuredTextViewer,但是,如果給StructuredTextViewer配置不同的SourceViewerConfiguration,則就可以定制其行為了^_^。 當(dāng)用StructuredTextEditor打開jsp文件時(shí),在StructuredTextEditor.createPartControl過程中給其配置StructuredTextViewerConfigurationJSP,當(dāng)用StructuredTextEditor打開html文件時(shí),在StructuredTextEditor.createPartControl過程中給其配置StructuredTextViewerConfigurationHTML...
【W(wǎng)TP StructuredTextEditor分析】
其實(shí)上面已經(jīng)分析了建立一個(gè)編輯器擴(kuò)展所依賴的關(guān)鍵角色,那么我們看一下WTP提供的用來編輯jsp、html等多種頁面資源的StructuredTextEditor是如何配置起來的。
IEditorPart:StructuredTextEditor
IEditorActionBarContributor:提供了ActionContributorJSP等多種實(shí)現(xiàn),通過org.eclipse.ui.editors擴(kuò)展來和StructuredTextEditor集成
IDocumentProvider:提供了StructuredModelDocumentProvider和StorageModelModelProvider兩種實(shí)現(xiàn),通過StructuredTextEditor.setDocumentProvider(IEditorInput)完成
ISourceViewer:StructuredTextViewer
SourceViewerConfiguration:提供StructuredTextViewerConfigurationJSP、StructuredTextViewerConfigurationHTML等多種實(shí)現(xiàn),在StructuredTextEditor.createPartControl過程中對StructuredTextViewer進(jìn)行配置。
【基于WTP創(chuàng)建自定義的JSP編輯器擴(kuò)展】
到這里,有關(guān)eclipse文本編輯器框架中各個(gè)角色以及它們之間的關(guān)系都基本上已經(jīng)清楚了。那我們看一下如何基于WTP創(chuàng)建自定義的JSP編輯器擴(kuò)展:
1、IEditorPart角色:
創(chuàng)建一個(gè)自定義IEditorPart實(shí)現(xiàn),直接繼承自WTP的StructuredTextEditor,暫定名字為JSPEditor。因?yàn)槲覀兒竺嬉赾reatePartControl中對WTP的StrcuturedTextViewer進(jìn)行config。
2、IEditorActionBarContributor角色:目前我們不打算提供定制工作臺(tái)菜單欄和工具欄,所以直接復(fù)用ActionContributorJSP
3、IDocumentProvider角色:直接復(fù)用WTP已有的,我們不打算提供我們自定義的IDocument實(shí)現(xiàn),我們只是定制編輯器外在的行為^_^
4、ISourceViewer角色:直接復(fù)用WTP提供的StrcuturedTextViewer
5、SourceViewerConfiguration角色:因?yàn)槭俏覀円ㄖ芖TP的StrcuturedTextViewer,例如后門定制自動(dòng)提示等等,所以
我們提供一個(gè)SourceViewerConfiguration,繼承自StructuredTextViewerConfigurationJSP,暫定名為JSPStructuredTextViewerConfiguration。
【主要代碼】
首先創(chuàng)建一個(gè)插件工程,我這邊叫做jspeditor,依賴如下插件:
org.eclipse.ui,
org.eclipse.core.runtime,
org.eclipse.wst.sse.ui,
org.eclipse.jface.text,
org.eclipse.ui.workbench.texteditor,
org.eclipse.jst.jsp.ui
接著創(chuàng)建我們自己的SourceViewerConfiguration:
//JSPStructuredTextViewerConfiguration.java
package jspeditor.configuration;
import org.eclipse.jst.jsp.ui.StructuredTextViewerConfigurationJSP;
/**
* 自定義StructuredTextViewerConfiguration,基于WTP jst提供的StructuredTextViewerConfigurationJSP,
* 后面會(huì)提供自定義的自動(dòng)提示策略等擴(kuò)展。
*
* @author zhuxing (mailto:zhu_xing@live.cn)
*/
/*
* 修改歷史
* $Log$
*/
public class JSPStructuredTextViewerConfiguration extends
StructuredTextViewerConfigurationJSP {
}
暫時(shí)還是個(gè)空殼子^_^, 后面會(huì)往里填充東西的。
再者,創(chuàng)建我們的IEditorPart主體類,并覆寫createPartControl過程,用我們自己的JSPStructuredTextViewerConfiguration配置WTP的SourceViewer(StructuredTextViewer):
1 package jspeditor;
2
3 import jspeditor.configuration.JSPStructuredTextViewerConfiguration;
4
5 import org.eclipse.jface.text.source.SourceViewerConfiguration;
6 import org.eclipse.swt.widgets.Composite;
7 import org.eclipse.ui.texteditor.IDocumentProvider;
8 import org.eclipse.wst.sse.ui.StructuredTextEditor;
9
10 /**
11 * 基于WTP的自定義JSP編輯器。
12 *
13 * @author zhuxing (mailto:zhu_xing@live.cn)
14 */
15 /*
16 * 修改歷史
17 * $Log$
18 */
19 public class JSPEditor extends StructuredTextEditor {
20
21 /* (non-Javadoc)
22 * @see org.eclipse.wst.sse.ui.StructuredTextEditor#createPartControl(org.eclipse.swt.widgets.Composite)
23 */
24 public void createPartControl(Composite parent) {
25 super.createPartControl(parent);
26
27 //用自定義的source viewer configuration配置WTP提供的SourceViewer實(shí)現(xiàn)(StrcuturedTextViewer)
28 SourceViewerConfiguration configuration = new JSPStructuredTextViewerConfiguration();
29 this.setSourceViewerConfiguration(configuration);
30 }
31
32 /*
33 * 保持WTP原有實(shí)現(xiàn)
34 *
35 * @see org.eclipse.ui.texteditor.AbstractDecoratedTextEditor#getDocumentProvider()
36 */
37 public IDocumentProvider getDocumentProvider() {
38 // TODO Auto-generated method stub
39 return super.getDocumentProvider();
40 }
41
42 /* (non-Javadoc)
43 * @see org.eclipse.wst.sse.ui.StructuredTextEditor#setSourceViewerConfiguration(org.eclipse.jface.text.source.SourceViewerConfiguration)
44 */
45 protected void setSourceViewerConfiguration(SourceViewerConfiguration configuration) {
46 // TODO Auto-generated method stub
47 super.setSourceViewerConfiguration(configuration);
48 }
49
50 }
最后,查看org.eclipse.ui.eidtors擴(kuò)展點(diǎn)契約,提供擴(kuò)展:
<extension
point="org.eclipse.ui.editors">
<editor
class="jspeditor.JSPEditor"
contributorClass="org.eclipse.jst.jsp.ui.internal.editor.ActionContributorJSP"
default="true"
extensions="jsp, jsf, jspf, jspx, tag, tagf"
icon="icons/jsp_editor.JPG"
id="jspeditor.editor"
name="自定義WTP JSP編輯器">
<contentTypeBinding contentTypeId="org.eclipse.jst.jsp.core.jspsource"/>
</editor>
</extension>
我做的編輯器圖標(biāo)^_^:
【效果預(yù)覽】
^_^,我們第一步完成了。
以后的幾個(gè)小節(jié),我們需要先停一下了,好好地分析一下WTP的數(shù)據(jù)模型,這是基礎(chǔ)中的基礎(chǔ)!!!
【源碼下載】
下載鏈接:
基于WTP自定義JSP編輯器源碼
本博客中的所有文章、隨筆除了標(biāo)題中含有引用或者轉(zhuǎn)載字樣的,其他均為原創(chuàng)。轉(zhuǎn)載請注明出處,謝謝!