採用 3.0 版的機制和 API 時,需要做哪些變更?

本節主要在說明,如果您想要變更 2.1 版外掛程式,讓它採用 3.0 版的機制和 API,必須做哪些變更。

移除 org.eclipse.core.runtime.compatibility

Eclipse 3.0 執行時期有相當大的變動。 基礎實作是以 OSGi 組織架構規格為基礎。Eclipse 3.0 執行時期,含有維護 2.1 API 的相容性層(在 org.eclipse.core.runtime.compatibility 外掛程式中)。 對其他效能和功能有興趣的外掛程式開發人員,不妨考慮採用 3.0 API,並且移除它們對相容性層的相依關係。 相容性程式碼會出現在下列三個地方:

下列文字將詳細說明,哪些類別和方法是用於相容性,並且教導我們更新外掛程式。

外掛程式和軟體組

Eclipse 執行時期已經重構為兩個部分:類別載入和必備項目管理,以及延伸/延伸點管理。 重構為兩個部分之後,就可以自然/縝密的採用 OSGi 組織架構規格,來載入類別並且管理必備項目。 這樣一來,就可以在執行時期啟用某個範圍的新功能, 小從動態外掛程式安裝/更新/解除安裝,大到安全性和增加的可配性都有。

讓我們繼續談論外掛程式,外掛程式在新的執行時期當中, 是一個軟體組加上一些延伸和延伸點。軟體組這個詞彙,是由 OSGi 組織架構規格所定義, 它是指類型和資源以及相關交互軟體組必備項目資訊的集合。延伸登錄是新格式的外掛程式登錄, 它只詳細說明延伸和延伸點的資訊。 其實延伸登錄 API 就是相關的外掛程式登錄 API(如果需要詳細資訊,請參閱登錄)。

在 Eclipse 2.x 執行時期中,外掛程式物件有下列幾個角色和責任:

在 Eclipse 3.0 版的執行時期圖片當中,這些角色和責任被分解為不同的物件。

Bundle
Bundle 是模組化的 OSGi 單元。 每一個軟體組都有一個類別載入器,您可以建構類似 Eclipse 的交互軟體組類別載入相依關係圖形。 軟體組有啟動和停止的生命週期, 而 OSGi 組織架構則可以將軟體組相關的事件(例如,安裝、解析、啟動、停止、解除安裝 ...),廣播給有興趣的對象。 OSGi Bundle 類別不能繼承,這一點與 Eclipse Plugin 類別不同。 換句話說,開發人員沒有機會可以定義他們自己的軟體組類別。
BundleActivator
BundleActivator 是一個由 OSGi 組織架構所定義的介面。 每一個軟體組都可以定義一個軟體組啟動器類別, 就像外掛程式可以定義它的 Plugin 類別一樣。 指定的類別是由組織架構建立實例,並且用來實作 start()stop() 生命週期處理。 不過,這個生命週期處理的本質,有一個很大的不同點。 在 Eclipse 中,Plugin 類別通常(雖然最好不要)都身兼起始設定和登錄兩項工作。 而在 OSGi 中,啟動器只能執行登錄。 在 BundleActivator.start() 中大量執行起始設定(或其他任何工作),會威脅系統的存留時間。
BundleContext
BundleContexts 是 OSGi 機制,它可以顯現一般的系統功能給個別的軟體組。 每一個軟體組都有一個專屬且私密的 BundleContext 實例, 可讓它們存取系統功能(例如,getBundles() 可以探索系統中所有的軟體組)。
Plugin
新的 Plugin 很像原始的 Eclipse Plugin 類別, 但是下列幾項例外:執行時期不再需要 Plugin 物件,或者不再管理 Plugin 物件,有許多方法已經棄用了。 基本上它是一種方便機制,雖然提供一群有用的功能和機制,但它們卻再也用不著了。 它所提供的功能,有許多仍然可以用在執行時期的 Platform 類別。

Plugin 也會實作 BundleActivator。 此舉凸顯示了以一個中央物件代表外掛程式生命週期和語意的方便性。 不過請注意,它並不同意過於急切的起始設定資料結構,而這是現今外掛程式常見的動作。 我們不會因為在其他外掛程式中驗證類別時,參照了一個週邊類別,就強調外掛程式可以啟動。 換句話說,不能因為外掛程式已經啟動,就表示需要用到它的功能。 同時也請注意,您隨時可以定義不同的 BundleActivator 類別,或者根本就不要任何軟體組啟動器。

將 2.x 版的 Plugin 類別移轉到 Eclipse 3.0 版,需要執行哪些步驟, 全賴該類別在做什麼而定。 根據上述概要說明,大部分的啟動生命週期工作,都落在下列一項:

起始設定
資料結構和模型起始設定,常常是在 Plugin.startup() 完成。 如果在 BundleActivator.start() 中自然/明顯對映執行這項工作,就等於把這個工作交給 Plugin 不過我們強烈建議您不要這麼做。 就像使用 2.x 版的外掛程式一樣,3.0 版的外掛程式/軟體組也可能會因為不同的情況,不同的理由而啟動。
我們以 Eclipse 2.0 版的一個實際範例來示範這個情況。 某個外掛程式起始設定了一個大型模型,該模型要求載入約 11MB 的程式碼以及幾 MB 的資料。 通常這個外掛程式啟動的目的,是為了檢查導覽器所出現的專案圖示是否應該用特定的標記加以裝飾。 這個測試並不需要在 startup() 做任何起始設定, 如果急切的進行起始設定,只會讓所有使用個案中所有的使用者,付出時間和記憶體的代價。
另一個方法,就是以傳統的智慧型樣式來起始設定。 比方說,不要在外掛程式/軟體組啟動時起始設定模型, 而是在真正需要它們時才起始設定(例如,在集中模型 accessor 方法中)。 對於許多使用個案來說,這個方法幾乎都可以及時完成, 但對於某些實務來說,這個方法卻會延遲起始設定(也許是無限期延遲)。 我們建議您在移轉 2.1 版外掛程式時,最好仔細考慮起始設定策略,三思而後行。
登錄
您可以趁外掛程式啟動時,登錄接聽器、服務和啟動背景處理執行緒(例如,在 Socket 上接聽)。 您可以選擇在 Plugin.start() 執行這個作業。 有時候它也可能會因為等待其他觸發程式而延遲(例如,使用特定的功能或資料元素)。
外掛程式廣域資料
您的 Plugin 類別可以繼續扮演這個角色。 但問題是,Plugin 物件已經不能再透過系統管理的清單,進行廣域存取了。 在 Eclipse 2.x 版中,您可以透過外掛程式登錄, 來探索任何外掛程式的 Plugin 物件。但現在這個方法已經行不通了。 大部分的情況都不需要進行這類型的存取作業。 透過登錄來存取的 Plugin,比較常作為通用的 Plugin,而不是用來呼叫網域專用的方法。 您可以存取和操作對應的「軟體組」物件,取得同樣層次的功能。

登錄和外掛程式模型

在新的執行時期當中,執行外掛程式所需、以及與外掛程式延伸和延伸點相關的資訊和結構,已經有所區隔。 前者是由 OSGi 組織架構規格加以定義和管理。 後者則是 Eclipse 特有的概念,是由 Eclipse 執行時期程式碼加入。 因此,原始的外掛程式登錄和相關的物件,就此分成 OSGi 軟體組和 Eclipse 延伸登錄

處理執行規格的 IPluginRegistry 的部分(例如,IPluginDescriptor、ILibraryIPrequisite)已經棄用,剩下與延伸和延伸點相關的部分,則是移到 IExtensionRegistry。 甚至,所謂與外掛程式登錄相關的模型物件,現在也已經棄用了。 這些類型是由執行時期顯示並且建立實例,主要目的是支援像 PDE 這樣的工具。 不過,由於所需要的資訊層次,常常都超過執行時期的功能或興趣(例如,記得 plugin.xml 元素的行號), 最後還是得由執行時期資訊的潛在消費者,來維護他們自己的結構。

在新的執行時期當中,我們已經重新評估由執行時期所提供的機能, 現在只提供對於執行時期執行作業很重要的機能, 或者是其他人很難做到的機能。 如上所示,具有外掛程式剖析 API 的外掛程式登錄模型物件,現在已經棄用了。 新的延伸登錄會維護重要的延伸相關資訊。 新的 state(請參閱 org.eclipse.osgi.service.resolver.State 和伙伴)結構, 代表並且容許您操作與執行相關的重要資訊。

NL 片段結構

在 Eclipse 3.0 版中,NL 片段結構已經比以前更加一致了。 之前像 plugin.properties 這類檔案的轉換,都是在片段所提供的 JAR 內部執行。 由於原始檔案是放在相關主機外掛程式的根目錄下, 因此把轉換後的檔案放在 NL 片段的根目錄下,可以更加一致。 例如,

  org.eclipse.ui.workbench.nl/
     fragment.xml
     plugin_fr.properties
     plugin_pt_BR.properties
     ...
     nl1.jar

請注意,之前 nl1.jar 檔含有 plugin.properties 的轉換。 這些檔案現在都放在片段的根目錄下,而且 JAR 含有主機外掛程式中任何可翻譯之資源的轉換(亦即,透過類別載入器載入的檔案)。

當然,Eclipse 2.1 版的 NL 片段結構,仍然可以用在 Eclipse 3.0 版執行的 2.1 版主機外掛程式上。 不過,您不可以在 3.0 版的外掛程式,使用 2.1 版的 NL 片段。 該片段必須改為新的結構。

API 變更概觀

org.eclipse.core.boot (package org.eclipse.core.boot)

整個 org.eclipse.core.boot 套件現在已經棄用了。 BootLoader 已經與 org.eclipse.core.runtime.Platform 合併, 因為沒必要再把啟動和執行時期分開。 其實,org.eclipse.core.boot 外掛程式已經被拆解,所有的程式碼都被移到新的執行時期或是相容性層。

IPlatformConfiguration 一直是由 Eclipse 安裝/更新元件所定義,並且是針對它而定義。 將執行時期重組之後,我們就能夠把這個類型送回它真正的目錄了。 這個類別多半不會變更,而且已經被重新套裝為 org.eclipse.update.configurator.IPlatformConfiguration

IPlatformRunnable 已經移到 org.eclipse.core.runtime.IPlatformRunnable。

IExtension 和 IExtensionPoint (package org.eclipse.core.runtime)

getDeclaringPlugin() 方法(在這兩個類別)會提供一個通往分別宣告延伸或延伸點之外掛程式的向上鏈結。 新的登錄模型已經把外掛程式的執行層面和延伸/延伸點層面區隔開來,不再含有 IPluginDescriptors。 這個 API 的使用者應該考慮使用在 IExtensionIExtensionPoint 找到的新方法 getParentIdentifier()

ILibrary、IPluginDescriptor、IPluginRegistry 和 IPrerequisite (package org.eclipse.core.runtime)

在原始執行時期中,外掛程式登錄所維護的是完整的執行時期配置圖片。 但在 Eclipse 3.0 版中,這個圖片已被分成 OSGi 組織架構和延伸登錄了。 就本身來說,這些類別已經被棄用了。 棄用通知會詳細告訴您,如何更新您的程式碼。

平台和外掛程式 (package org.eclipse.core.runtime)

在新的執行時期當中,Plugin 物件已經不再被執行時期管理,因此無法透過平台,進行一般存取作業。 同樣的,外掛程式登錄已經不存在,或者不再給予外掛程式描述子的存取權了。 不過,卻有適合的置換方法可以使用,詳細資訊可以參閱這些類別中已經棄用之方法的 Javadoc。

org.eclipse.core.runtime.model (package org.eclipse.core.runtime.model)

本套件中所有的類型已經全部棄用。 如果需要其他詳細資訊,請參閱登錄的相關討論。

IWorkspaceRunnable 和 IWorkspace.run (package org.eclipse.core.resources)

IWorkspace.run(IWorkspaceRunnable,IProgressMonitor) 方法的用戶端, 應該重新造訪它們使用這個方法的地方, 並且考慮使用更好的方法 IWorkspace.run(IWorkspaceRunnable,ISchedulingRule,int,IProgressMonitor)。 舊的 IWorkspace.run 方法在進行 IWorkspaceRunnable 時,需要鎖定整個工作區。 也就是說,以這個方法完成的作業,永遠都不可能與其他變更工作區的作業同時執行。 在 Eclipse 3.0 版中,許多長時間執行的作業,已經移到背景緒, 因而作業與作業之間發生衝突的可能性,也大為增加。 如果前景作業被長時間執行的背景作業中斷了, UI 必須等到前景作業完成之後,或者等到其中一個作業被取消之後,才能夠恢復。

我們建議您切換所有舊 IWorkspace.run 的參照,改用含有排程規則參數的新方法。 排程規則應該是最精細的規則,它包含了該作業所有變更用的規則。 如果該作業想要修改排程規則範圍以外的資源,便會發生執行時期異常狀況。 工作區作業所要求的精確排程規則並沒有指定,而且可能會根據安裝在專案上的儲存庫提供者而改變。 您應該利用 Factory IResourceRuleFactory,取得資源變更作業用的排程規則。 必要時,也可以用 MultiRule 來指定多個資源規則, 而且可以用 MultiRule.combine 方便方法, 從各種資源變更作業來組合規則。

如果不必做任何鎖定動作,那就使用 null 的排程規則。 這麼一來,就可以容許可執行的方法來修改工作區中所有的資源,但並不會防止其他執行緒同時修改同一個工作區。 如果只是對工作區進行簡單的修改,這個方法通常是最容易而且最適合並行作業的解決方案。

IWorkbenchPage (package org.eclipse.ui)

IEditorDescriptor (package org.eclipse.ui)

ISharedImages (package org.eclipse.ui)

IWorkbenchActionConstants (package org.eclipse.ui)

IWorkbenchPreferenceConstants (package org.eclipse.ui)

IExportWizard (package org.eclipse.ui)

IImportWizard (package org.eclipse.ui)

INewWizard (package org.eclipse.ui)

WorkbenchHelp (package org.eclipse.ui.help)

IHelp (package org.eclipse.help)

ITextEditorActionConstants (package org.eclipse.ui.texteditor)

IAbstractTextEditorHelpContextIds (package org.eclipse.ui.texteditor)

BasicTextEditorActionContributor (package org.eclipse.ui.texteditor)

TextEditorActionContributor (package org.eclipse.ui.editors.text)

annotationTypes 延伸點(外掛程式 org.eclipse.ui.editors)

現在註釋類型有明確的記號。 請參閱 Annotation.getType() 和 Annotation.setType()。 註釋的類型在生命期限內可能會變更。 為了宣告註釋類型 "org.eclipse.ui.editors.annotationTypes",因此加了新的延伸點。 註釋類型有其名稱,而且可以被宣告為另一個被宣告之註釋類型的子類型。 註釋類型宣告也可以使用屬性 "markerType" 和 "markerSeverity", 來指定在文字編輯器中,以特定註釋類型的註釋,來代表類型和嚴重性的標記。 而 "org.eclipse.ui.editors.markerAnnotationSpecification" 中的屬性 "markerType" 和 "markerSeverity", 則不應再使用。 現在標記註釋規格與標記已經沒有關係了,因此這個名稱可能會產生誤導。 不過,為了確保反向相容性,這個名稱仍然不變。

AbstractMarkerAnnotationModel 的子類別的實例, 會自動為它們從標記建立的註釋,偵測並且設定正確的註釋類型。 為了以程式設計的方式,來擷取標記或 markerType 和 markerSeverity 這對標記的註釋類型, 請使用 org.eclipse.ui.texteditor.AnnotationTypeLookup。

註釋類型階層的存取權,是由 IAnnotationAccessExtension 所提供。 您可以針對一個註釋類型取得 Super 類型的鏈,並且檢查註釋類型是不是另一個註釋類型的子類型。 DefaultMarkerAnnotationAccess 會實作這個介面。

markerAnnotationSpecification 延伸點(外掛程式 org.eclipse.ui.editors)

註釋類型是尋找相關標記註釋規格的關鍵。 註釋類型可以延伸其他的註釋類型,標記註釋規格之間有隱含的關係。 因此,某個註釋類型的標記註釋規格,是由指派給某個註釋類型之 Super 類型的標記註釋規格所完成。 因此,標記註釋規格不必像以前要求的這麼完整。 標記註釋規格是由 AnnotationPreferences 擷取。 您可以利用 org.eclipse.ui.texteditor.AnnotationPreferenceLookup, 針對一個以透通方式連同註釋 Super 類型鏈一起完成喜好設定的註釋類型, 來擷取註釋喜好設定。

標記註釋規格已經以另外三個屬性加以延伸,以便在垂直尺規定義某個註釋類型的自訂外觀。 這些屬性有:"icon"、"symbolicIcon" 和 "annotationImageProvider"。 "icon" 的值是通往含該圖示影像之檔案的路徑。 "symbolicIcon" 的值,是 "error"、"warning"、"info"、"task"、"bookmark" 的其中一項。 "symbolicIcon" 屬性的用途,則是告訴平台,應該以平台用來表示錯誤、警告、資訊、作業和書籤的影像,來描述註釋。 "annotationImageProvider" 的值是實作 org.eclipse.ui.texteditor.IAnnotationImageProvider 的一個類別, 可讓您完全自訂註釋表示法。

垂直尺規是利用與它相關的 IAnnotationAccess/IAnnotationAccessExtension 來繪製註釋。 垂直尺規不會再呼叫 Annotation.paint 了。 通常,註釋應該是不會繪製它本身。 為了讓註釋與 UI 彼此獨立,現在已經不用 "paint" 和 "getLayer" 方法了。 DefaultMarkerAnnotationAccess 是 IAnnotationAccess/IAnnotationAccessExtension 的預設實作。 DefaultMarkerAnnotationAccess 會實作下列策略來繪製註釋: 如果註釋實作 IAnnotationPresentation,就呼叫 IAnnotationPresentation.paint。 如果不是,則查詢註釋喜好設定中的註釋影像提供者。 註釋影像提供者只有在指定時,以及在定義含括標記註釋規格的外掛程式已經載入時才能使用。 如果有註釋影像提供者,則呼叫就會轉遞給它。 如果沒有,則會查詢指定的 "icon"。 "symbolicIcon" 相當於最終的 fallback。 對於繪製註釋來說,註釋呈現層是相關的。 DefaultMarkerAnnotationAccess 會採用下述策略來查詢呈現層: 如果註釋喜好設定指定呈現層,則採用指定層。 如果沒有任何層和註釋實作 IAnnotationPresentation, 則採用 IAnnotationPresentation.getLayer, 否則就傳回預設的呈現層(為 0)。

移轉到 annotationTypes 延伸點(外掛程式 org.eclipse.ui.editors)

下列註釋類型是由 org.eclipse.ui.editors 外掛程式所宣告:

   <extension point="org.eclipse.ui.editors.annotationTypes">
      <type
         name="org.eclipse.ui.workbench.texteditor.error"
         markerType="org.eclipse.core.resources.problemmarker"
         markerSeverity="2">
      </type>
      <type
         name="org.eclipse.ui.workbench.texteditor.warning"
         markerType="org.eclipse.core.resources.problemmarker"
         markerSeverity="1">
      </type>
      <type
         name="org.eclipse.ui.workbench.texteditor.info"
         markerType="org.eclipse.core.resources.problemmarker"
         markerSeverity="0">
      </type>
      <type
         name="org.eclipse.ui.workbench.texteditor.task"
         markerType="org.eclipse.core.resources.taskmarker">
      </type>
      <type
         name="org.eclipse.ui.workbench.texteditor.bookmark"
         markerType="org.eclipse.core.resources.bookmark">
      </type>
      </extension>

定義的 markerAnnotationSpecification 延伸,不再提供 "markerType" 和 "markerSeverity" 屬性。 它們是以對應的值來定義 "symbolicIcon" 屬性。 因此,它們不會再呼叫 MarkerAnnotation.paint 和 MarkerAnnotation.getLayer, 換句話說,就算置換這些方法也沒有用。 影響所及的用戶端應該實作 IAnnotationPresentation。

ILaunchConfigurationType (package org.eclipse.debug.core)

由於 3.0 版引進了可延伸的啟動模式,因此一個啟動配置類型可以有多個啟動委派存在。 3.0 版之前的版本,只支援一個啟動配置類型一個啟動委派。 現在 ILaunchConfigurationType.getDelegate() 方法已經棄用了。 getDelegate(String mode) 方法應該在這裡用來擷取特定啟動模式的啟動委派。 已經棄用的方法,則改為傳回 run 模式的啟動委派。

ILaunchConfigurationTab 和 ILaunchConfigurationTabGroup(套件 org.eclipse.debug.ui)

現在啟動完成時,不會再通知啟動標籤群組和啟動標籤了。 ILaunchConfigurationTabILaunchConfigurationTabGroup 介面中 的 launched(ILaunch) 方法已經棄用,不再呼叫。 由於只有從啟動對話框執行啟動時,才有標籤存在,因此啟動功能採用這個方法不是很可靠。 同時,自從引進背景啟動之後,就再也不能呼叫這個方法了, 因為在得出啟動物件之前,就會關閉啟動對話框。

ILaunchConfigurationTab 和 AbstractLaunchConfigurationTab(套件 org.eclipse.debug.ui)

ILaunchConfigurationTab 介面已經加入下列兩個方法 - activated 和 deactivated。 在標籤進入和退出時,會分別呼叫這兩個新的生命週期方法。 將除錯外掛程式所提供的抽象類別分成子類別的現有 ILaunchConfigurationTab 實作 (AbstractLaunchConfigurationTab), 是採用二進位方式,因為這些方法是在抽象類別上實作。

在舊版當中,當標籤啟動時,會收到 initializeFrom 訊息, 取消啟動時,則會收到 performApply 訊息。 啟動配置標籤組織架構就是透過啟動配置來提供交互標籤通訊 (當標籤退出時,以現行屬性值來更新配置,並且更新剛輸入的標籤)。 不過,由於許多標籤都不執行交互標籤通訊,因此光是這樣可能還不夠。 同時,被啟動的標籤,以及第一次顯示所選啟動配置的標籤,其實很難分辨。 剛剛加入的方法,可以讓標籤分辨啟動和起始設定,以及取消啟動和儲存現行值。

activated 的預設實作是由抽象標籤所提供,它會呼叫 initializeFromdeactivated 的預設實作則是呼叫 performApply。 想要利用新 API 的標籤,應該根據它們的需要,換掉這些方法。 對於不執行交互標籤通訊的標籤來說,通常我們建議它重新實作這些方法,不做任何動作。

launchConfigurationTabGroup 延伸點類型(套件 org.eclipse.debug.ui)

在舊版當中, 視景切換是透過啟動配置屬性 ATTR_TARGET_DEBUG_PERSPECTIVEATTR_TARGET_RUN_PERSPECTIVE, 在啟動配置上指定。 由於在 3.0 版加入了可以延伸的啟動模式,因此這種方式就不再調整比例了。 現在,每一個啟動配置類型支援的啟動模式,都會以啟動配置類型指定視景切換。 API 已經加到 DebugUITools,目的是為了設定和取得與特定啟動模式之啟動配置類型相關的視景。

launchConfigurationTabGroup 延伸點另外加了一個選擇性的 launchMode 元素, 讓提供的標籤群組針對啟動配置和模式,指定一個預設視景。

使用者可以從 Eclipse 使用者介面,編輯與啟動配置類型相關的視景, 方法是開啟啟動配置對話框,以及在樹狀結構(而不是在個別配置)選取啟動配置類型節點。 標籤可以讓使用者以每一個支援的啟動模式來設定視景。

[只限 JDT] IVMRunner(套件 org.eclipse.jdt.launching)

VMRunnerConfiguration 類別加了兩個方法,來支援環境變數的設定和擷取。 IVMRunner 的實作程式應該呼叫 VMRunnerConfiguration.getEnvironment(), 並且將環境傳到執行的 JVM。 使用 DebugPlugin.exec(String[] cmdLine, File workingDirectory) 的用戶端, 可以改而呼叫 DebugPlugin.exec(String[] cmdLine, File workingDirectory, String[] envp)。 他們只要傳遞 getEnvironment() 的結果就行了。

[只限 JDT] VMRunnerConfiguration 和 Bootstrap 類別(套件 org.eclipse.jdt.launching)

在舊版當中,VMRunnerConfiguration 有一個屬性負責說明啟動路徑。 該屬性是 -Xbootclasspath 引數所指定的 Strings 集合。 VMRunnerConfiguration 一共加了三個新屬性來支援 JVM,這些 JVM 容許您附加在啟動路徑的前面和後面。 下面是新加入的方法/屬性:

舊引數 getBootClassPath() 仍然存在,而且含有相當於三個新屬性之路徑的完整路徑。 不過,支援新啟動路徑選項的 VMRunners,應該利用新的屬性。

[只限 JDT] 工作複本的改良支援(套件 org.eclipse.jdt.core)

在 3.0 版中,Java 模型工作複本機能已經重做,以提供大幅增加的功能。 在 3.0 版之前,Java 模型可以讓您個別建立編譯單元的工作複本。 您可以先在工作複本變更,稍後再加以確定。 舊版支援在剩下的 Java 模型的環境定義中,對工作複本進行有限的分析。 不過,這些分析一次只能針對一個工作複本。

3.0 版的變更,就可以建立和管理幾組編譯單元的工作複本,並且對所有的工作複本進行分析。 比方說,現在像 JDT 這樣的用戶端就可以進行重構,為多個它考慮在工作複本之間修改然後解析類型參照的編譯單元,建立工作複本。 過去只有在您對編譯單元工作複本所做的變更經過確定之後,才能這麼做。

Java 模型 API 以下面兩種方式變更,以加入這個改良式的支援:

(1) 過去在 IWorkingCopy 的功能,以及由 ICompilationUnit 繼承的功能, 已經合併到 ICompilationUnit 中了。 IWorkingCopy 介面只能用在這個地方,而且太過籠統,不符所需。 這項改變簡化了 API。 IWorkingCopy 現在已經棄用。 其他在 API 中,把 IWorkingCopy 作為參數,或是已經棄用結果類型的地方, 置換 API 方法是以 ICompilationUnit 代替 IWorkingCopy

(2) 介面 IBufferFactory 已經換成 WorkingCopyOwner。 工作複本的改良支援,要求必須有一個物件擁有這些工作複本。 雖然 IBufferFactory 是位於正確的地方,但是這個名稱卻不足以表達新工作複本機制的運作方式。 WorkingCopyOwner 就好多了。 此外,WorkingCopyOwner 是宣告為抽象類別,而不是介面, 這是為了讓工作複本擁有者的記號在未來逐步成形。 IBufferFactory 的方法則是移到 WorkingCopyOwnerWorkingCopyOwner 並未實作 IBufferFactory,此舉明白表示 IBufferFactory 已經過氣了。 IBufferFactory 已經棄用了。 其他在 API 中,把 IBufferFactory 作為參數,或是結果類型已經棄用的地方, 置換 API 方法是以 WorkingCopyOwner 代替 IBufferFactory

這些變更不會中斷二進位相容性。

在進行移轉時,所有 IWorkingCopy 類型的參照,都應該參照 ICompilationUnit 才是。 單獨實作 IWorkingCopy 時,也會實作 ICompilationUnit, 這表示類型為 IWorkingCopy 的物件, 可以安全的強制轉型為 ICompilationUnit

實作 IBufferFactory 的類別,必須換成 WorkingCopyOwner 的子類別。 雖然 WorkingCopyOwner 不會實作 IBufferFactory 本身, 但卻可以宣告實作 IBufferFactoryWorkingCopyOwner 的子類別, 因而在新舊版之間建立橋接 (由 IBufferFactory 宣告 createBuffer(IOpenable), 由 WorkingCopyOwner 宣告 createBuffer(ICompilationUnit); 而由 ICompilationUnit 延伸 IOpenable)。

由於變更涵蓋了 IWorkingCopyIBufferFactory,因此我們建議您同時處理兩者。 下面是有關棄用的詳細資訊:

重組 org.eclipse.help 外掛程式

用來存放 API 和延伸點,以便提供給說明系統並且延伸說明系統,以及顯示說明的 org.eclipse.help 外掛程式, 現在只含有 API 和延伸點,以提供和存取說明資源。 該外掛程式內預設說明 UI 實作的一部分, 已經連同 API 移到新的外掛程式 org.eclipse.help.base,以便延伸實作。 提供說明 UI 和顯示說明的 API 和延伸點,則是移到 org.eclipse.ui 外掛程式。 這項重組作業可以給應用程式在說明系統方面有更大的彈性; 新的結構可以讓以通用工作台為基礎的應用程式, 提供自己的說明 UI 和(或)說明實作,或者全盤省略說明系統。

由於影響所及的延伸點和 API 套件,只供說明系統本身使用, 因此現有的外掛程式很可能會受到這項變更的影響。 它們會併到這裡,只是為了保持完整性而已:

新的搜尋 UI API

實作自訂搜尋所用的新 API,已經加到 3.0 版了。 原始 API 在 3.0 版已經棄用, 我們建議用戶端移轉到 org.eclipse.search.ui 和 org.eclipse.search.ui.text 套件中的新 API。

用戶端必須建立 ISearchQueryISearchResultISearchResultPage 的實作。 ISearchResultPage 實作必須加到新的org.eclipse.search.searchResultViewPages 延伸點當中。

ISearchResultISearchResultPage 的預設實作,是在套件 org.eclipse.search.ui.text 中提供。

MessageBox 和 DirectoryDialog 中的空值訊息(套件 org.eclipse.swt.widgets)

在 3.0 版之前,以空值字串呼叫 SWT 的 DirectoryDialog.setMessage(String string) 或 MessageBox.setMessage(String string),會產生一個沒有標題文字的對話框。 這項行為不是指定行為(傳遞空值是絕對不允許的),因此會產生一些問題,並且附隨 getMessage, 表示不容許傳回空值。 到了 3.0 版,傳遞空值則會擲出 IllegalArgumentException 異常狀況, 規格中也會跟著做一些變更,讓它與 Super 類別 Dialog.setMessage 上的方法一致。 如果您是使用 Dialog.setMessage 時,請務必傳遞非空值的字串。 不過如果您希望對話框的標題沒有文字,那就儘管傳遞空字串吧。

改良 modal 進度回饋

要支援並行作業,需要更準確的方法來顯示 modal 進度。 在類別 IProgressService 中,另外還實作了其他的進度支援作為回應。 雖然以 ProgressMonitorDialog 來顯示進度的方法,目前仍然在用, 不過為了讓使用者用起來更得心應手,我們建議您還是移轉到新的 IProgressService 吧。

顯示 Eclipse 3.0 版的 Modal 進度一文,將說明如何移轉到新的 IProgressService。

「除錯動作群組」已經移除

「除錯動作群組」延伸點 (org.eclipse.debug.ui.debugActionGroups) 現在已經移除了。 在 Eclipse 3.0 版中,工作台會透過 org.eclipse.platform.ui.activities 延伸點引進活動支援。 這項支援不但提供「除錯動作群組」所提供的所有功能,而且更加好用(它支援型樣,而不是辛苦的指定所有的動作), 另外,還有程式設計 API 支援它。 即使無法移除舊延伸點的參照,也不會導致任何失敗。 延伸點的參照,大可略過不管。 產品供應商可以利用工作台活動支援,將語言特有的除錯器動作, 關聯到語言特有的活動(例如,C++ 除錯動作,可能與「開發 C++」這個活動相關聯)。

BreakpointManager 可以停用

IBreakpointManager 可定義 setEnabled(boolean) 和 isEnabled() 兩種方法。 當岔斷點管理程式停用時,除錯器應該會略過所有登錄的岔斷點。 除錯平台也會提供新的接聽器機制 IBreakpointManagerListener, 這項機制可以讓用戶端在岔斷點管理程式登錄, 只要啟用狀態一有變動,就會收到通知。 「岔斷點」視圖會從新的切換動作,呼叫這個 API,讓使用者「跳過所有的岔斷點」。 由於除錯器不接受岔斷點管理程式的啟用動作, 因此只要使用者一使用這項功能,就會使它中斷。

[只限 JDT] Java 搜尋參與者(套件 org.eclipse.jdt.core.search)

只要是接近 Java(例如,JSP、SQLJ、JWS 等)的語言,應該都能夠參與 Java 搜尋作業。 尤其是,這類語言的實作程式應該都能夠:

這類實作程式稱為搜尋參與者。 它繼承了 SearchParticipant 類別。搜尋參與者會傳遞給搜尋查詢 (請參閱 SearchEngine.search(SearchPattern, SearchParticipant[], IJavaSearchScope, SearchRequestor, IProgressMonitor))。

不管是為相符的項目製作索引還是尋找相符的項目,搜尋參與者都必須定義 SearchDocument 的子類別, 該子類別可以置換 getByteContents() 或 getCharContents(),來擷取文件內容。 這個子類別的實例,會在 getDocument(String) 傳回。

如果搜尋參與者想要為某個文件製作索引,會使用 SearchParticipant.scheduleDocumentIndexing(SearchDocument, IPath) 來排定在某個索引製作文件索引的時間表。 只要文件可以製作索引了,基礎組織架構便會呼叫 SearchParticipant.indexDocument(SearchDocument, IPath)。 搜尋參與者就取得文件內容,加以剖析,然後利用 SearchDocument.addIndexEntry(char[], char[]) 加入索引項目。

完成索引作業之後,就可以查詢索引, 利用 SearchEngine.search(SearchPattern, SearchParticipant[], IJavaSearchScope, SearchRequestor, IProgressMonitor),尋找相符的項目。 首先得利用 SearchParticipant.selectIndexes(SearchPattern, IJavaSearchScope), 向每一個搜尋參與者,索取這個查詢所需要的索引。 只要找到與給定型樣相符的索引項目,就會要求搜尋參與者建立一份搜尋文件(請參閱 getDocument(String))。 這些文件都會傳給搜尋參與者, 讓它利用 locateMatches(SearchDocument[], SearchPattern, IJavaSearchScope, SearchRequestor, IProgressMonitor),尋找相符的項目。 搜尋參與者會利用 acceptSearchMatch(SearchMatch),並且傳遞 SearchMatch 的子類別實例, 通知 SearchRequestor 找到相符的項目。

搜尋參與者可以委派部分工作給預設的 Java 搜尋參與者。 這個預設參與者的實例,是利用 SearchEngine.getDefaultSearchParticipant() 取得。 比方說,當 SQLJ 參與者被要求尋找相符項目時, 可以從它的 .sqlj 文件建立 .java 文件, 並且將 .java 文件傳給預設的參與者,委派工作給他。