Live a simple life

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

          【Eclipse插件開發(fā)】基于WTP開發(fā)自定義的JSP編輯器(十一):TLD Content Model分析視圖

                      在上一節(jié)中我們分析了WTP TLD Content Model的關(guān)鍵特性,并簡要介紹了WTP Content Model的整體結(jié)構(gòu)。在本節(jié)中,我們將開發(fā)一個WTP TLD Content Model分析視圖,幫助我們更直觀的了解所謂的WTP TLD內(nèi)容模型。本視圖的開發(fā)和前面開發(fā)過的WTP StructuredDocument分析視圖和WTP Structured Model分析視圖非常類似,有些技術(shù)實現(xiàn)細(xì)節(jié)的分析可以參見前面相應(yīng)的章節(jié)。

                      【需求】
                      1、提供一個TLD Content Model分析視圖,以樹狀方式將當(dāng)前編輯器中JSP文檔對應(yīng)的TLD內(nèi)容模型顯示出來,每個TLDDocument為一個獨立節(jié)點,TLDDocument下面持有TLD Element和TLD Attribute兩級子節(jié)點
                      2、交互(編輯器 ---> TLD Content Model分析視圖):
                            激活 JSP編輯器,即時更新TLD Content Model分析視圖
                            當(dāng)編輯器中的內(nèi)容改變時,即時更新TLD Content Model分析視圖
                            當(dāng)前激活編輯器關(guān)閉時,清空TLD Content Model分析視圖內(nèi)容
                      3、交互(TLD Content Model分析視圖 ---> 編輯器)
                            雙擊視圖中TLD Document節(jié)點時,打開對應(yīng)的TLD定義文件

                      4、進(jìn)一步需求,當(dāng)編輯器中的光標(biāo)位置變化時,即時更新TLD Content Model分析視圖。(說明:在上一節(jié)中我們分析過,一個TLD Document有位置相關(guān)的特性,獲取光標(biāo)位置相關(guān)的TLD Document列表,也就是光標(biāo)位置之前可以被識別的TLD導(dǎo)入^_^)

                      【效果預(yù)覽】
                      1、位置無關(guān)的TLD Content Model分析效果預(yù)覽 
                       如圖所示,不管光標(biāo)位于編輯器中的任何位置,都會列舉出所有的TLD Content Document。

                      2、位置相關(guān)的TLD Content Model分析效果預(yù)覽

                          如圖所示,光標(biāo)位于test1 tld和test2 tld之間,這時候分析視圖中只列舉除了當(dāng)前位置可以識別的TLD信息。在此位置,test2 tld還不能夠獲取到,所以使用test2中的標(biāo)簽會得到WTP的一個錯誤提示:不能識別的標(biāo)簽。(我想,理解了TLD Content Document位置相關(guān)的特性,也就理解了WTP中對特定標(biāo)簽在特定位置是否可以被識別是怎么實現(xiàn)的了^_^)

                      【實現(xiàn)摘要(文章后門會附上對應(yīng)的源碼)】

                          說明:有關(guān)視圖實現(xiàn)類創(chuàng)建、如何利用Eclipse工作臺的selection service和part service等代碼實現(xiàn),請參照前面章節(jié)中的兩個分析視圖的實現(xiàn):
                          基于WTP開發(fā)自定義的JSP編輯器(四):Strucutured Document分析視圖
                          基于WTP開發(fā)自定義的JSP編輯器(六):IStructuredModel(DOM Document)分析視圖

                          
                          1、位置無關(guān)場景下TLD Content Document列表的獲取代碼
          /**
               * 獲取指定文檔對應(yīng)的TLD Content Document列表
               * 
               * 
          @param structuredDocument   jsp structured document
               * 
          @return
               
          */
              
          private TLDDocument[] getTLDDocuments(IStructuredDocument structuredDocument) {
                  TLDCMDocumentManager tldDocumentManager 
          = TaglibController.getTLDCMDocumentManager(structuredDocument);
                  List taglibTrackers = tldDocumentManager.getTaglibTrackers();
                  
                  TLDDocument[] tldDocuments 
          = new TLDDocument[taglibTrackers.size()];
                  
          for (int i = 0; i < tldDocuments.length; i++) {
                      TaglibTracker taglibTracker 
          = (TaglibTracker)taglibTrackers.get(i);
                      tldDocuments[i] 
          = (TLDDocument)taglibTracker.getDocument();
                  }
                  
          return tldDocuments;
              }
                          上一節(jié)中,我們闡述過taglib tracker的獲取方式,TLDCMDocumentManager.getTaglibTrackers()就是位置無關(guān)的獲取方式,具體細(xì)節(jié)請參見上一節(jié)中的內(nèi)容。

                          2、位置相關(guān)場景下TLD Content Document列表的獲取代碼
          /**
               * 獲取指定文檔中特定位置對應(yīng)的TLD Content Document列表 
               * 
               * 
          @param structuredDocument  jsp structured document
               * 
          @param offset    文檔中的位置
               * 
          @return
               
          */
              
          private TLDDocument[] getTLDDocuments(IStructuredDocument structuredDocument, int offset) {
                  TLDCMDocumentManager tldDocumentManager 
          = TaglibController.getTLDCMDocumentManager(structuredDocument);
                  List taglibTrackers = tldDocumentManager.getCMDocumentTrackers(offset);

                  
                  TLDDocument[] tldDocuments 
          = new TLDDocument[taglibTrackers.size()];
                  
          for (int i = 0; i < tldDocuments.length; i++) {
                      TaglibTracker taglibTracker 
          = (TaglibTracker)taglibTrackers.get(i);
                      tldDocuments[i] 
          = (TLDDocument)taglibTracker.getDocument();
                  }
                  
          return tldDocuments;
              }
                          taglib tracker列表的獲取方式:TLDCMDocumentManager.getCMDocumentTrackers(int offset),位置相關(guān)。

                          3、對用戶選擇事件的處理: 
          /* (non-Javadoc)
               * @see org.eclipse.ui.ISelectionListener#selectionChanged(org.eclipse.ui.IWorkbenchPart, org.eclipse.jface.viewers.ISelection)
               
          */
              
          public void selectionChanged(IWorkbenchPart part, ISelection selection) {
                  
          if (!(part instanceof TextEditor)) 
                      
          return ;
                  
                  IEditorInput editorInput 
          = ((TextEditor)part).getEditorInput();
                  IDocument document 
          = ((TextEditor)part).getDocumentProvider().getDocument(editorInput);
                  
          if (!(document instanceof IStructuredDocument)) {
                      
          this.viewer.setInput(null);
                      
          return ;
                  }
                  
                  
          //記錄source part和source document
                  this.sourcePart = part;
                  
          this.sourceDocument = document;
                  
                  
          //注冊對應(yīng)的document change listener
                  document.addDocumentListener(this.documentListener);
                  
          //        //獲取TLD Content Document列表(位置無關(guān)方式),并更新tree viewer輸入
          //        TLDDocument[] tldDocuments = this.getTLDDocuments((IStructuredDocument)document);
          //        this.viewer.setInput(tldDocuments);
          //        this.viewer.expandToLevel(2);
                  
                  
          //獲取TLD Content Document列表(位置相關(guān)方式),并更新tree viewer輸入
                  int offset = ((ITextSelection)selection).getOffset();
                  TLDDocument[] tldDocuments 
          = this.getTLDDocuments((IStructuredDocument)document, offset);
                  
          this.viewer.setInput(tldDocuments);
                  
          this.viewer.expandToLevel(2);
              }
                          在處理用戶選擇事件時候,根據(jù)只需要調(diào)用不同的TLD Content Document獲取方式(1、2點中闡述的)就可以了^_^。
                      
                          4、視圖中TLD Document節(jié)點的雙擊事件的處理
          //添加雙擊支持
                  this.viewer.addDoubleClickListener(new IDoubleClickListener() {
                      
          public void doubleClick(DoubleClickEvent event) {
                          ITreeSelection treeSelection 
          = (ITreeSelection)event.getSelection();
                          Object selectedElement 
          = treeSelection.getFirstElement();
                          
          if (!(selectedElement instanceof TLDDocument))
                              
          return ;
                          
                          
          //獲取TLD Document對應(yīng)的TLD文件
                          String baseLocation = ((TLDDocument)selectedElement).getBaseLocation();
                          IFile file 
          = ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(new Path(baseLocation));
                          
          if (!file.exists()) 
                              
          return ;
                          
                          
          //打開TLD定義文件
                          try {
                              IWorkbenchPage page 
          = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
                              IDE.openEditor(page, file);
                          } 
          catch (PartInitException e) {
                              IStatus status 
          = new Status(IStatus.ERROR, "wtp.tldcontentdocument"1111"打開TLD定義文件失敗", e);
                              Activator.getDefault().getLog().log(status);
                          }
                      }
                  });
                          主要步驟如下:
                           1、利用TLDDocument接口中的getBaseLocation獲取該TLDDocument對應(yīng)的頁面資源的絕對路徑信息
                           2、定位工作區(qū)中對應(yīng)的TLD資源文件,打開

                          5、視圖tree viewer對應(yīng)的content provider
                          
          /* (non-Javadoc)
               * @see org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java.lang.Object)
               
          */
              
          public Object[] getChildren(Object parentElement) {
                  
          if (parentElement == null)
                      
          return new Object[0];
                  
                  
          if (parentElement instanceof TLDDocument[])
                      
          return (TLDDocument[])parentElement;
                  
                  
          //如果是tld content document, 則獲取對應(yīng)的tld element列表
                  if (parentElement instanceof TLDDocument) {
                      CMNamedNodeMap tagMap 
          = ((TLDDocument)parentElement).getElements();
                      
                      Object[] children 
          = new Object[tagMap.getLength()];
                      
          for (int i = 0; i < children.length; i++) {
                          children[i] 
          = tagMap.item(i);
                      }
                      
          return children;
                  }
                  
                  
          //如果是tld element(tag),則獲取對應(yīng)的attrbute列表
                  if (parentElement instanceof TLDElementDeclaration) {
                      CMNamedNodeMap attributeMap 
          = ((TLDElementDeclaration)parentElement).getAttributes();
                      
                      Object[] children 
          = new Object[attributeMap.getLength()];
                      
          for (int i = 0; i < children.length; i++) {
                          children[i] 
          = attributeMap.item(i);
                      }
                      
          return children;
                  }
                  
                  
          return new Object[0];
              }
                          如果輸入是tld content document(TLDDocument),則獲取對應(yīng)的tld element列表,也就是tld中定義的tag列表;如果輸入是tld element(TLDElementDeclaration),則獲取對應(yīng)的tld attribute列表,也就是特定tag下面定義的標(biāo)簽屬性列表。
                          
                          其他具體代碼實現(xiàn)細(xì)節(jié),參見附件中的源碼。^_^


                      【后記】
                         本插件工程需要依賴的插件列表為:
                           org.eclipse.ui,
                           org.eclipse.core.runtime,
                           org.eclipse.jface.text,
                           org.eclipse.ui.editors,
                           org.eclipse.ui.workbench.texteditor,
                           org.eclipse.wst.sse.core,
                           org.eclipse.jst.jsp.core,
                           org.eclipse.wst.xml.core,
                           org.eclipse.core.resources,
                           org.eclipse.ui.ide
                         
                          源碼為實際工程以Export ---> Archive File方式導(dǎo)出的,下載鏈接TLD Content Model分析視圖源碼


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

          posted on 2008-10-16 18:05 zhuxing 閱讀(1204) 評論(1)  編輯  收藏 所屬分類: Eclipse Plug-in & OSGI 、WTP(Web Tools Platform)

          評論

          # re: 【Eclipse插件開發(fā)】基于WTP開發(fā)自定義的JSP編輯器(十一):TLD Content Model分析視圖  回復(fù)  更多評論   

          朱興,能不能再介紹一下wtp 是如何 基于 xml 的 dtd 來對 xml 進(jìn)行校驗和語法提示的?是不是類似于tld的這種方式?我現(xiàn)在要開發(fā)一個特定xml的編輯器,需要根據(jù)一定的業(yè)務(wù)規(guī)則來進(jìn)行校驗和提示,請問該怎么做比較好?
          2008-10-16 19:36 | 飛揚的麥子
          主站蜘蛛池模板: 岗巴县| 通榆县| 嵊泗县| 施秉县| 合水县| 习水县| 怀柔区| 丹凤县| 辽中县| 南阳市| 科技| 平和县| 嘉兴市| 会东县| 茂名市| 泰和县| 社旗县| 神农架林区| 托克逊县| 霍林郭勒市| 大同县| 孝义市| 修文县| 莆田市| 嘉黎县| 鱼台县| 灯塔市| 新丰县| 麦盖提县| 涟水县| 左贡县| 大兴区| 同江市| 白朗县| 镇沅| 吉林市| 樟树市| 邵武市| 松滋市| 吴旗县| 乃东县|