以下是模型提供者能夠執行哪些動作來利用團隊邏輯模型支援的清單:
下列各節會分別詳細說明這幾點。 org.eclipse.team.examples.filesystem 外掛程式含有一個範例,可以說明若干這些要點。 您可以從 CVS 儲存庫移出專案,用它來作為閱讀這份教學指導時的參考資料。免責聲明:這個範例外掛程式中的程式碼可能會在一段時間之後有所改變。 如果要取得符合這個範例所用內容的副本,您可以利用 3.2 版標示(很可能是 R3_2)或 2006 年 6 月 28 日的日期標示來移出專案。
資源對映 API 有意簡化,省略了邏輯模型的操作。 用戶端無法利用這個介面來顯示邏輯模型,或取得任何其他有用的相關知識。 它的目的是簡化成將一或多個模型元素對映至工作區資源。
這個 API 由下列類別組成:
Object getModelObject()
:衍生(或改寫)對映的來源模型物件。ResourceTraversal[] getTraversals(ResourceMappingContext, IProgressMonitor)
:涵蓋組成模型物件之資源的資源遍訪。ResourceTraversal
包含一組資源和一個深度旗標,旗標指出遍訪的資源關聯於起源模型物件的深度。
資源對映將資源遍訪提供給用戶端,以便說明模型內容,讓用戶端(如儲存庫提供者)能夠儘可能有效執行它的作業。
有用的方法如下:
getResources()
getDepth()
ResourceMappingContext
和 RemoteResourceMappingContext
用起來稍微複雜一些,請參閱資源對映環境定義一節,以取得相關說明。
在資源對映中,有兩類應該有用的外掛程式。 一種是提供模型的外掛程式,且所提供的模型由工作區資源組成或持續保存在工作區資源中,一種是想要在資源上執行作業的外掛程式。 下一節討論前面一種,邏輯模型整合的儲存庫導覽圖會討論後面一種。
如果物件如何改寫來配合資源的說明越豐富越好,改寫模式物件來配合 IResource
,以便將特定資源專用動作顯示在快速功能表的外掛程式,現在可以配合 ResourceMapping
來改寫。
不過,如果沒有好處,便不需要如此。
例如,目前配合 IFile
的 Java 編譯單元(也就是 JDT 視圖所顯示的 *.java 檔)不需要改成配合 ResourceMapping
,因為沒有好處。
不過,Java 套件應該配合 ResourceMapping
,以便指出套件只由對應資料夾中的檔案組成,子資料夾不包括在內。
使用配接器 Factory 是配合資源對映來改寫模型元素的偏好方式。 以下是在外掛程式 Manifest 中提供配接器 Factory 的 XML 標記。
<extension
point="org.eclipse.core.runtime.adapters">
<factory
class="org.eclipse.example.library.logical.AdapterFactory"
adaptableType="org.eclipse.example.library.Book">
<adapter type="org.eclipse.core.resources.mapping.ResourceMapping"/>
</factory>
<factory
class="org.eclipse.example.library.logical.AdapterFactory"
adaptableType="org.eclipse.example.library.Library">
<adapter type="org.eclipse.core.resources.mapping.ResourceMapping"/>
</factory>
...
</extension>
配接器 Factory 實作看起來會如下:
public class AdapterFactory implements IAdapterFactory {
public Object getAdapter(Object adaptableObject, Class adapterType) {
if((adaptableObject instanceof EObject) && adapterType == ResourceMapping.class) {
return new EObjectResourceMapping((EObject)adaptableObject);
}
return null;
}
public Class[] getAdapterList() {
return new Class[] {ResourceMapping.class};
}
}
模型物件可以實作 IAdaptable
介面。
當它們實作這個介面時,它們必須確定咨詢了平台配接器管理者。
繼承 PlatformObject
或使用下列程式碼行,便可以完成這項作業:
Platform.getAdapterManager().getAdapter(Object, Class)
以上是偏好的方法。
不過,模型物件可以實作 IAdaptable 介面及提供所建立的 getAdapter(Class)
實作,當要求 ResourceMapping
實例時,它會明確傳回一個。
這是比較直接而明確的方法,但卻最不好,因為模型必須明確瞭解配合資源來進行的改寫作業。
在某些情況下,邏輯模型的提供者可能不想讓它們的模型在每個環境定義中都配合 IResource
,或者關於提供物件,相對於其他環境定義,邏輯模型提供者也可能會想讓物件以不同的方式來配合。
工作台使用者介面為了這個目的,提供了特殊的中間配接器 API IContributorResourceAdapter
。
當在提供物件的環境定義中,正在配合 IResource
來改寫物件之時,工作台會先嘗試配合 IContributorResourceAdapter
來改寫資源,之後,才會嘗試直接配合 IResource
來改寫。
IContributorResourceAdapter2
是這個介面的新的子介面,它提供了與 ResourceMapping
相同的功能。
不同之處,只有模型提供者應該登錄 IContributorResourceAdapter
的 Factory,因為工作台會執行 instanceof 檢查,以瞭解所提供的配接器是否也是 IContributorResourceAdapter2
的實例。
Java 套件 ResourceMapping
子類別的實作看起來應該如下。
public class JavaPackageResourceMapping extends ResourceMapping {
IPackageFragment package;
...
public getModelObject() {
return package;
}
public ResourceTraversals[] getTraversals(
ResourceMappingContext context,
IProgressMonitor monitor) {
return new ResourceTraversal[] {
new ResourceTraversal(
new IResource[] { package.getCorrespondingResource() },
IResource.DEPTH_ONE, IResource.NONE)
}
}
}
這是一項直接而明確的對映,因此,實作並不複雜。 當然,不同模型的資源對映實作,會有各不相同的複雜度。
「資源對映 API」的好處之一,是它容許外掛程式在資源對映方面,實作它們所需要的任何作業(如 CVS 更新、CVS 確定、CVS 標示、用過的裝飾等)。不過,目前所引進的 API 只會處理模型的本端狀態。 當使用可能有開發人員在共用的模型時,您會進入模型的遠端狀態(也就是另一位使用者已移入儲存庫之模型的狀態)不同於工作區狀態的情況。 如果您執行 CVS 更新,您會想要模型的本端狀態符合遠端狀態,即使這代表了必須併入或刪除一些檔案,也是如此。
對某些邏輯模型而言,這不是問題。 比方說,Java 套件便是被造訪到某個深度的儲存檔案,不論模型的遠端狀態為何,都是如此。 在這個情況下,儲存庫提供者可以輕易判斷在確定時應該併入送出刪除,在更新時應該併入送入新增。 不過,構成某些邏輯模型的資源可能會隨著時間而改變。 例如,構成模型元素的資源可能會相依於 Manifest 檔(或其他類似機制)的內容。 為了使資源對映傳回適當的遍訪,它必須存取 Manifest 檔的遠端內容(如果不同於本端內容的話),以便瞭解是否需要併入其他資源。 這些其他資源不一定會在工作區中,但儲存庫提供者會知道在執行所選取動作時,如何確定它們在工作區中。
如果要支援這些比較複雜的模型,您可以將 RemoteResourceMappingContext
傳給 ResourceMapping#getTraversals
方法。
當提供環境定義時,對映可以利用它來確定遍訪併入了所有必要的資源。
如果未提供環境定義,對映可能假設只有本端狀態有用。
ResourceMapping
只需要擔心提供給 getTraversals
方法的環境定義,以防組成模型的資源隨著時間而改變,而保證將組成模型的這些資源(也只有這些資源)封裝起來的簡式遍訪卻無法說明模型和資源之間的關係。
例如,雖然 Java 套件的資源可能隨著時間而改變,套件仍可以被說明為深度為 1 的資料夾,因此,Java 套件的資源對映仍可以使用資源對映的環境定義。
我們設想一個比較複雜的範例:含有若干影像的 HTML 檔。
我們假設 HTML 檔所參照的任何影像都屬於這個檔案的模型。
當從儲存庫更新 HTML 檔的本端內容時,使用者會預期任何新的影像都包括在內。HTML 檔案模型 ResourceMapping
的 getTraversals
方法看起來會類似於:
public class HTMLResourceMapping extends ResourceMapping {
private HTMLFile htmlFile;
public ResourceTraversal[] getTraversals(ResourceMappingContext context,
IProgressMonitor monitor)
IResource[] resources = htmlFile.getResources();
if (context instanceof RemoteResourceMappingContext) {
// Look for any additional resources on the server
RemoteResourceMappingContext remoteContext = (RemoteResourceMappingContext)context;
IFile file = htmlFile.getFile();
if (remoteContext.hasRemoteChange(file, monitor)) {
IStorage storage = remoteContext.fetchRemoteContents(file, monitor);
IResource[] additionalResources = getReferences(storage.getContents());
resources = combine(resources, additionalResources);
}
if (remoteContext.isThreeWay() && remoteContext.hasLocalChange(file, monitor)) {
IStorage storage = remoteContext.fetchBaseContents(file, monitor);
IResource[] additionalResources = getReferences(storage.getContents());
resources = combine(resources, additionalResources);
}
}
y return new ResourceTraversal[] {
new ResourceTraversal(resources, IResource.DEPTH_ZERO, IResource.NONE)};
}
}
請注意,模型包括兩組資源:在工作區中從 HTML 檔本端內容衍生而來的資源,以及取自遠端檔案和基本檔案內容的資源。 這兩組資源都可能有不在工作區中的資源。 例如,本端 HTML 檔可能含有相對鏈結,通往不在工作區中的影像。 您應該併入這項資源,以便當它在遠端時,能夠提取它。 至於遠端檔案,它可能含有新副本,參照下載新遠端內容時所應提取的其他影像。
模型提供者用來將相關資源對映分成一組的方法。 以下是通往 ModelProvider 類別的鏈結。 這個類別有三個主要用途:
IResourceMappingMerger
便是改寫模型提供者而取得。以下是 modelProvider 延伸定義的範例。
<extension
id="modelProvider"
name="Library Example"
point="org.eclipse.core.resources.modelProviders">
<modelProvider
class="org.eclipse.team.examples.library.adapt.LibraryModelProvider"
name="Library Example"/>
<extends-model id="org.eclipse.core.resources.modelProvider"/>
<enablement> <test property="org.eclipse.core.resources.projectNature" value="org.eclipse.team.examples.library.view.nature" />
</enablement>
</extension>
LibraryModelProvider
是 ModelProvider
的子類別。
啟用規則用來比對「程式庫」模型將它的模型持續保存在其中的資源。
在上述範例中,模型提供者會比對含程式庫本質之專案中的任何資源。
定義好模型提供者之後,應該置換 ResourceMapping#getModelProviderId()
方法來傳回模型提供者的 ID。
public String getModelProviderId() {
return "org.eclipse.team.examples.library.adapt.modelProvider";
}
對於符合提供者啟用規則的資源,如果要取得資源對資源的對映之適當倒轉對映,您也應該置換兩個 getMapping
方法或其中之一。
您必須置換的方法會隨著模型是否有元素含有多項資源而不同。
如果您的模型元素對映至單一資源,您可以置換接受單一 IResource
引數的方法。
否則,您必須置換接受資源陣列的方法。
以下是使用單一資源案例的範例。
下列範例方法將程式庫模型檔包裝在適當的資源對映中。
另外,它也包裝了一些資料夾,其中含有對模型提供者有用的檔案。
public class LibraryModelProvider extends ModelProvider {
public ResourceMapping[] getMappings(IResource resource,
ResourceMappingContext context, IProgressMonitor monitor) {
if (isModelFile(resource)) {
// Return a resource mapping on the file
return new LibraryResourceMapping(resource);
} if (containsModelFiles(resource)) {
// Create a deep resource mapping on the container
return new LibraryContainerResourceMapping(resource);
}
// The resource is not of interest to this model provider
return null;
}
}
之後,用戶端便可以存取模型提供者來判斷模型提供者是否在意即將處理的資源。 下一節說明將提供給團隊作業的 API,這些團隊作業利用模型提供者 API 來判斷在一組所選資源或模型元素上執行團隊作業時,所要處理的整組資源對映。
在資源上執行的作業,應該先進行驗證,以確保使用者會得知任何可能的負面影響。 以下是驗證資源變更所需要的步驟。
IResourceChangeDescriptionFactory
來建置變更的說明。
Factory 會產生一個 IResourceDelta
來鏡映作業執行之後,所產生的資源差異外觀。ResourceChangeValidator
來驗證變更。
驗證器會咨詢所有登錄為對受影響的資源有興趣的模型提供者。
結果是一或多個狀態,這些狀態含有起源模型的 ID 及作業對模型所可能造成之負面影響的說明。當團隊提供者嘗試無監視器型合併時,它會執行下列動作:
在「團隊作業」的環境定義中,模型元素的顯示是因「共用導覽器」架構而成為可能。
上述步驟可讓模型出現在團隊作業所用的對話框中。整合到合併預覽中,還需要一些其他步驟。
在檔案歷程和模型元素歷程的區域中,已進行了下列改進:
已提供下列項目來支援遠端瀏覽:
「團隊提供者」可以依照將提供物件轉換成適用於資源對映的相同方式,將它們的小型裝飾元轉換成適用於資源對映,以裝飾模型元素。 不過,邏輯模型元素裝飾有一個方面有問題。 如果模型元素與資源沒有 1:1 的對映,當基礎資源變更時,模型元素可能不會收到標籤更新。
為了處理這個問題,引進了 ITeamStateProvider
,使模型提供者能夠存取可能會影響到團隊裝飾的狀態變更。
另外,模型視圖也可以利用 SynchronizationStateTester
來判斷何時需要更新邏輯模型元素的標籤。
這個 API 依賴 ITeamStateProvider
介面來判斷資源團隊狀態的變更時間,它可以傳遞給團隊裝飾元,而成為 IDecorationContext
的一部分。