DIV CSS 佈局教程網

 DIV+CSS佈局教程網 >> 網頁腳本 >> XML學習教程 >> XML詳解 >> 使用 XML: 使用 XML:集成 XM 和 Eclipse
使用 XML: 使用 XML:集成 XM 和 Eclipse
編輯:XML詳解     

 Eclipse 是出色的集成開發環境(IDE),因為它促進了可擴展的體系結構。Eclipse 認識到現代開發需要許多技能。它不再滿足於僅僅使用 Java 或Html 或C++。現代的 IDE 需要支持所有這些語言以及其它一些語言。

  為滿足這一需要,Eclipse 使用插件。插件擴展了 IDE,以支持新的語言、編譯器以及其它開發工具。在 Eclipse 中沒有缺省語言。Eclipse 通過插件支持每種語言 - 包括 Java 語言。因此,倘若您編寫適當的插件,那麼 Eclipse 所能支持的語言數目是沒有限制的。正如我通過此項目發現的,編寫 Eclipse 插件並不是那麼困難。要從 Eclipse 啟動 XM,我只需編寫兩個類。對於開發人員,這是個特棒的消息。根據我的經驗,無論供應商在工具箱中包括了什麼 -不管它是自產的實用程序、第三方工具或是軟件管理 - 我始終需要其它工具。

  任何 IDE 都可以啟動外部工具,但是這往往意味著我必須在 IDE 和外部工具之間來回切換。我確信使用 Eclipse 可以將工具集成到 IDE 中並且有條理地組織每樣東西。要學習如何編寫這樣的插件,請繼續閱讀。

  向 Eclipse 開發團隊脫帽致敬 - 我開始非常喜歡你們的工作了。

  XM 背景知識

  距離我上次在本專欄討論 XM 已有很長時間了。從我所收到的郵件來看,一些讀者對它究竟是什麼產生了誤解。XM 是用於發布使用 XML 和 XSLT 的靜態網站的低成本解決方案。它和 WebSphere Portal 或 Cocoon 並非競爭關系。我發起 XM 是因為我發現用於 XML 發布的簡單解決方案很缺乏,對此深感不便。

  大多數發布項目最後都發展到同一個終點:它們需要應用程序服務器,但並不是每個項目一開始就有數量巨大的文檔。XM 旨在在早期階段幫助您。例如,撰寫這篇專欄文章時,我剛訪問一個 XM 新用戶後回來。這個組織大約有 400 個極少更新的簡單 XML 文檔。它們的樣式表長度少於 100 行。那麼,僅僅為了發布這 400 個文檔而獲取並安裝成熟的應用程序服務器有意義嗎?我認為沒什麼意義,而他們也持相同觀點。目前,每個晚上批處理運行 XM 更有意義。顯然,當他們更熟悉 XML 時,他們會想要功能更強大的解決方案,但是現在 XM 滿足了他們的需求,它也滿足了許多小到中型網站的需求。

為 XM 編寫插件

  編寫 Eclipse 插件時,第一步是決定擴展哪個元素。插件可以擴展導航器或概述文件、添加菜單項、替換編輯器或繪制新的控制台和狀態窗口。

  如圖 1 所示,我決定從將新的 Run XM項添加到導航器的彈出菜單開始。我還添加了新的 XM Console窗口來顯示狀態消息。通過這兩個添加,有可能不用離開 Eclipse 窗口就可使用 XM。


圖 1. 從 Eclipse 啟動 XM 
使用 XML: 使用 XML:集成 XM 和 Eclipse

  查看原圖(大圖)

  這兒有個難題是確定何時顯示 Run XM 菜單。在 XM 開發的較早時期,我選擇了消除配置文件。遺憾的是,沒剩下什麼可以在上面單擊鼠標右鍵了。因此,第一步是定義 .xmp (XM 項目)文件。配置插件以使 Run XM 和 .xmp 文件相關聯。

  簡而言之, .xmp 文件是帶有以下四個特性的 Java 特性文件,這四個特性對應於命令行參數(請參閱 清單 1,以獲取示例):

  source :指向源目錄(缺省值: src )

  publish :指向發布或目標目錄(缺省值: publish )

  rules :指向樣式表目錄(缺省值: rules )

  build :為 true 或 false 值 - true 強制執行重新構建,其中,XM 處理每個文件(缺省值: false )


清單 1. 樣本 .xmp 文件
# this publishes the ananas.org site 
source=src 
publish=ananas-Html 
rules=style-sheet 
build=false 


XM 控制台

  XM 控制台是在 MessengerVIEw 中實現的。它是一個 部件(part)- 工作台中“窗口”的 Eclipse 術語。因為 上個月的專欄文章包括了用作部件的插件,因此代碼對您來說應該很熟悉了,所以我將只是重新生成摘錄。如果您沒有閱讀上一篇專欄文章(該文件簡介了 Eclipse 插件體系結構),那麼我建議您現在就回頭閱讀它。

  本文和上個月的專欄文章最顯著的差異是使用 SWT 表代替了標簽。該表有兩列,其中第一列包含了消息狀態(出錯、警告等),第二列包含了消息本身。對於一列消息來說,表很方便,因為它允許用戶用滾動欄上下翻頁。

  在 SWT 中,表是 org.eclipse.swt.widgets.Table 的實例。使用 TableColumn 類定義每個列的寬度及其標題,如清單 2 所示。


清單 2. 創建 SWT 表
table = new Table(parent,SWT.SINGLE); 
TableColumn column = new TableColumn( 
     
     
      
     table 
     
    ,SWT.NONE); 
column.setText("Status"); 
column.setWidth(50); 
column = new TableColumn( 
     
     
      
     table 
     
    ,SWT.NONE); 
column.setText("Message"); 
column.setWidth(500); 
table.setHeaderVisible(true); 
    

  請注意,這裡沒有 addColumn() 方法。相反,您把表實例傳入 TableColumn 構造器中。 TableItem 代表了表行。要對它進行初始化,將字符串數組(每列一個字符串)傳遞給它的 setText() 方法,如清單 3 所示。

清單 3. 添加新行
TableItem item = new TableItem(table,SWT.NONE); 
String[] text = new String[2]; 
text[0] = type; 
text[1] = t.getLocalizedMessage(); 
item.setText(text); 

  MessengerView 還實現了 Messenger 接口。老讀者會記得 Messenger 是 XM 用來打印消息的接口。 MessengerVIEw 只是將消息重定向到窗口。

  運行 XM 菜單

  彈出菜單在 XMRunner 類中實現。當用戶選擇菜單時,Eclipse 使用 IObjectActionDelegate 接口通知插件。 XMRunner 可在清單 4 中獲得。


清單 4. 應答用戶點擊
package org.ananas.xm.eclipse.runner; 
import Java.io.*; 
import Java.util.*; 
import org.ananas.xm.*; 
import org.eclipse.ui.*; 
import org.eclipse.ui.actions.*; 
import org.eclipse.jface.action.*; 
import org.eclipse.core.runtime.*; 
import org.eclipse.jface.dialogs.*; 
import org.eclipse.jface.vIEwers.*; 
import org.eclipse.core.resources.*; 
public class XMRunner 
  
     
     
      
     extends ActionDelegate 
     
     
  implements IObjectActionDelegate 
{ 
  public static final String PLUGIN_ID = 
   "org.ananas.xm.eclipse.runner"; 
  public static final String CONSOLE_ID = 
   "org.ananas.xm.eclipse.runner.vIEw.Console"; 
  private IFile selectedFile; 
  private IWorkbenchPart part; 
  
     
     
      
     public void run(IAction action) 
  { 
   try 
   { 
     if(part != null) 
     {  
      saveDirtyEditors(); 
      MessengerVIEw messenger = showConsole(); 
      if(messenger != null) 
      { 
        messenger.clean(); 
        runXM(messenger); 
      } 
      else 
        throw new NullPointerException("Failed."); 
     } 
   } 
   catch(Exception x) 
   { 
     ErrorDialog.openError(part.getSite().getShell(), 
                "XM","Exception.",makeStatus(x)); 
   } 
  } 
     
     
 
  public void selectionChanged(IAction action, 
                ISelection selection) 
  { 
   selectedFile = null; 
   if(selection instanceof IStructuredSelection) 
   { 
     IStructuredSelection structuredSelection = 
      (IStructuredSelection)selection; 
     if(structuredSelection.size() == 1) 
     { 
      Object selectedResource = 
        structuredSelection.getFirstElement(); 
      if(selectedResource instanceof IFile) 
        selectedFile = (IFile)selectedResource; 
     } 
   } 
  } 
 
  public void setActivePart(IAction action, 
               IWorkbenchPart targetPart) 
  { 
   part = targetPart; 
  } 
  private MessengerVIEw showConsole() 
   throws PartInitException 
  { 
   IWorkbenchPage page = 
     part.getSite().getWorkbenchWindow().getActivePage(); 
   MessengerVIEw messenger = null; 
   if(page != null) 
     messenger = (MessengerView)page.showVIEw(CONSOLE_ID); 
   return messenger; 
  } 
  private void runXM(Messenger messenger) 
   throws CoreException, IOException, XMException 
  { 
   InputStream is = selectedFile.getContents(); 
   Properties properties = new PropertIEs(); 
   propertIEs.load(is); 
   String rulesPath = 
        propertIEs.getProperty("rules","rules"), 
       sourcePath = 
        propertIEs.getProperty("source","src"), 
       publishPath = 
        propertIEs.getProperty("publish","publish"), 
       buildString = 
        propertIEs.getProperty("build","false"); 
   boolean build = 
     Boolean.valueOf(buildString).booleanValue(); 
   IResource parent = selectedFile.getParent(); 
   if(parent != null) 
   { 
     IPath parentPath = parent.getLocation(); 
     rulesPath = 
      parentPath.append(rulesPath).toOSString(); 
     sourcePath = 
      parentPath.append(sourcePath).toOSString(); 
     publishPath = 
      parentPath.append(publishPath).toOSString(); 
   } 
   DirectoryWalker walker = 
     new DirectoryWalker(messenger,rulesPath,build); 
   walker.walk(sourcePath,publishPath); 
  } 
  private IStatus makeStatus(Exception x) 
  { 
   Throwable t = MessengerVIEw.popThrowables(x); 
   if(t instanceof CoreException) 
     return ((CoreException)t).getStatus(); 
   else 
     return new Status(IStatus.ERROR, 
              PLUGIN_ID, 
              IStatus.ERROR, 
              x.getMessage(), 
              t); 
  } 
  private void saveDirtyEditors() 
  { 
   IWorkbenchWindow window = 
     part.getSite().getWorkbenchWindow(); 
   IWorkbenchWindow[] Windows = 
     window.getWorkbench().getWorkbenchWindows(); 
   for(int i = 0;i < Windows.length;i++) 
   { 
     IWorkbenchPage[] pages = Windows[i].getPages(); 
     for(int j = 0;j < pages.length;j++) 
      pages[j].saveAllEditors(false); 
   } 
  } 
} 
    

您應該把這個類當作 事件偵聽器。Eclipse 工作台使用它將用戶的選擇轉發給插件。該類從 ActionDelegate 繼承 - ActionDelegate 為 IObjectActionDelegate 的大部分提供了缺省實現。當用戶選擇導航器中的新文件時,Eclipse 工作台調用 selectionChanged() 。當用戶選擇菜單時,它調用 run() 方法,了解這一點非常重要。

  在 run() 中,插件保存編輯器的內容(如果用戶正在編輯文件,就保存它),將 XM 控制台調到前台並啟動 XM。 runXM() 和 XM 本身的 main() 方法之間的主要區別在於, main() 從命令行獲得其參數,而 runXM() 從特性文件讀取這些參數。

  額外時間

  這樣就完成了本月專欄文章要介紹的集成工作。但是請稍候,這裡還有一個工具!我發現 Eclipse 提供了基本 XML 編輯器。您只須編譯它。現在您編輯 XML 文檔時語法會突出顯現,並且可以通過 XM 發布它們。

  XML 編輯器

  Eclipse 的項目向導可以生成基本 XML 編輯器。過程如下:

  從 File菜單,選擇 New然後選擇 Project。

  在項目向導中,選擇 Plug-in Development和 Plug-in Project。如果您沒看到 Plug-in Development選項,請從 Eclipse 網站下載 Plug-in SDK。

  單擊 Next。

  給您的項目取個名字,比如 org.ananas.eclipse.XML.editor ,然後單擊 Next。

  單擊 Next以接受下一屏幕中的缺省值 - Plug-in Project Structure。

  確保選擇了 Create a plug-in project using a code generation wizard,並指向 Plug-in with an editor(請參閱 圖 2)。該向導自動生成帶有語法突出顯示的基本 XML 編輯器。

  單擊 Next。

  單擊 Finish接受下一屏幕中的選項 - Plug-in Content。Eclipse 創建新項目並編寫 XML 編輯器。

從 Project菜單,選擇 Rebuild All來構建項目。

  用該類文件生成名為 editor.jar 的 JAR 壓縮文檔。要從 Eclipse 創建 JAR,使用 File菜單中的 Export選項。這很重要 - 如果不生成 JAR 文件,Eclipse 就不會裝入您的插件。

  退出 Eclipse,在 workspace 目錄下尋找新項目。

  將項目目錄從 workspace 復制到 plug-in 目錄,然後重新啟動 Eclipse。

  當您雙擊 XML 文件時,XML 編輯器自動啟動。要與更多文件相關聯(比如 .xsl ),請選擇 Window > Preferences > Workbench,然後選擇 File Associations。


圖 2. 編譯隱藏的 XML 編輯器 
使用 XML: 使用 XML:集成 XM 和 Eclipse

  XM 更新

  當我使用 XM 時,我修正了幾個錯誤並添加一個選項以更改文件擴展名。缺省情況下,XM 把 .html 擴展名給 HTML 文件。XML 文件得到 .XML 擴展名。有些用戶可能需要將缺省值更改成 .htm 、 .sHtml 、 .rss 、 .wml 或其它擴展名。如果您需要這項功能,請復制清單 5 的代碼。請注意新的 rules:extension 屬性。


清單 5. 更改文件擴展名
<?XML version="1.0"?> 
<xsl:stylesheet version="1.0" 
  XMLns:xsl="http://www.w3.org/1999/XSL/Transform" 
  XMLns:rules="http://ananas.org/2001/XM/XSLT/Rules"> 
<xsl:output method="Html" 
       
     
     
      
     rules:extension="htm" 
     
    /> 
<!-- style sheet comes here --> 
</xsl:stylesheet> 
    

  這一特性和 XM 鏈接管理完全集成在了一起,因此您的所有鏈接都保持有效。

  工作將繼續進行

  只用了兩個類就從 Eclipse 啟動了 XM,這是對插件功能的證明。在我的下一篇專欄文章中,我打算編寫向導插件來初始化新的 XM 項目。同時,您可以下載並測試 XM 運行器插件。您將看到通過 Eclipsee 編輯和發布網站是件很愉快的事。然而,要提醒的是:目前插件只可用於 JDK 1.4。如果需要在 JDK 1.3.x 中運行 Eclipse,您必須安裝 Xalan 並相應地調整插件。


 

XML學習教程| jQuery入門知識| AJAX入門| Dreamweaver教程| Fireworks入門知識| SEO技巧| SEO優化集錦|
Copyright © DIV+CSS佈局教程網 All Rights Reserved