don't clobber workspace info cache when there are >1 TFS server
[tfs.git] / class / Microsoft.TeamFoundation.VersionControl.Client / VersionControlServer.cs
blob2469d12a1c647e7c915b16b7969ba0edd663d35b
1 //
2 // Microsoft.TeamFoundation.VersionControl.Client.VersionControlServer
3 //
4 // Authors:
5 // Joel Reed (joelwreed@gmail.com)
6 //
7 // Copyright (C) 2007 Joel Reed
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
16 //
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 //
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 using System;
30 using System.Collections;
31 using System.Collections.Generic;
32 using System.IO;
33 using System.Net;
34 using System.Xml;
35 using System.Web.Services;
36 using Microsoft.TeamFoundation.Client;
37 using Microsoft.TeamFoundation.VersionControl.Common;
39 namespace Microsoft.TeamFoundation.VersionControl.Client
41 public sealed class VersionControlServer
43 private Repository repository;
44 private string authenticatedUser;
45 private TeamFoundationServer teamFoundationServer;
46 internal Uri uri;
48 public event ExceptionEventHandler NonFatalError;
49 public event GettingEventHandler Getting;
50 public event ProcessingChangeEventHandler BeforeCheckinPendingChange;
51 public event PendingChangeEventHandler NewPendingChange;
52 public event ConflictEventHandler Conflict;
53 public event PendingChangeEventHandler UndonePendingChange;
55 //internal event FileTransferEventHandler Uploading;
57 public VersionControlServer(TeamFoundationServer teamFoundationServer)
59 ICredentials credentials = teamFoundationServer.Credentials;
60 this.teamFoundationServer = teamFoundationServer;
61 this.uri = teamFoundationServer.Uri;
62 this.repository = new Repository(this, uri, credentials);
64 if (credentials != null)
65 this.authenticatedUser = credentials.GetCredential(uri, "").UserName;
68 public LabelResult[] CreateLabel (VersionControlLabel label,
69 LabelItemSpec[] labelSpecs,
70 LabelChildOption childOption)
72 Workspace workspace = GetWorkspace(labelSpecs[0].ItemSpec.Item);
73 return repository.LabelItem(workspace, label, labelSpecs, childOption);
76 public LabelResult[] UnlabelItem (string labelName, string labelScope,
77 ItemSpec[] itemSpecs, VersionSpec version)
79 Workspace workspace = GetWorkspace(itemSpecs[0].Item);
80 return repository.UnlabelItem(workspace, labelName, labelScope,
81 itemSpecs, version);
84 public Workspace CreateWorkspace(string name, string owner)
86 return CreateWorkspace(name, owner, null, new WorkingFolder[0], Environment.MachineName);
89 public Workspace CreateWorkspace(string name, string owner, string comment,
90 WorkingFolder[] folders, string computer)
92 Workspace w1 = new Workspace(this, name, owner, comment, folders, computer);
93 Workspace w2 = repository.CreateWorkspace(w1);
94 Workstation.Current.AddCachedWorkspaceInfo(ServerGuid, Uri, w2);
95 return w2;
98 public void DeleteWorkspace(string workspaceName, string workspaceOwner)
100 repository.DeleteWorkspace(workspaceName, workspaceOwner);
101 Workstation.Current.RemoveCachedWorkspaceInfo(Uri, workspaceName);
104 public void DeleteShelveset(Shelveset shelveset)
106 DeleteShelveset(shelveset.Name, shelveset.OwnerName);
109 public void DeleteShelveset(string shelvesetName, string shelvesetOwner)
111 repository.DeleteShelveset(shelvesetName, shelvesetOwner);
114 public BranchHistoryTreeItem[][] GetBranchHistory(ItemSpec[] itemSpecs,
115 VersionSpec version)
117 if (itemSpecs.Length == 0) return null;
119 string workspaceName = String.Empty;
120 string workspaceOwner = String.Empty;
121 string item = itemSpecs[0].Item;
123 if (!VersionControlPath.IsServerItem(item))
125 WorkspaceInfo info = Workstation.Current.GetLocalWorkspaceInfo(item);
126 if (info != null)
128 workspaceName = info.Name;
129 workspaceOwner = info.OwnerName;
133 return repository.QueryBranches(workspaceName, workspaceOwner,
134 itemSpecs, version);
137 public Changeset GetChangeset (int changesetId)
139 return GetChangeset(changesetId, false, false);
142 public Changeset GetChangeset (int changesetId, bool includeChanges,
143 bool includeDownloadInfo)
145 return repository.QueryChangeset(changesetId, includeChanges, includeDownloadInfo);
148 public Item GetItem(int id, int changeSet)
150 return GetItem(id, changeSet, false);
153 public Item GetItem(int id, int changeSet, bool includeDownloadInfo)
155 int[] ids = new int[1];
156 ids[0] = id;
158 Item[] items = GetItems(ids, changeSet, includeDownloadInfo);
159 if (items.Length > 0) return items[0];
160 return null;
163 public Item[] GetItems(int[] ids, int changeSet)
165 return GetItems(ids, changeSet, false);
168 public Item GetItem(string path)
170 return GetItem(path, VersionSpec.Latest);
173 public Item GetItem(string path, VersionSpec versionSpec)
175 return GetItem(path, versionSpec, 0, false);
178 public Item GetItem(string path, VersionSpec versionSpec,
179 int deletionId, bool includeDownloadInfo)
181 ItemSpec itemSpec = new ItemSpec(path, RecursionType.None);
182 ItemSet itemSet = GetItems(itemSpec, versionSpec, DeletedState.NonDeleted,
183 ItemType.Any, includeDownloadInfo);
185 Item[] items = itemSet.Items;
186 if (items.Length > 0) return items[0];
187 return null;
190 public Item[] GetItems(int[] ids, int changeSet, bool includeDownloadInfo)
192 return repository.QueryItemsById(ids, changeSet, includeDownloadInfo);
195 public ItemSet GetItems(string path, RecursionType recursionType)
197 ItemSpec itemSpec = new ItemSpec(path, recursionType);
198 return GetItems(itemSpec, VersionSpec.Latest, DeletedState.NonDeleted,
199 ItemType.Any, false);
202 public ItemSet GetItems(string path, VersionSpec versionSpec,
203 RecursionType recursionType)
205 ItemSpec itemSpec = new ItemSpec(path, recursionType);
206 return GetItems(itemSpec, versionSpec, DeletedState.NonDeleted,
207 ItemType.Any, false);
210 public ItemSet GetItems(ItemSpec itemSpec, VersionSpec versionSpec,
211 DeletedState deletedState, ItemType itemType,
212 bool includeDownloadInfo)
214 List<ItemSpec> itemSpecs = new List<ItemSpec>();
215 itemSpecs.Add(itemSpec);
216 ItemSet[] itemSet = GetItems(itemSpecs.ToArray(), versionSpec, deletedState,
217 itemType, includeDownloadInfo);
218 return itemSet[0];
221 public ItemSet[] GetItems(ItemSpec[] itemSpecs, VersionSpec versionSpec,
222 DeletedState deletedState, ItemType itemType,
223 bool includeDownloadInfo)
225 if (itemSpecs.Length == 0) return null;
227 string workspaceName = String.Empty;
228 string workspaceOwner = String.Empty;
230 string item = itemSpecs[0].Item;
231 if (!VersionControlPath.IsServerItem(item))
233 WorkspaceInfo info = Workstation.Current.GetLocalWorkspaceInfo(item);
234 if (info != null)
236 workspaceName = info.Name;
237 workspaceOwner = info.OwnerName;
241 return repository.QueryItems(workspaceName, workspaceOwner,
242 itemSpecs, versionSpec, deletedState,
243 itemType, includeDownloadInfo);
246 public ExtendedItem[] GetExtendedItems(string path,
247 DeletedState deletedState,
248 ItemType itemType)
250 List<ItemSpec> itemSpecs = new List<ItemSpec>();
251 itemSpecs.Add(new ItemSpec(path, RecursionType.OneLevel));
252 ExtendedItem[][] items = GetExtendedItems(itemSpecs.ToArray(), deletedState, itemType);
254 if (items.Length == 0) return null;
255 return items[0];
258 public ExtendedItem[][] GetExtendedItems (ItemSpec[] itemSpecs,
259 DeletedState deletedState,
260 ItemType itemType)
262 return Repository.QueryItemsExtended(null, null,
263 itemSpecs, deletedState, itemType);
266 public int GetLatestChangesetId()
268 RepositoryProperties properties = Repository.GetRepositoryProperties();
269 return properties.LatestChangesetId;
272 public Workspace GetWorkspace(string localPath)
274 string path = Path.GetFullPath(localPath);
276 WorkspaceInfo info = Workstation.Current.GetLocalWorkspaceInfo(path);
277 if (info == null) throw new ItemNotMappedException(path);
279 return new Workspace(this, info.Name, info.OwnerName,
280 info.Comment, new WorkingFolder[0], Workstation.Current.Name);
283 public Workspace GetWorkspace(string workspaceName, string workspaceOwner)
285 return repository.QueryWorkspace(workspaceName, workspaceOwner);
288 public IEnumerable QueryHistory (string path, VersionSpec version,
289 int deletionId, RecursionType recursion,
290 string user, VersionSpec versionFrom,
291 VersionSpec versionTo, int maxCount,
292 bool includeChanges, bool slotMode)
294 return QueryHistory(path, version, deletionId, recursion,
295 user, versionFrom, versionTo, maxCount,
296 includeChanges, slotMode, false);
299 public IEnumerable QueryHistory (string path, VersionSpec version,
300 int deletionId, RecursionType recursion,
301 string user, VersionSpec versionFrom,
302 VersionSpec versionToOrig, int maxCount,
303 bool includeChanges, bool slotMode,
304 bool includeDownloadInfo)
306 ItemSpec itemSpec = new ItemSpec(path, recursion, deletionId);
308 string workspaceName = String.Empty;
309 string workspaceOwner = String.Empty;
311 if (!VersionControlPath.IsServerItem(itemSpec.Item))
313 WorkspaceInfo info = Workstation.Current.GetLocalWorkspaceInfo(itemSpec.Item);
314 if (info != null)
316 workspaceName = info.Name;
317 workspaceOwner = info.OwnerName;
321 List<Changeset> changes = new List<Changeset>();
322 int total = maxCount;
323 VersionSpec versionTo = versionToOrig;
325 while (total > 0)
327 int batchMax = Math.Min(256, total);
328 int batchCnt = repository.QueryHistory(workspaceName, workspaceOwner, itemSpec,
329 version, user, versionFrom, versionTo,
330 batchMax, includeChanges, slotMode,
331 includeDownloadInfo, ref changes);
333 if (batchCnt < batchMax) break;
335 total -= batchCnt;
336 Changeset lastChangeset = changes[changes.Count - 1];
337 versionTo = new ChangesetVersionSpec(lastChangeset.ChangesetId);
340 return changes.ToArray();
343 public ChangesetMerge[] QueryMerges (string sourcePath, VersionSpec sourceVersion,
344 string targetPath, VersionSpec targetVersion,
345 VersionSpec versionFrom, VersionSpec versionTo,
346 RecursionType recursion)
348 string workspaceName = String.Empty;
349 string workspaceOwner = String.Empty;
351 if (!VersionControlPath.IsServerItem(targetPath))
353 WorkspaceInfo info = Workstation.Current.GetLocalWorkspaceInfo(targetPath);
354 if (info != null)
356 workspaceName = info.Name;
357 workspaceOwner = info.OwnerName;
361 ItemSpec sourceItem = null;
362 if (!String.IsNullOrEmpty(sourcePath)) sourceItem = new ItemSpec(sourcePath, recursion);
364 ItemSpec targetItem = new ItemSpec(targetPath, recursion);
365 ChangesetMerge[] merges = repository.QueryMerges(workspaceName, workspaceOwner,
366 sourceItem, sourceVersion,
367 targetItem, targetVersion,
368 versionFrom, versionTo,
369 Int32.MaxValue);
370 return merges;
373 public Workspace GetWorkspace(WorkspaceInfo workspaceInfo)
375 if (workspaceInfo == null)
376 throw new ArgumentNullException("workspaceInfo");
378 return new Workspace(this, workspaceInfo);
381 public VersionControlLabel[] QueryLabels(string labelName, string labelScope,
382 string owner, bool includeItems)
384 return repository.QueryLabels(null, null, labelName, labelScope, owner, null,
385 VersionSpec.Latest, includeItems, false);
388 public VersionControlLabel[] QueryLabels(string labelName, string labelScope,
389 string owner, bool includeItems,
390 string filterItem, VersionSpec versionFilterItem)
392 return repository.QueryLabels(null, null, labelName, labelScope, owner, filterItem,
393 versionFilterItem, includeItems, false);
396 public VersionControlLabel[] QueryLabels(string labelName, string labelScope,
397 string owner, bool includeItems,
398 string filterItem, VersionSpec versionFilterItem,
399 bool generateDownloadUrls)
401 return repository.QueryLabels(null, null, labelName, labelScope, owner, filterItem,
402 versionFilterItem, includeItems, generateDownloadUrls);
405 public ItemSecurity[] GetPermissions(string[] items, RecursionType recursion)
407 return GetPermissions(null, items, recursion);
410 public ItemSecurity[] GetPermissions(string[] identityNames, string[] items,
411 RecursionType recursion)
413 return Repository.QueryItemPermissions(identityNames, items, recursion);
416 public Shelveset[] QueryShelvesets (string shelvesetName, string shelvesetOwner)
418 return repository.QueryShelvesets(shelvesetName, shelvesetOwner);
421 public Workspace[] QueryWorkspaces(string workspaceName, string ownerName,
422 string computer)
424 return repository.QueryWorkspaces(workspaceName, ownerName, computer);
427 internal void OnDownloading(GettingEventArgs args)
429 if (null != Getting) Getting(this, args);
432 internal void OnNonFatalError(Workspace workspace, Failure failure)
434 if (null != NonFatalError) NonFatalError(workspace, new ExceptionEventArgs(workspace, failure));
437 internal void OnUndonePendingChange(Workspace workspace, PendingChange change)
439 if (null != UndonePendingChange) UndonePendingChange(workspace, new PendingChangeEventArgs(workspace, change));
442 internal void OnUploading()
444 //if (null != Uploading) Uploading(null, null);
447 public string AuthenticatedUser
449 get { return authenticatedUser; }
452 public Guid ServerGuid
454 get { return new Guid(); }
457 public TeamFoundationServer TeamFoundationServer
459 get { return teamFoundationServer; }
462 internal Repository Repository
464 get { return repository; }
467 internal Uri Uri
469 get { return uri; }