<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Live a simple life

    沉默(zhu_xing@live.cn)
    隨筆 - 48, 文章 - 0, 評(píng)論 - 132, 引用 - 0
    數(shù)據(jù)加載中……

    【Eclipse插件開(kāi)發(fā)】基于WTP開(kāi)發(fā)自定義的JSP編輯器(十二):定制自動(dòng)編輯策略(Auto Edit Strategy)

                JFace Text Framework框架的一個(gè)重要的功能特征就是自動(dòng)編輯策略,它允許用戶(hù)對(duì)輸入的內(nèi)容(準(zhǔn)確的說(shuō)應(yīng)該是即將來(lái)臨的Document修改^_^)做即時(shí)編輯,然后又會(huì)透明的將用戶(hù)的修改付諸于實(shí)現(xiàn)(即應(yīng)用到當(dāng)前文檔)。在本節(jié),我們將在前兩節(jié)有關(guān)TLD Content Model的基礎(chǔ)上開(kāi)發(fā)一個(gè)自動(dòng)編輯策略。

            【JFace Text Framework 自動(dòng)編輯策略原理介紹】

             【JDT Java源碼編輯器自動(dòng)編輯策略演示】
              我們每個(gè)使用Eclipse JDT進(jìn)行Java編程的開(kāi)發(fā)者都會(huì)對(duì)JDT中Java源碼編輯器的自動(dòng)編輯策略印象深刻,它給編碼人員帶來(lái)了很大的方便。舉例如下:
         
                如上圖所示,我們?cè)诰帉?xiě)一個(gè)新的函數(shù),圖中黑色豎線“|”就是光標(biāo)所在處,當(dāng)我們按下回車(chē)鍵的時(shí)候,效果變?yōu)槿缦拢?br />      
                    如上圖所示,當(dāng)我們輸入回車(chē)鍵之后,JDT Java源碼編輯器自動(dòng)幫我們矯正了內(nèi)容(text)和位置(offset):原來(lái)的輸入內(nèi)容應(yīng)該是“\r\n”,JDT Java源碼編輯器自動(dòng)幫我們矯正為“\r\n\t\t\r\n\t}”;根據(jù)“\r\n”內(nèi)容推算,輸入后光標(biāo)位置應(yīng)該位于28行的起始處,JDT Java源碼編輯器自動(dòng)幫我們矯正為離28行其實(shí)處兩個(gè)“\t”的距離。

                【自動(dòng)編輯流程和主要角色】
                                    
                    上圖就演示了自動(dòng)編輯過(guò)程:
                    1、用戶(hù)編輯,鍵盤(pán)事件
                    2、根據(jù)鍵盤(pán)事件,對(duì)事件信息進(jìn)行分析,拼裝到名為DocumentCommand的數(shù)據(jù)結(jié)構(gòu)中,該數(shù)據(jù)結(jié)構(gòu)中包含了用戶(hù)的輸入內(nèi)容(text)、光標(biāo)位置(offset)等信息,例如,上面JDT的例子中用戶(hù)的輸入內(nèi)容為“\r\n”。這一步JFace Text Framework幫用戶(hù)解決了
                    3、調(diào)用自動(dòng)編輯策略,對(duì)應(yīng)DocumentCommand中數(shù)據(jù)進(jìn)行自定義矯正,例如,JDT Java源碼編輯器的自動(dòng)編輯策略將輸入內(nèi)容矯正為“\r\n\t\t\r\n\t}”。用戶(hù)自己負(fù)責(zé),JDT Java源碼編輯器在這邊干活了,提供了自己的IAutoEditStrategy^_^
                    4、將用戶(hù)矯正后的DocumentCommand應(yīng)用到對(duì)應(yīng)編輯器(說(shuō)白了,就是轉(zhuǎn)化為一個(gè)Document replace動(dòng)作執(zhí)行)。這一步JFace Text Framework幫用戶(hù)解決了。
                    
                    我們可以看到,JFace Text Framework已經(jīng)替我們干了大部分活,我們需要關(guān)心的是如下兩個(gè)角色:    
                    org.eclipse.jface.text.DocumentCommand:數(shù)據(jù)載體,封裝了一個(gè)文本變化(text modification)的信息,例如輸入內(nèi)容(text)、光標(biāo)位置(offset)、長(zhǎng)度(length)等等。我們要做的恰恰就是在我們自己的自動(dòng)編輯策略中對(duì)DocumentCommand中的內(nèi)容做矯正,然后JFace Text Framework會(huì)自動(dòng)幫我們應(yīng)用到目標(biāo)IDocument中。
                    org.eclipse.jface.text.IAutoEditStrategy:自動(dòng)編輯編輯策略,根據(jù)不同應(yīng)用場(chǎng)景對(duì)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);
    }
                
                【配置IAutoEditStrategy到SourceViewer】
                
    上面我們已經(jīng)講了自動(dòng)編輯的流程和主要角色,可以大家都有個(gè)疑問(wèn):IAutoEditStrategy到底是如何被自動(dòng)調(diào)用的?IAutoEditStrategy實(shí)現(xiàn)需要被配置到對(duì)應(yīng)的SourceViewerConfiguration中,并和對(duì)應(yīng)的內(nèi)容類(lèi)型(很多時(shí)候也可以理解為分區(qū)類(lèi)型)綁定。JFace Text Framework會(huì)在初始化編輯器實(shí)例的時(shí)候讀取用戶(hù)的配置,然后根據(jù)不同的內(nèi)容類(lèi)型去查找對(duì)應(yīng)的自動(dò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) {
            
    //
        }
    }
                
                附加說(shuō)明:1、有關(guān)內(nèi)容類(lèi)型(分區(qū)類(lèi)型)可以參考前面章節(jié)的內(nèi)容; 2、原有的IAutoIndentStrategy接口Eclipse已經(jīng)不推薦使用^_^

                【定制WTP StructuredTextEditor的自動(dòng)編輯策略】
             
    【需求】
                    當(dāng)用戶(hù)輸入標(biāo)簽結(jié)束符“>”時(shí),如果標(biāo)簽在TLD中定義為不含有標(biāo)簽體(即bodycontent屬性值為empty),則自動(dòng)將用戶(hù)的輸入內(nèi)容矯正為“/>”。
                    
                    【前提知識(shí)】
                      對(duì)WTP基本數(shù)據(jù)模型不很了解的可以參見(jiàn)一下前面的相關(guān)章節(jié):
                      【Eclipse插件開(kāi)發(fā)】基于WTP開(kāi)發(fā)自定義的JSP編輯器(三) :WTP Structured Document     
                      【Eclipse插件開(kāi)發(fā)】基于WTP開(kāi)發(fā)自定義的JSP編輯器(五) :WTP Structured Model     
                      【Eclipse插件開(kāi)發(fā)】基于WTP開(kāi)發(fā)自定義的JSP編輯器(七):WTP數(shù)據(jù)模型總結(jié)和模型管理    
                      【Eclipse插件開(kāi)發(fā)】基于WTP開(kāi)發(fā)自定義的JSP編輯器(十):WTP TLD內(nèi)容模型介紹     

                    【開(kāi)發(fā)自定義的IAutoEditStrategy實(shí)現(xiàn)】    
    /**
     * 針對(duì)JSP_DIRECTIVE分區(qū)的自動(dòng)編輯策略
     *
     * 
    @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、用戶(hù)正在標(biāo)簽名區(qū)域編輯;2、用戶(hù)編輯位置位于標(biāo)簽名末端
            if (currentRegion.getType() == DOMRegionContext.XML_TAG_NAME 
                    
    && command.offset >= startOffset +
     textLength) {
                
    if (!
    hasBody(structuredDocumentRegion))
                    command.text 
    = "/>"
    ;
            }
        }

        
    /**
         * 查詢(xún)對(duì)應(yīng)的TLD內(nèi)容模型,判斷該標(biāo)簽在TLD中定義的時(shí)候是否含有標(biāo)簽體
         * 
         * 
    @param structuredDocumentRegion
         * 
    @return
         
    */
        
    private boolean hasBody(IStructuredDocumentRegion structuredDocumentRegion) {
            
    //獲取標(biāo)簽名稱(chēng)
            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、查找對(duì)應(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è)用戶(hù)正在標(biāo)簽名區(qū)域編輯(通過(guò)判斷編輯區(qū)域region的region type來(lái)判斷),并且編輯位置位于標(biāo)簽名內(nèi)容末端           
                    2、查詢(xún)和當(dāng)前文檔中特定位置相關(guān)的WTP TLD內(nèi)容模型,判斷該標(biāo)簽在TLD文件中定義的時(shí)候是否聲明允許有標(biāo)簽體
                    3、如果標(biāo)簽在TLD中定義為不含有標(biāo)簽體,則矯正為自動(dòng)閉合,“>”--->“/>”

                    PS:有關(guān)語(yǔ)法Document、語(yǔ)義Doucment、WTP TLD Content Document等數(shù)據(jù)類(lèi)型相關(guān)內(nèi)容請(qǐng)參見(jiàn)前面的章節(jié)。

                【配置SourceViewerConfiguration】
                  將我們上面的開(kāi)發(fā)的自動(dòng)編輯策略配置到我們的SourceViewerConfiguration實(shí)現(xiàn)中:   
    /**
     * 自定義StructuredTextViewerConfiguration,基于WTP jst提供的StructuredTextViewerConfigurationJSP,
     * 后面會(huì)提供自定義的自動(dòng)提示策略等擴(kuò)展。
     *
     * 
    @author zhuxing (mailto:zhu_xing@live.cn)
     
    */
    /*
     * 修改歷史
     * $Log$ 
     
    */
    public class JSPStructuredTextViewerConfiguration extends
            StructuredTextViewerConfigurationJSP {
        
    /* 
         * 提供自定義的自動(dòng)提示策略
         * 
         * @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)簽屬性值自動(dòng)提示的情況,所以針對(duì)的分區(qū)類(lèi)型為IJSPPartitions.JSP_DIRECTIVE
            if (partitionType == IJSPPartitions.JSP_DIRECTIVE) {
                
    return new IContentAssistProcessor[]{new CustomizedJSPContentAssistantProcessor(), new JSPContentAssistProcessor()};
            }
            
            
    return super.getContentAssistProcessors(sourceViewer, partitionType);
        }
        
        
    /* 
         * 提供自定義的自動(dòng)編輯策略
         * 
         * @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)的自動(dòng)編輯策略,所以針對(duì)的分區(qū)類(lèi)型為IJSPPartitions.JSP_DIRECTIVE
            if (contentType == IJSPPartitions.JSP_DIRECTIVE) {
                List
    <IAutoEditStrategy> strategies = new ArrayList<IAutoEditStrategy>();
                
                
    //WTP已配置的自動(dòng)編輯策略
                IAutoEditStrategy[] existingStrategies = super.getAutoEditStrategies(sourceViewer, contentType);
                Collections.addAll(strategies, existingStrategies);
                
                
    //自定義的自動(dòng)編輯策略
                IAutoEditStrategy customizedStrategies = new JSPDirectivePartitionAutoEditStrategy();
                strategies.add(customizedStrategies);
                
                
    return strategies.toArray(new IAutoEditStrategy[strategies.size()]);
            }
            
            
    return super.getAutoEditStrategies(sourceViewer, contentType);
        }
        
    }

                我們?cè)谖覀冏约旱腟ourceViewerConfiguration實(shí)現(xiàn)JSPStructuredTextViewerConfiguration中覆寫(xiě)了getAutoEditStrategies方法。由于我們只是演示定制標(biāo)簽名輸入時(shí)候的自動(dòng)編輯策略,所以針對(duì)的分區(qū)類(lèi)型為IJSPPartitions.JSP_DIRECTIVE。

                【效果演示】

               
    如上圖所示,我們輸入了標(biāo)簽名test1:test,而且光標(biāo)位于標(biāo)簽名文本內(nèi)容之后,此時(shí)WTP的源碼校驗(yàn)器給出了錯(cuò)誤提示,說(shuō)我們的標(biāo)簽缺少對(duì)應(yīng)的閉合符號(hào)。

               我們看一下test1:test標(biāo)簽對(duì)應(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.tkk7.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)我們?cè)趫D中光標(biāo)位置輸入“>”的時(shí)候,我們前面開(kāi)發(fā)的自動(dòng)編輯策略會(huì)自動(dòng)將其矯正為合法的結(jié)束符“/>”,效果如下:

                
                對(duì)比如下,如果沒(méi)有應(yīng)用自動(dòng)編輯策略,則會(huì)得到如下源碼校驗(yàn)錯(cuò)誤:


            【后記】
                提醒:從需求上講,我們示例中開(kāi)發(fā)的自動(dòng)編輯策略其實(shí)是非常簡(jiǎn)單的。但是將其放置到一個(gè)定制WTP StructuredTextEditor的場(chǎng)景中,就不可避免的和我們前面介紹的WTP基礎(chǔ)數(shù)據(jù)模型的知識(shí)打交道,在這里再次強(qiáng)調(diào),前面介紹的WTP各種數(shù)據(jù)模型一定要熟練搞清楚,基礎(chǔ)中的基礎(chǔ)?。?!

                 源碼為實(shí)際工程以Export ---> Archive File方式導(dǎo)出的,下載鏈接:WTP StructuredTextEditor自動(dòng)編輯策略定制示例源碼

    本博客中的所有文章、隨筆除了標(biāo)題中含有引用或者轉(zhuǎn)載字樣的,其他均為原創(chuàng)。轉(zhuǎn)載請(qǐng)注明出處,謝謝!

    posted on 2008-10-20 15:50 zhuxing 閱讀(3361) 評(píng)論(3)  編輯  收藏 所屬分類(lèi): Eclipse Plug-in & OSGI 、WTP(Web Tools Platform)

    評(píng)論

    # re: 【Eclipse插件開(kāi)發(fā)】基于WTP開(kāi)發(fā)自定義的JSP編輯器(十二):定制自動(dòng)編輯策略(Auto Edit Strategy)  回復(fù)  更多評(píng)論   

    有個(gè)問(wèn)題想請(qǐng)教一下,我想導(dǎo)入org.eclipse.wst.dtd.core這個(gè)插件,但是發(fā)現(xiàn)在RCP中無(wú)法加載該插件,我想是應(yīng)該該插件一些依賴(lài)沒(méi)有加進(jìn)來(lái),那么我該怎么知道需要再添加那些插件作為依賴(lài)啊?
    2008-10-20 19:32 | 飛揚(yáng)的麥子

    # re: 【Eclipse插件開(kāi)發(fā)】基于WTP開(kāi)發(fā)自定義的JSP編輯器(十二):定制自動(dòng)編輯策略(Auto Edit Strategy)  回復(fù)  更多評(píng)論   

    1、首先確定是否是你說(shuō)的缺少依賴(lài)的問(wèn)題
    2、簡(jiǎn)單的插件依賴(lài)關(guān)系缺少,結(jié)合編譯錯(cuò)誤稍微看一下應(yīng)該就可以解決了
    3、如果真的插件依賴(lài)關(guān)系比較復(fù)雜,可以借助Plug-in Dependencies視圖
    2008-10-21 09:39 | zhuxing

    # re: 【Eclipse插件開(kāi)發(fā)】基于WTP開(kāi)發(fā)自定義的JSP編輯器(十二):定制自動(dòng)編輯策略(Auto Edit Strategy)  回復(fù)  更多評(píng)論   

    如果想實(shí)現(xiàn)驗(yàn)證后對(duì)編輯器屬性文字進(jìn)行相關(guān)顏色、字體樣式設(shè)置,應(yīng)該怎么做呢?
    2013-08-29 10:38 | cat

    只有注冊(cè)用戶(hù)登錄后才能發(fā)表評(píng)論。


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 免费国产在线精品一区 | 国产成人免费一区二区三区| 在线观看无码的免费网站| 亚洲成av人片一区二区三区| 亚洲av日韩av不卡在线观看| 伊人久久五月丁香综合中文亚洲 | 成人爽a毛片免费| 麻豆成人精品国产免费| 亚洲国产二区三区久久| 国产精品亚洲а∨无码播放麻豆 | 成人免费看吃奶视频网站| 亚洲人成精品久久久久| 亚洲熟妇无码AV| 蜜桃精品免费久久久久影院| 无码亚洲成a人在线观看| 免费观看激色视频网站bd | 亚洲成av人在片观看| 草久免费在线观看网站| 女人18毛片免费观看| 国产成人人综合亚洲欧美丁香花 | 色欲色欲天天天www亚洲伊| 凹凸精品视频分类国产品免费| 亚洲特级aaaaaa毛片| 老司机69精品成免费视频| 亚洲精品视频在线观看你懂的| 亚洲色无码国产精品网站可下载| 国产精品自在自线免费观看| 国产免费内射又粗又爽密桃视频| 情侣视频精品免费的国产| 99999久久久久久亚洲| 69视频在线是免费观看| 亚洲av午夜成人片精品网站| 国产97视频人人做人人爱免费| 国产91久久久久久久免费| 岛国精品一区免费视频在线观看| 亚洲国产成人五月综合网 | 亚洲午夜精品一级在线播放放 | 亚洲午夜国产精品无卡| 性xxxx视频免费播放直播| 亚洲AV中文无码乱人伦下载 | 免费欧洲毛片A级视频无风险|