【Eclipse插件開發(fā)】基于WTP開發(fā)自定義的JSP編輯器(十二):定制自動編輯策略(Auto Edit Strategy)
JFace Text Framework框架的一個重要的功能特征就是自動編輯策略,它允許用戶對輸入的內(nèi)容(準(zhǔn)確的說應(yīng)該是即將來臨的Document修改^_^)做即時編輯,然后又會透明的將用戶的修改付諸于實(shí)現(xiàn)(即應(yīng)用到當(dāng)前文檔)。在本節(jié),我們將在前兩節(jié)有關(guān)TLD Content Model的基礎(chǔ)上開發(fā)一個自動編輯策略。
【JFace Text Framework 自動編輯策略原理介紹】
【JDT Java源碼編輯器自動編輯策略演示】
我們每個使用Eclipse JDT進(jìn)行Java編程的開發(fā)者都會對JDT中Java源碼編輯器的自動編輯策略印象深刻,它給編碼人員帶來了很大的方便。舉例如下:

如上圖所示,我們在編寫一個新的函數(shù),圖中黑色豎線“|”就是光標(biāo)所在處,當(dāng)我們按下回車鍵的時候,效果變?yōu)槿缦拢?br />
如上圖所示,當(dāng)我們輸入回車鍵之后,JDT Java源碼編輯器自動幫我們矯正了內(nèi)容(text)和位置(offset):原來的輸入內(nèi)容應(yīng)該是“\r\n”,JDT Java源碼編輯器自動幫我們矯正為“\r\n\t\t\r\n\t}”;根據(jù)“\r\n”內(nèi)容推算,輸入后光標(biāo)位置應(yīng)該位于28行的起始處,JDT Java源碼編輯器自動幫我們矯正為離28行其實(shí)處兩個“\t”的距離。
【自動編輯流程和主要角色】

上圖就演示了自動編輯過程:
1、用戶編輯,鍵盤事件
2、根據(jù)鍵盤事件,對事件信息進(jìn)行分析,拼裝到名為DocumentCommand的數(shù)據(jù)結(jié)構(gòu)中,該數(shù)據(jù)結(jié)構(gòu)中包含了用戶的輸入內(nèi)容(text)、光標(biāo)位置(offset)等信息,例如,上面JDT的例子中用戶的輸入內(nèi)容為“\r\n”。這一步JFace Text Framework幫用戶解決了。
3、調(diào)用自動編輯策略,對應(yīng)DocumentCommand中數(shù)據(jù)進(jìn)行自定義矯正,例如,JDT Java源碼編輯器的自動編輯策略將輸入內(nèi)容矯正為“\r\n\t\t\r\n\t}”。用戶自己負(fù)責(zé),JDT Java源碼編輯器在這邊干活了,提供了自己的IAutoEditStrategy^_^
4、將用戶矯正后的DocumentCommand應(yīng)用到對應(yīng)編輯器(說白了,就是轉(zhuǎn)化為一個Document replace動作執(zhí)行)。這一步JFace Text Framework幫用戶解決了。
我們可以看到,JFace Text Framework已經(jīng)替我們干了大部分活,我們需要關(guān)心的是如下兩個角色:
org.eclipse.jface.text.DocumentCommand:數(shù)據(jù)載體,封裝了一個文本變化(text modification)的信息,例如輸入內(nèi)容(text)、光標(biāo)位置(offset)、長度(length)等等。我們要做的恰恰就是在我們自己的自動編輯策略中對DocumentCommand中的內(nèi)容做矯正,然后JFace Text Framework會自動幫我們應(yīng)用到目標(biāo)IDocument中。
org.eclipse.jface.text.IAutoEditStrategy:自動編輯編輯策略,根據(jù)不同應(yīng)用場景對DocumentCommand中的信息做不同的矯正。我們看一下其接口定義就知道了:
【配置IAutoEditStrategy到SourceViewer】
上面我們已經(jīng)講了自動編輯的流程和主要角色,可以大家都有個疑問:IAutoEditStrategy到底是如何被自動調(diào)用的?IAutoEditStrategy實(shí)現(xiàn)需要被配置到對應(yīng)的SourceViewerConfiguration中,并和對應(yīng)的內(nèi)容類型(很多時候也可以理解為分區(qū)類型)綁定。JFace Text Framework會在初始化編輯器實(shí)例的時候讀取用戶的配置,然后根據(jù)不同的內(nèi)容類型去查找對應(yīng)的自動編輯器策略。
附加說明:1、有關(guān)內(nèi)容類型(分區(qū)類型)可以參考前面章節(jié)的內(nèi)容; 2、原有的IAutoIndentStrategy接口Eclipse已經(jīng)不推薦使用^_^
【定制WTP StructuredTextEditor的自動編輯策略】
【需求】
當(dāng)用戶輸入標(biāo)簽結(jié)束符“>”時,如果標(biāo)簽在TLD中定義為不含有標(biāo)簽體(即bodycontent屬性值為empty),則自動將用戶的輸入內(nèi)容矯正為“/>”。
【前提知識】
對WTP基本數(shù)據(jù)模型不很了解的可以參見一下前面的相關(guān)章節(jié):
【Eclipse插件開發(fā)】基于WTP開發(fā)自定義的JSP編輯器(三) :WTP Structured Document
【Eclipse插件開發(fā)】基于WTP開發(fā)自定義的JSP編輯器(五) :WTP Structured Model
【Eclipse插件開發(fā)】基于WTP開發(fā)自定義的JSP編輯器(七):WTP數(shù)據(jù)模型總結(jié)和模型管理
【Eclipse插件開發(fā)】基于WTP開發(fā)自定義的JSP編輯器(十):WTP TLD內(nèi)容模型介紹
【開發(fā)自定義的IAutoEditStrategy實(shí)現(xiàn)】
基本流程如下:
1、執(zhí)行條件判斷,我這邊假設(shè)用戶正在標(biāo)簽名區(qū)域編輯(通過判斷編輯區(qū)域region的region type來判斷),并且編輯位置位于標(biāo)簽名內(nèi)容末端
2、查詢和當(dāng)前文檔中特定位置相關(guān)的WTP TLD內(nèi)容模型,判斷該標(biāo)簽在TLD文件中定義的時候是否聲明允許有標(biāo)簽體
3、如果標(biāo)簽在TLD中定義為不含有標(biāo)簽體,則矯正為自動閉合,“>”--->“/>”
PS:有關(guān)語法Document、語義Doucment、WTP TLD Content Document等數(shù)據(jù)類型相關(guān)內(nèi)容請參見前面的章節(jié)。
【配置SourceViewerConfiguration】
將我們上面的開發(fā)的自動編輯策略配置到我們的SourceViewerConfiguration實(shí)現(xiàn)中:
根據(jù)需求,當(dāng)我們在圖中光標(biāo)位置輸入“>”的時候,我們前面開發(fā)的自動編輯策略會自動將其矯正為合法的結(jié)束符“/>”,效果如下:

對比如下,如果沒有應(yīng)用自動編輯策略,則會得到如下源碼校驗(yàn)錯誤:

【后記】
提醒:從需求上講,我們示例中開發(fā)的自動編輯策略其實(shí)是非常簡單的。但是將其放置到一個定制WTP StructuredTextEditor的場景中,就不可避免的和我們前面介紹的WTP基礎(chǔ)數(shù)據(jù)模型的知識打交道,在這里再次強(qiáng)調(diào),前面介紹的WTP各種數(shù)據(jù)模型一定要熟練搞清楚,基礎(chǔ)中的基礎(chǔ)!!!
源碼為實(shí)際工程以Export ---> Archive File方式導(dǎo)出的,下載鏈接:WTP StructuredTextEditor自動編輯策略定制示例源碼
【JFace Text Framework 自動編輯策略原理介紹】
【JDT Java源碼編輯器自動編輯策略演示】
我們每個使用Eclipse JDT進(jìn)行Java編程的開發(fā)者都會對JDT中Java源碼編輯器的自動編輯策略印象深刻,它給編碼人員帶來了很大的方便。舉例如下:
如上圖所示,我們在編寫一個新的函數(shù),圖中黑色豎線“|”就是光標(biāo)所在處,當(dāng)我們按下回車鍵的時候,效果變?yōu)槿缦拢?br />
如上圖所示,當(dāng)我們輸入回車鍵之后,JDT Java源碼編輯器自動幫我們矯正了內(nèi)容(text)和位置(offset):原來的輸入內(nèi)容應(yīng)該是“\r\n”,JDT Java源碼編輯器自動幫我們矯正為“\r\n\t\t\r\n\t}”;根據(jù)“\r\n”內(nèi)容推算,輸入后光標(biāo)位置應(yīng)該位于28行的起始處,JDT Java源碼編輯器自動幫我們矯正為離28行其實(shí)處兩個“\t”的距離。
【自動編輯流程和主要角色】
上圖就演示了自動編輯過程:
1、用戶編輯,鍵盤事件
2、根據(jù)鍵盤事件,對事件信息進(jìn)行分析,拼裝到名為DocumentCommand的數(shù)據(jù)結(jié)構(gòu)中,該數(shù)據(jù)結(jié)構(gòu)中包含了用戶的輸入內(nèi)容(text)、光標(biāo)位置(offset)等信息,例如,上面JDT的例子中用戶的輸入內(nèi)容為“\r\n”。這一步JFace Text Framework幫用戶解決了。
3、調(diào)用自動編輯策略,對應(yīng)DocumentCommand中數(shù)據(jù)進(jìn)行自定義矯正,例如,JDT Java源碼編輯器的自動編輯策略將輸入內(nèi)容矯正為“\r\n\t\t\r\n\t}”。用戶自己負(fù)責(zé),JDT Java源碼編輯器在這邊干活了,提供了自己的IAutoEditStrategy^_^
4、將用戶矯正后的DocumentCommand應(yīng)用到對應(yīng)編輯器(說白了,就是轉(zhuǎn)化為一個Document replace動作執(zhí)行)。這一步JFace Text Framework幫用戶解決了。
我們可以看到,JFace Text Framework已經(jīng)替我們干了大部分活,我們需要關(guān)心的是如下兩個角色:
org.eclipse.jface.text.DocumentCommand:數(shù)據(jù)載體,封裝了一個文本變化(text modification)的信息,例如輸入內(nèi)容(text)、光標(biāo)位置(offset)、長度(length)等等。我們要做的恰恰就是在我們自己的自動編輯策略中對DocumentCommand中的內(nèi)容做矯正,然后JFace Text Framework會自動幫我們應(yīng)用到目標(biāo)IDocument中。
org.eclipse.jface.text.IAutoEditStrategy:自動編輯編輯策略,根據(jù)不同應(yīng)用場景對DocumentCommand中的信息做不同的矯正。我們看一下其接口定義就知道了:
package org.eclipse.jface.text;
/**
* An auto edit strategy can adapt changes that will be applied to
* a text viewer's document. The strategy is informed by the text viewer
* about each upcoming change in form of a document command. By manipulating
* this document command, the strategy can influence in which way the text
* viewer's document is changed. Clients may implement this interface.
*
* @since 2.1
*/
public interface IAutoEditStrategy {
/**
* Allows the strategy to manipulate the document command.
*
* @param document the document that will be changed
* @param command the document command describing the change
*/
void customizeDocumentCommand(IDocument document, DocumentCommand command);
}
/**
* An auto edit strategy can adapt changes that will be applied to
* a text viewer's document. The strategy is informed by the text viewer
* about each upcoming change in form of a document command. By manipulating
* this document command, the strategy can influence in which way the text
* viewer's document is changed. Clients may implement this interface.
*
* @since 2.1
*/
public interface IAutoEditStrategy {
/**
* Allows the strategy to manipulate the document command.
*
* @param document the document that will be changed
* @param command the document command describing the change
*/
void customizeDocumentCommand(IDocument document, DocumentCommand command);
}
【配置IAutoEditStrategy到SourceViewer】
上面我們已經(jīng)講了自動編輯的流程和主要角色,可以大家都有個疑問:IAutoEditStrategy到底是如何被自動調(diào)用的?IAutoEditStrategy實(shí)現(xiàn)需要被配置到對應(yīng)的SourceViewerConfiguration中,并和對應(yīng)的內(nèi)容類型(很多時候也可以理解為分區(qū)類型)綁定。JFace Text Framework會在初始化編輯器實(shí)例的時候讀取用戶的配置,然后根據(jù)不同的內(nèi)容類型去查找對應(yīng)的自動編輯器策略。
package org.eclipse.jface.text.source;
public class SourceViewerConfiguration {
/**
* Returns the auto edit strategies ready to be used with the given source viewer
* when manipulating text of the given content type. For backward compatibility, this implementation always
* returns an array containing the result of {@link #getAutoIndentStrategy(ISourceViewer, String)}.
*
* @param sourceViewer the source viewer to be configured by this configuration
* @param contentType the content type for which the strategies are applicable
* @return the auto edit strategies or <code>null</code> if automatic editing is not to be enabled
* @since 3.1
*/
public IAutoEditStrategy[] getAutoEditStrategies(ISourceViewer sourceViewer, String contentType) {
//
}
}
public class SourceViewerConfiguration {
/**
* Returns the auto edit strategies ready to be used with the given source viewer
* when manipulating text of the given content type. For backward compatibility, this implementation always
* returns an array containing the result of {@link #getAutoIndentStrategy(ISourceViewer, String)}.
*
* @param sourceViewer the source viewer to be configured by this configuration
* @param contentType the content type for which the strategies are applicable
* @return the auto edit strategies or <code>null</code> if automatic editing is not to be enabled
* @since 3.1
*/
public IAutoEditStrategy[] getAutoEditStrategies(ISourceViewer sourceViewer, String contentType) {
//

}
}
附加說明:1、有關(guān)內(nèi)容類型(分區(qū)類型)可以參考前面章節(jié)的內(nèi)容; 2、原有的IAutoIndentStrategy接口Eclipse已經(jīng)不推薦使用^_^
【定制WTP StructuredTextEditor的自動編輯策略】
【需求】
當(dāng)用戶輸入標(biāo)簽結(jié)束符“>”時,如果標(biāo)簽在TLD中定義為不含有標(biāo)簽體(即bodycontent屬性值為empty),則自動將用戶的輸入內(nèi)容矯正為“/>”。
【前提知識】
對WTP基本數(shù)據(jù)模型不很了解的可以參見一下前面的相關(guān)章節(jié):
【Eclipse插件開發(fā)】基于WTP開發(fā)自定義的JSP編輯器(三) :WTP Structured Document
【Eclipse插件開發(fā)】基于WTP開發(fā)自定義的JSP編輯器(五) :WTP Structured Model
【Eclipse插件開發(fā)】基于WTP開發(fā)自定義的JSP編輯器(七):WTP數(shù)據(jù)模型總結(jié)和模型管理
【Eclipse插件開發(fā)】基于WTP開發(fā)自定義的JSP編輯器(十):WTP TLD內(nèi)容模型介紹
【開發(fā)自定義的IAutoEditStrategy實(shí)現(xiàn)】
/**
* 針對JSP_DIRECTIVE分區(qū)的自動編輯策略
*
* @author zhuxing (mailto:zhu_xing@live.cn)
*/
/*
* 修改歷史
* $Log$
*/
public class JSPDirectivePartitionAutoEditStrategy implements IAutoEditStrategy {
/* (non-Javadoc)
* @see org.eclipse.jface.text.IAutoEditStrategy#customizeDocumentCommand(org.eclipse.jface.text.IDocument, org.eclipse.jface.text.DocumentCommand)
*/
public void customizeDocumentCommand(IDocument document, DocumentCommand command) {
String text = command.text;
if (!">".equals(text))
return ;
IStructuredDocument structuredDocument = (IStructuredDocument)document;
IStructuredDocumentRegion structuredDocumentRegion = structuredDocument.getRegionAtCharacterOffset(command.offset);
ITextRegion currentRegion = structuredDocumentRegion.getRegionAtCharacterOffset(command.offset);
int startOffset = structuredDocumentRegion.getStartOffset(currentRegion);
int textLength = currentRegion.getTextLength();
//執(zhí)行前提條件:1、用戶正在標(biāo)簽名區(qū)域編輯;2、用戶編輯位置位于標(biāo)簽名末端
if (currentRegion.getType() == DOMRegionContext.XML_TAG_NAME
&& command.offset >= startOffset + textLength) {
if (!hasBody(structuredDocumentRegion))
command.text = "/>";
}
}
/**
* 查詢對應(yīng)的TLD內(nèi)容模型,判斷該標(biāo)簽在TLD中定義的時候是否含有標(biāo)簽體
*
* @param structuredDocumentRegion
* @return
*/
private boolean hasBody(IStructuredDocumentRegion structuredDocumentRegion) {
//獲取標(biāo)簽名稱
IStructuredDocument structuredDocument = structuredDocumentRegion.getParentDocument();
IStructuredModel structuredModel = StructuredModelManager.getModelManager().getModelForRead(structuredDocument);
IDOMElement domElement = (IDOMElement)structuredModel.getIndexedRegion(structuredDocumentRegion.getStartOffset());
String tagName = domElement.getNodeName();
/**
* 1、獲取位置相關(guān)的TLD Document列表
* 2、查找對應(yīng)的TLD Element(Tag)定義
* 3、判斷TLD Element(Tag)定義中定義的bodycontent屬性是否為“empty”
*/
TLDCMDocumentManager manager = TaglibController.getTLDCMDocumentManager(structuredDocument);
List list = manager.getCMDocumentTrackers(structuredDocumentRegion.getStartOffset());
for (Iterator iter = list.iterator(); iter.hasNext();) {
TaglibTracker tracker = (TaglibTracker) iter.next();
TLDDocument tlDocument = (TLDDocument)tracker.getDocument();
CMNode cmnode = tlDocument.getElements().getNamedItem(tagName);
if (cmnode == null)
continue ;
String bodyType = ((TLDElementDeclaration)cmnode).getBodycontent();
if ("empty".equals(bodyType))
return false;
return true;
}
return false;
}
}
* 針對JSP_DIRECTIVE分區(qū)的自動編輯策略
*
* @author zhuxing (mailto:zhu_xing@live.cn)
*/
/*
* 修改歷史
* $Log$
*/
public class JSPDirectivePartitionAutoEditStrategy implements IAutoEditStrategy {
/* (non-Javadoc)
* @see org.eclipse.jface.text.IAutoEditStrategy#customizeDocumentCommand(org.eclipse.jface.text.IDocument, org.eclipse.jface.text.DocumentCommand)
*/
public void customizeDocumentCommand(IDocument document, DocumentCommand command) {
String text = command.text;
if (!">".equals(text))
return ;
IStructuredDocument structuredDocument = (IStructuredDocument)document;
IStructuredDocumentRegion structuredDocumentRegion = structuredDocument.getRegionAtCharacterOffset(command.offset);
ITextRegion currentRegion = structuredDocumentRegion.getRegionAtCharacterOffset(command.offset);
int startOffset = structuredDocumentRegion.getStartOffset(currentRegion);
int textLength = currentRegion.getTextLength();
//執(zhí)行前提條件:1、用戶正在標(biāo)簽名區(qū)域編輯;2、用戶編輯位置位于標(biāo)簽名末端
if (currentRegion.getType() == DOMRegionContext.XML_TAG_NAME
&& command.offset >= startOffset + textLength) {
if (!hasBody(structuredDocumentRegion))
command.text = "/>";
}
}
/**
* 查詢對應(yīng)的TLD內(nèi)容模型,判斷該標(biāo)簽在TLD中定義的時候是否含有標(biāo)簽體
*
* @param structuredDocumentRegion
* @return
*/
private boolean hasBody(IStructuredDocumentRegion structuredDocumentRegion) {
//獲取標(biāo)簽名稱
IStructuredDocument structuredDocument = structuredDocumentRegion.getParentDocument();
IStructuredModel structuredModel = StructuredModelManager.getModelManager().getModelForRead(structuredDocument);
IDOMElement domElement = (IDOMElement)structuredModel.getIndexedRegion(structuredDocumentRegion.getStartOffset());
String tagName = domElement.getNodeName();
/**
* 1、獲取位置相關(guān)的TLD Document列表
* 2、查找對應(yīng)的TLD Element(Tag)定義
* 3、判斷TLD Element(Tag)定義中定義的bodycontent屬性是否為“empty”
*/
TLDCMDocumentManager manager = TaglibController.getTLDCMDocumentManager(structuredDocument);
List list = manager.getCMDocumentTrackers(structuredDocumentRegion.getStartOffset());
for (Iterator iter = list.iterator(); iter.hasNext();) {
TaglibTracker tracker = (TaglibTracker) iter.next();
TLDDocument tlDocument = (TLDDocument)tracker.getDocument();
CMNode cmnode = tlDocument.getElements().getNamedItem(tagName);
if (cmnode == null)
continue ;
String bodyType = ((TLDElementDeclaration)cmnode).getBodycontent();
if ("empty".equals(bodyType))
return false;
return true;
}
return false;
}
}
基本流程如下:
1、執(zhí)行條件判斷,我這邊假設(shè)用戶正在標(biāo)簽名區(qū)域編輯(通過判斷編輯區(qū)域region的region type來判斷),并且編輯位置位于標(biāo)簽名內(nèi)容末端
2、查詢和當(dāng)前文檔中特定位置相關(guān)的WTP TLD內(nèi)容模型,判斷該標(biāo)簽在TLD文件中定義的時候是否聲明允許有標(biāo)簽體
3、如果標(biāo)簽在TLD中定義為不含有標(biāo)簽體,則矯正為自動閉合,“>”--->“/>”
PS:有關(guān)語法Document、語義Doucment、WTP TLD Content Document等數(shù)據(jù)類型相關(guān)內(nèi)容請參見前面的章節(jié)。
【配置SourceViewerConfiguration】
將我們上面的開發(fā)的自動編輯策略配置到我們的SourceViewerConfiguration實(shí)現(xiàn)中:
/**
* 自定義StructuredTextViewerConfiguration,基于WTP jst提供的StructuredTextViewerConfigurationJSP,
* 后面會提供自定義的自動提示策略等擴(kuò)展。
*
* @author zhuxing (mailto:zhu_xing@live.cn)
*/
/*
* 修改歷史
* $Log$
*/
public class JSPStructuredTextViewerConfiguration extends
StructuredTextViewerConfigurationJSP {
/*
* 提供自定義的自動提示策略
*
* @see org.eclipse.jst.jsp.ui.StructuredTextViewerConfigurationJSP#getContentAssistProcessors(org.eclipse.jface.text.source.ISourceViewer, java.lang.String)
*/
protected IContentAssistProcessor[] getContentAssistProcessors(ISourceViewer sourceViewer, String partitionType) {
//我們目前只自定義JSP標(biāo)簽屬性值自動提示的情況,所以針對的分區(qū)類型為IJSPPartitions.JSP_DIRECTIVE
if (partitionType == IJSPPartitions.JSP_DIRECTIVE) {
return new IContentAssistProcessor[]{new CustomizedJSPContentAssistantProcessor(), new JSPContentAssistProcessor()};
}
return super.getContentAssistProcessors(sourceViewer, partitionType);
}
/*
* 提供自定義的自動編輯策略
*
* @see org.eclipse.jst.jsp.ui.StructuredTextViewerConfigurationJSP#getAutoEditStrategies(org.eclipse.jface.text.source.ISourceViewer, java.lang.String)
*/
public IAutoEditStrategy[] getAutoEditStrategies(ISourceViewer sourceViewer, String contentType) {
//我們目前只自定義JSP標(biāo)簽名有關(guān)的自動編輯策略,所以針對的分區(qū)類型為IJSPPartitions.JSP_DIRECTIVE
if (contentType == IJSPPartitions.JSP_DIRECTIVE) {
List<IAutoEditStrategy> strategies = new ArrayList<IAutoEditStrategy>();
//WTP已配置的自動編輯策略
IAutoEditStrategy[] existingStrategies = super.getAutoEditStrategies(sourceViewer, contentType);
Collections.addAll(strategies, existingStrategies);
//自定義的自動編輯策略
IAutoEditStrategy customizedStrategies = new JSPDirectivePartitionAutoEditStrategy();
strategies.add(customizedStrategies);
return strategies.toArray(new IAutoEditStrategy[strategies.size()]);
}
return super.getAutoEditStrategies(sourceViewer, contentType);
}
}
* 自定義StructuredTextViewerConfiguration,基于WTP jst提供的StructuredTextViewerConfigurationJSP,
* 后面會提供自定義的自動提示策略等擴(kuò)展。
*
* @author zhuxing (mailto:zhu_xing@live.cn)
*/
/*
* 修改歷史
* $Log$
*/
public class JSPStructuredTextViewerConfiguration extends
StructuredTextViewerConfigurationJSP {
/*
* 提供自定義的自動提示策略
*
* @see org.eclipse.jst.jsp.ui.StructuredTextViewerConfigurationJSP#getContentAssistProcessors(org.eclipse.jface.text.source.ISourceViewer, java.lang.String)
*/
protected IContentAssistProcessor[] getContentAssistProcessors(ISourceViewer sourceViewer, String partitionType) {
//我們目前只自定義JSP標(biāo)簽屬性值自動提示的情況,所以針對的分區(qū)類型為IJSPPartitions.JSP_DIRECTIVE
if (partitionType == IJSPPartitions.JSP_DIRECTIVE) {
return new IContentAssistProcessor[]{new CustomizedJSPContentAssistantProcessor(), new JSPContentAssistProcessor()};
}
return super.getContentAssistProcessors(sourceViewer, partitionType);
}
/*
* 提供自定義的自動編輯策略
*
* @see org.eclipse.jst.jsp.ui.StructuredTextViewerConfigurationJSP#getAutoEditStrategies(org.eclipse.jface.text.source.ISourceViewer, java.lang.String)
*/
public IAutoEditStrategy[] getAutoEditStrategies(ISourceViewer sourceViewer, String contentType) {
//我們目前只自定義JSP標(biāo)簽名有關(guān)的自動編輯策略,所以針對的分區(qū)類型為IJSPPartitions.JSP_DIRECTIVE
if (contentType == IJSPPartitions.JSP_DIRECTIVE) {
List<IAutoEditStrategy> strategies = new ArrayList<IAutoEditStrategy>();
//WTP已配置的自動編輯策略
IAutoEditStrategy[] existingStrategies = super.getAutoEditStrategies(sourceViewer, contentType);
Collections.addAll(strategies, existingStrategies);
//自定義的自動編輯策略
IAutoEditStrategy customizedStrategies = new JSPDirectivePartitionAutoEditStrategy();
strategies.add(customizedStrategies);
return strategies.toArray(new IAutoEditStrategy[strategies.size()]);
}
return super.getAutoEditStrategies(sourceViewer, contentType);
}
}
我們在我們自己的SourceViewerConfiguration實(shí)現(xiàn)JSPStructuredTextViewerConfiguration中覆寫了getAutoEditStrategies方法。由于我們只是演示定制標(biāo)簽名輸入時候的自動編輯策略,所以針對的分區(qū)類型為IJSPPartitions.JSP_DIRECTIVE。
【效果演示】
如上圖所示,我們輸入了標(biāo)簽名test1:test,而且光標(biāo)位于標(biāo)簽名文本內(nèi)容之后,此時WTP的源碼校驗(yàn)器給出了錯誤提示,說我們的標(biāo)簽缺少對應(yīng)的閉合符號。
我們看一下test1:test標(biāo)簽對應(yīng)的TLD定義,定位為不允許有標(biāo)簽體:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN" "http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd">
<taglib>
<tlibversion>1.0</tlibversion>
<jspversion>1.0</jspversion>
<shortname>test1</shortname>
<uri>http://www.aygfsteel.com/zhuxing/tags/test1</uri>
<tag>
<name>test</name>
<tagclass>any</tagclass>
<bodycontent>empty</bodycontent>
<attribute>
<name>scope</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
</taglib>
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN" "http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd">
<taglib>
<tlibversion>1.0</tlibversion>
<jspversion>1.0</jspversion>
<shortname>test1</shortname>
<uri>http://www.aygfsteel.com/zhuxing/tags/test1</uri>
<tag>
<name>test</name>
<tagclass>any</tagclass>
<bodycontent>empty</bodycontent>
<attribute>
<name>scope</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
</taglib>
根據(jù)需求,當(dāng)我們在圖中光標(biāo)位置輸入“>”的時候,我們前面開發(fā)的自動編輯策略會自動將其矯正為合法的結(jié)束符“/>”,效果如下:
對比如下,如果沒有應(yīng)用自動編輯策略,則會得到如下源碼校驗(yàn)錯誤:
【后記】
提醒:從需求上講,我們示例中開發(fā)的自動編輯策略其實(shí)是非常簡單的。但是將其放置到一個定制WTP StructuredTextEditor的場景中,就不可避免的和我們前面介紹的WTP基礎(chǔ)數(shù)據(jù)模型的知識打交道,在這里再次強(qiáng)調(diào),前面介紹的WTP各種數(shù)據(jù)模型一定要熟練搞清楚,基礎(chǔ)中的基礎(chǔ)!!!
源碼為實(shí)際工程以Export ---> Archive File方式導(dǎo)出的,下載鏈接:WTP StructuredTextEditor自動編輯策略定制示例源碼
本博客中的所有文章、隨筆除了標(biāo)題中含有引用或者轉(zhuǎn)載字樣的,其他均為原創(chuàng)。轉(zhuǎn)載請注明出處,謝謝!
posted on 2008-10-20 15:50 zhuxing 閱讀(3356) 評論(3) 編輯 收藏 所屬分類: Eclipse Plug-in & OSGI 、WTP(Web Tools Platform)