BUGFIX: on windows, must do case insensitive path comparisons
[tfs.git] / class / Microsoft.TeamFoundation.VersionControl.Client / Repository.cs
blob6411a68782a34e02e9968120694bbf63c6f0a2f0
1 //
2 // Microsoft.TeamFoundation.VersionControl.Client.Repository
3 //
4 // Authors:
5 // Joel Reed (joelwreed@gmail.com)
6 //
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.IO;
31 using System.Collections.Generic;
32 using System.Net;
33 using System.Reflection;
34 using System.Text;
35 using System.Xml;
36 using System.Xml.Schema;
37 using System.Web.Services;
38 using System.Web.Services.Description;
39 using System.Web.Services.Discovery;
40 using System.Web.Services.Protocols;
41 using Microsoft.TeamFoundation.VersionControl.Common;
43 namespace Microsoft.TeamFoundation.VersionControl.Client
45 [System.Web.Services.WebServiceBinding(Name="RepositorySoap", Namespace="http://schemas.microsoft.com/TeamFoundation/2005/06/VersionControl/ClientServices/03")]
46 [System.Diagnostics.DebuggerStepThroughAttribute()]
47 [System.ComponentModel.DesignerCategoryAttribute("code")]
48 [System.Xml.Serialization.XmlIncludeAttribute(typeof(SecurityChange))]
49 internal class Repository : System.Web.Services.Protocols.SoapHttpClientProtocol {
51 private VersionControlServer versionControlServer;
52 private string itemUrl;
53 private string uploadUrl;
55 public Repository(VersionControlServer versionControlServer,
56 Uri url, ICredentials credentials)
58 this.versionControlServer = versionControlServer;
59 this.Url = String.Format("{0}/{1}", url, "VersionControl/v1.0/Repository.asmx");
60 this.itemUrl = String.Format("{0}/{1}", url, RepositoryConstants.DownloadUrlSuffix);
61 this.uploadUrl = String.Format("{0}/{1}", url, RepositoryConstants.UploadUrlSuffix);
62 this.Credentials = credentials;
65 public void UploadFile(string workspaceName, string ownerName, PendingChange change)
67 FileInfo fi = new FileInfo(change.LocalItem);
68 long len = fi.Length;
70 UploadFile upload = new UploadFile(uploadUrl, Credentials);
71 upload.AddValue(RepositoryConstants.ServerItemField, change.ServerItem);
72 upload.AddValue(RepositoryConstants.WorkspaceNameField, workspaceName);
73 upload.AddValue(RepositoryConstants.WorkspaceOwnerField, ownerName);
74 upload.AddValue(RepositoryConstants.LengthField, len.ToString());
75 upload.AddValue(RepositoryConstants.HashField, Convert.ToBase64String(change.UploadHashValue));
77 // send byte range
78 // TODO: handle files to large to fit in a single POST
79 upload.AddValue(RepositoryConstants.RangeField,
80 String.Format("bytes=0-{0}/{1}", len-1, len));
82 upload.AddFile(change.LocalItem);
84 WebResponse response;
86 try
88 response = upload.Send();
90 catch (WebException ex)
92 response = ex.Response;
93 HttpWebResponse http_response = response as HttpWebResponse;
94 if (http_response == null || http_response.StatusCode != HttpStatusCode.InternalServerError)
95 throw ex;
98 // Get the stream associated with the response.
99 //Stream receiveStream = response.GetResponseStream ();
100 //StreamReader readStream = new StreamReader(receiveStream, Encoding.UTF8);
101 //Console.WriteLine (readStream.ReadToEnd ());
103 response.Close();
104 //readStream.Close();
107 protected HttpWebResponse Invoke (Message message)
109 message.End();
110 HttpWebResponse response = GetWebResponse(message.Request) as HttpWebResponse;
112 if (response == null)
114 throw new TeamFoundationServerException("No response from server");
117 if (response.StatusCode == HttpStatusCode.Unauthorized)
119 string msg = String.Format("TF30063: You are not authorized to access {0} ({1}).\n--> Did you supply the correct username, password, and domain?",
120 (new Uri(this.Url)).Host, message.MethodName);
122 //StreamReader readStream = new StreamReader(response.GetResponseStream(), Encoding.UTF8);
123 // Console.Error.WriteLine (readStream.ReadToEnd ());
124 //readStream.Close();
126 throw new TeamFoundationServerException(msg);
129 if (response.StatusCode == HttpStatusCode.InternalServerError)
131 throw new VersionControlException(GetExceptionMessage(response));
134 return response;
137 public string GetExceptionMessage(HttpWebResponse response)
139 StreamReader sr = new StreamReader(response.GetResponseStream(), new UTF8Encoding (false), false);
140 XmlReader reader = new XmlTextReader(sr);
141 string msg = String.Empty;
142 while (reader.Read())
144 if (reader.NodeType == XmlNodeType.Element && reader.Name == "faultstring")
146 msg = reader.ReadElementContentAsString();
147 break;
151 response.Close();
152 return msg;
155 public int CheckIn(Workspace workspace, string[] serverItems, string comment)
157 Message msg = new Message(GetWebRequest (new Uri(Url)), "CheckIn");
159 msg.Body.WriteElementString("workspaceName", workspace.Name);
160 msg.Body.WriteElementString("ownerName", workspace.OwnerName);
162 msg.Body.WriteStartElement("serverItems");
163 foreach (string serverItem in serverItems)
165 msg.Body.WriteElementString("string", serverItem);
167 msg.Body.WriteEndElement();
169 // write info subtree
170 msg.Body.WriteStartElement("info");
171 msg.Body.WriteAttributeString("date", DateTime.Now.ToString("s"));
172 msg.Body.WriteAttributeString("cset", "0");
173 msg.Body.WriteAttributeString("owner", workspace.OwnerName);
174 msg.Body.WriteElementString("Comment", comment);
175 msg.Body.WriteElementString("CheckinNote", "");
176 msg.Body.WriteElementString("PolicyOverride", "");
177 msg.Body.WriteElementString("CheckinOptions", "ValidateCheckinOwner");
178 msg.Body.WriteEndElement();
180 int cset = 0;
181 using (HttpWebResponse response = Invoke(msg))
183 XmlReader results = msg.ResponseReader(response);
184 cset = Convert.ToInt32(results.GetAttribute("cset"));
186 List<Failure> failures = new List<Failure>();
188 //TODO: read <UndoneServerItems /> and <ImplicitItems />
189 //<CheckInResponse xmlns="http://schemas.microsoft.com/TeamFoundation/2005/06/VersionControl/ClientServices/03"><CheckInResult cset="11486"><UndoneServerItems /><ImplicitItems /></CheckInResult><failures /></CheckInResponse>
190 while (results.Read())
192 if (results.NodeType == XmlNodeType.Element)
194 switch (results.Name)
196 case "Failure":
197 failures.Add(Failure.FromXml(this, results));
198 break;
203 foreach (Failure failure in failures)
205 versionControlServer.OnNonFatalError(workspace, failure);
209 return cset;
212 public void CreateTeamProjectFolder(TeamProjectFolderOptions teamProjectOptions)
214 Message msg = new Message(GetWebRequest (new Uri(Url)), "CreateTeamProjectFolder");
215 teamProjectOptions.ToXml(msg.Body, "");
216 HttpWebResponse response = Invoke(msg);
217 response.Close();
220 public Workspace CreateWorkspace(Workspace workspace)
222 Message msg = new Message(GetWebRequest (new Uri(Url)), "CreateWorkspace");
223 workspace.ToXml(msg.Body, "workspace");
225 Workspace newWorkspace;
226 using (HttpWebResponse response = Invoke(msg))
228 XmlReader results = msg.ResponseReader(response);
229 newWorkspace = Workspace.FromXml(this, results);
232 return newWorkspace;
235 [System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://schemas.microsoft.com/TeamFoundation/2005/06/VersionControl/ClientServices/03/DeleteWorkspace", RequestNamespace="http://schemas.microsoft.com/TeamFoundation/2005/06/VersionControl/ClientServices/03", ResponseNamespace="http://schemas.microsoft.com/TeamFoundation/2005/06/VersionControl/ClientServices/03", ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped, Use=System.Web.Services.Description.SoapBindingUse.Literal)]
236 public void DeleteWorkspace(string workspaceName, string ownerName)
238 this.Invoke("DeleteWorkspace", new object[] { workspaceName, ownerName});
241 public LabelResult[] LabelItem(Workspace workspace, VersionControlLabel label,
242 LabelItemSpec[] labelSpecs, LabelChildOption children)
244 Message msg = new Message(GetWebRequest (new Uri(Url)), "LabelItem");
246 msg.Body.WriteElementString("workspaceName", workspace.Name);
247 msg.Body.WriteElementString("workspaceOwner", workspace.OwnerName);
248 label.ToXml(msg.Body, "label");
250 msg.Body.WriteStartElement("labelSpecs");
251 foreach (LabelItemSpec labelSpec in labelSpecs)
253 labelSpec.ToXml(msg.Body, "LabelItemSpec");
255 msg.Body.WriteEndElement();
257 msg.Body.WriteElementString("children", children.ToString());
259 List<LabelResult> labelResults = new List<LabelResult>();
260 List<Failure> faillist = new List<Failure>();
262 using (HttpWebResponse response = Invoke(msg))
264 XmlReader results = msg.ResponseReader(response);
266 while (results.Read())
268 if (results.NodeType == XmlNodeType.Element)
270 switch (results.Name)
272 case "LabelResult":
273 labelResults.Add(LabelResult.FromXml(this, results));
274 break;
275 case "Failure":
276 faillist.Add(Failure.FromXml(this, results));
277 break;
283 foreach (Failure failure in faillist)
285 versionControlServer.OnNonFatalError(workspace, failure);
288 return labelResults.ToArray();
291 public LabelResult[] UnlabelItem(Workspace workspace, string labelName,
292 string labelScope, ItemSpec[] itemSpecs,
293 VersionSpec version)
295 Message msg = new Message(GetWebRequest (new Uri(Url)), "UnlabelItem");
297 msg.Body.WriteElementString("workspaceName", workspace.Name);
298 msg.Body.WriteElementString("workspaceOwner", workspace.OwnerName);
299 msg.Body.WriteElementString("labelName", labelName);
301 if (!String.IsNullOrEmpty(labelScope))
302 msg.Body.WriteElementString("labelScope", labelScope);
304 msg.Body.WriteStartElement("items");
305 foreach (ItemSpec itemSpec in itemSpecs)
307 itemSpec.ToXml(msg.Body, "ItemSpec");
309 msg.Body.WriteEndElement();
311 version.ToXml(msg.Body, "version");
313 List<LabelResult> labelResults = new List<LabelResult>();
314 List<Failure> faillist = new List<Failure>();
316 using (HttpWebResponse response = Invoke(msg))
318 XmlReader results = msg.ResponseReader(response);
320 while (results.Read())
322 if (results.NodeType == XmlNodeType.Element)
324 switch (results.Name)
326 case "LabelResult":
327 labelResults.Add(LabelResult.FromXml(this, results));
328 break;
329 case "Failure":
330 faillist.Add(Failure.FromXml(this, results));
331 break;
337 foreach (Failure failure in faillist)
339 versionControlServer.OnNonFatalError(workspace, failure);
342 return labelResults.ToArray();
345 public GetOperation[] Get(string workspaceName, string ownerName,
346 GetRequest[] requests, bool force, bool noGet) {
348 Message msg = new Message(GetWebRequest (new Uri(Url)), "Get");
349 msg.Body.WriteElementString("workspaceName", workspaceName);
350 msg.Body.WriteElementString("ownerName", ownerName);
352 msg.Body.WriteStartElement("requests");
353 foreach (GetRequest request in requests)
355 request.ToXml(msg.Body, "");
357 msg.Body.WriteEndElement();
359 msg.Body.WriteElementString("force", force.ToString().ToLower());
360 msg.Body.WriteElementString("noGet", noGet.ToString().ToLower());
362 List<GetOperation> operations = new List<GetOperation>();
363 using (HttpWebResponse response = Invoke(msg))
365 XmlReader results = msg.ResponseReader(response);
367 while (results.Read())
369 if (results.NodeType == XmlNodeType.Element &&
370 results.Name == "GetOperation")
371 operations.Add(GetOperation.FromXml(ItemUrl, results));
375 return operations.ToArray();
378 public RepositoryProperties GetRepositoryProperties()
380 Message msg = new Message(GetWebRequest (new Uri(Url)), "GetRepositoryProperties");
381 RepositoryProperties properties;
382 using (HttpWebResponse response = Invoke(msg))
384 XmlReader results = msg.ResponseReader(response);
385 properties = RepositoryProperties.FromXml(this, results);
388 return properties;
391 public GetOperation[] PendChanges(Workspace workspace, ChangeRequest[] changes)
393 Message msg = new Message(GetWebRequest (new Uri(Url)), "PendChanges");
395 msg.Body.WriteElementString("workspaceName", workspace.Name);
396 msg.Body.WriteElementString("ownerName", workspace.OwnerName);
397 msg.Body.WriteStartElement("changes");
398 foreach (ChangeRequest change in changes)
400 change.ToXml(msg.Body, "");
402 msg.Body.WriteEndElement();
404 List<GetOperation> operations = new List<GetOperation>();
405 List<Failure> faillist = new List<Failure>();
407 using (HttpWebResponse response = Invoke(msg))
409 XmlReader results = msg.ResponseReader(response);
411 while (results.Read())
413 if (results.NodeType == XmlNodeType.Element)
415 switch (results.Name)
417 case "GetOperation":
418 operations.Add(GetOperation.FromXml(ItemUrl, results));
419 break;
420 case "Failure":
421 faillist.Add(Failure.FromXml(this, results));
422 break;
428 foreach (Failure failure in faillist)
430 versionControlServer.OnNonFatalError(workspace, failure);
433 return operations.ToArray();
436 public Annotation[] QueryAnnotation(string annotationName, string annotatedItem, int version)
438 Message msg = new Message(GetWebRequest (new Uri(Url)), "QueryAnnotation");
440 msg.Body.WriteElementString("annotationName", annotationName);
441 msg.Body.WriteElementString("annotatedItem", annotatedItem);
442 msg.Body.WriteElementString("version", Convert.ToString(version));
444 List<Annotation> labels = new List<Annotation>();
445 using (HttpWebResponse response = Invoke(msg))
447 XmlReader results = msg.ResponseReader(response);
449 while (results.Read())
451 if (results.NodeType == XmlNodeType.Element &&
452 results.Name == "Annotation")
453 labels.Add(Annotation.FromXml(this, results));
457 return labels.ToArray();
460 public BranchHistoryTreeItem[][] QueryBranches(string workspaceName, string workspaceOwner,
461 ItemSpec[] itemSpecs, VersionSpec versionSpec)
463 Message msg = new Message(GetWebRequest (new Uri(Url)), "QueryBranches");
465 if (!String.IsNullOrEmpty(workspaceName)) msg.Body.WriteElementString("workspaceName", workspaceName);
466 if (!String.IsNullOrEmpty(workspaceOwner)) msg.Body.WriteElementString("workspaceOwner", workspaceOwner);
467 msg.Body.WriteStartElement("items");
468 foreach (ItemSpec itemSpec in itemSpecs)
469 itemSpec.ToXml(msg.Body, "ItemSpec");
470 msg.Body.WriteEndElement();
472 versionSpec.ToXml(msg.Body, "version");
474 List<BranchHistoryTreeItem[]> tree = new List<BranchHistoryTreeItem[]>();
475 using (HttpWebResponse response = Invoke(msg))
477 XmlReader results = msg.ResponseReader(response);
478 while (results.Read())
480 if (results.NodeType == XmlNodeType.Element &&
481 results.Name == "ArrayOfBranchRelative")
483 List<BranchRelative> branches = new List<BranchRelative>();
484 while (results.Read())
486 if (results.NodeType == XmlNodeType.EndElement &&
487 results.Name == "ArrayOfBranchRelative") break;
488 if (results.NodeType == XmlNodeType.Element &&
489 results.Name == "BranchRelative")
490 branches.Add(BranchRelative.FromXml(this, results));
493 if (branches.Count > 0)
495 List<BranchHistoryTreeItem> items = new List<BranchHistoryTreeItem>();
496 items.Add(new BranchHistoryTreeItem(branches.ToArray()));
497 tree.Add(items.ToArray());
503 return tree.ToArray();
506 public Changeset QueryChangeset(int changesetId, bool includeChanges,
507 bool generateDownloadUrls)
509 Message msg = new Message(GetWebRequest (new Uri(Url)), "QueryChangeset");
511 msg.Body.WriteElementString("changesetId", Convert.ToString(changesetId));
512 msg.Body.WriteElementString("includeChanges", Convert.ToString(includeChanges).ToLower());
513 msg.Body.WriteElementString("generateDownloadUrls", Convert.ToString(generateDownloadUrls).ToLower());
515 Changeset changeset = null;
517 using (HttpWebResponse response = Invoke(msg))
519 XmlReader results = msg.ResponseReader(response);
520 changeset = Changeset.FromXml(this, results);
523 return changeset;
526 public Changeset[] QueryHistory (string workspaceName, string workspaceOwner,
527 ItemSpec itemSpec, VersionSpec version,
528 string user, VersionSpec versionFrom,
529 VersionSpec versionTo, int maxCount,
530 bool includeFiles, bool slotMode,
531 bool generateDownloadUrls)
533 Message msg = new Message(GetWebRequest (new Uri(Url)), "QueryHistory");
535 if (!String.IsNullOrEmpty(workspaceName)) msg.Body.WriteElementString("workspaceName", workspaceName);
536 if (!String.IsNullOrEmpty(workspaceOwner)) msg.Body.WriteElementString("workspaceOwner", workspaceOwner);
538 itemSpec.ToXml(msg.Body, "itemSpec");
539 if (version != null) version.ToXml(msg.Body, "versionItem");
540 if (versionFrom != null) versionFrom.ToXml(msg.Body, "versionFrom");
541 if (versionTo != null) versionTo.ToXml(msg.Body, "versionTo");
543 if (!String.IsNullOrEmpty(user)) msg.Body.WriteElementString("user", user);
544 msg.Body.WriteElementString("maxCount", Convert.ToString(maxCount));
545 msg.Body.WriteElementString("includeFiles", Convert.ToString(includeFiles).ToLower());
546 msg.Body.WriteElementString("generateDownloadUrls", Convert.ToString(generateDownloadUrls).ToLower());
547 msg.Body.WriteElementString("slotMode", Convert.ToString(slotMode).ToLower());
549 List<Changeset> changes = new List<Changeset>();
550 using (HttpWebResponse response = Invoke(msg))
552 XmlReader results = msg.ResponseReader(response);
554 while (results.Read())
556 if (results.NodeType == XmlNodeType.Element &&
557 results.Name == "Changeset")
558 changes.Add(Changeset.FromXml(this, results));
562 return changes.ToArray();
565 public ItemSet[] QueryItems(string workspaceName, string workspaceOwner,
566 ItemSpec[] itemSpecs, VersionSpec versionSpec,
567 DeletedState deletedState, ItemType itemType,
568 bool generateDownloadUrls)
570 Message msg = new Message(GetWebRequest (new Uri(Url)), "QueryItems");
572 if (!String.IsNullOrEmpty(workspaceName)) msg.Body.WriteElementString("workspaceName", workspaceName);
573 if (!String.IsNullOrEmpty(workspaceOwner)) msg.Body.WriteElementString("workspaceOwner", workspaceOwner);
574 msg.Body.WriteStartElement("items");
575 foreach (ItemSpec itemSpec in itemSpecs)
576 itemSpec.ToXml(msg.Body, "ItemSpec");
577 msg.Body.WriteEndElement();
579 versionSpec.ToXml(msg.Body, "version");
581 msg.Body.WriteElementString("deletedState",
582 deletedState.ToString());
583 msg.Body.WriteElementString("itemType",
584 itemType.ToString());
585 msg.Body.WriteElementString("generateDownloadUrls",
586 generateDownloadUrls.ToString().ToLower());
588 List<ItemSet> itemSet = new List<ItemSet>();
589 using (HttpWebResponse response = Invoke(msg))
591 XmlReader results = msg.ResponseReader(response);
593 while (results.Read())
595 if (results.NodeType == XmlNodeType.Element &&
596 results.Name == "ItemSet")
597 itemSet.Add(ItemSet.FromXml(this, results));
601 return itemSet.ToArray();
604 public ExtendedItem[][] QueryItemsExtended(string workspaceName, string workspaceOwner,
605 ItemSpec[] itemSpecs,
606 DeletedState deletedState, ItemType itemType)
608 Message msg = new Message(GetWebRequest (new Uri(Url)), "QueryItemsExtended");
610 if (!String.IsNullOrEmpty(workspaceName)) msg.Body.WriteElementString("workspaceName", workspaceName);
611 if (!String.IsNullOrEmpty(workspaceOwner)) msg.Body.WriteElementString("workspaceOwner", workspaceOwner);
613 msg.Body.WriteStartElement("items");
614 foreach (ItemSpec itemSpec in itemSpecs)
616 itemSpec.ToXml(msg.Body, "ItemSpec");
618 msg.Body.WriteEndElement();
620 msg.Body.WriteElementString("deletedState",
621 deletedState.ToString());
622 msg.Body.WriteElementString("itemType",
623 itemType.ToString());
625 List< ExtendedItem[] > listOfItemArrays = new List<ExtendedItem[] >();
626 using (HttpWebResponse response = Invoke(msg))
628 XmlReader results = msg.ResponseReader(response);
629 while (results.Read())
631 if (results.NodeType == XmlNodeType.Element &&
632 results.Name == "ArrayOfExtendedItem")
634 List<ExtendedItem> items = new List<ExtendedItem>();
635 while (results.Read())
637 //Console.WriteLine(" " + results.Name + ":" + results.NodeType);
638 if (results.NodeType == XmlNodeType.EndElement &&
639 results.Name == "ArrayOfExtendedItem") break;
640 if (results.NodeType == XmlNodeType.Element &&
641 results.Name == "ExtendedItem")
642 items.Add(ExtendedItem.FromXml(this, results));
644 listOfItemArrays.Add(items.ToArray());
649 return listOfItemArrays.ToArray();
652 public VersionControlLabel[] QueryLabels(string workspaceName, string workspaceOwner,
653 string labelName, string labelScope,
654 string owner, string filterItem,
655 VersionSpec versionFilterItem,
656 bool includeItems, bool generateDownloadUrls)
658 Message msg = new Message(GetWebRequest (new Uri(Url)), "QueryLabels");
660 if (!String.IsNullOrEmpty(workspaceName)) msg.Body.WriteElementString("workspaceName", workspaceName);
661 if (!String.IsNullOrEmpty(workspaceOwner)) msg.Body.WriteElementString("workspaceOwner", workspaceOwner);
662 if (!String.IsNullOrEmpty(labelName)) msg.Body.WriteElementString("labelName", labelName);
663 if (!String.IsNullOrEmpty(labelScope)) msg.Body.WriteElementString("labelScope", labelScope);
664 if (!String.IsNullOrEmpty(owner)) msg.Body.WriteElementString("owner", owner);
665 if (!String.IsNullOrEmpty(filterItem)) msg.Body.WriteElementString("filterItem", filterItem);
667 if (null != versionFilterItem) versionFilterItem.ToXml(msg.Body, "versionFilterItem");
668 msg.Body.WriteElementString("includeItems", includeItems.ToString().ToLower());
669 msg.Body.WriteElementString("generateDownloadUrls", generateDownloadUrls.ToString().ToLower());
671 List<VersionControlLabel> labels = new List<VersionControlLabel>();
672 using (HttpWebResponse response = Invoke(msg))
674 XmlReader results = msg.ResponseReader(response);
676 while (results.Read())
678 if (results.NodeType == XmlNodeType.Element &&
679 results.Name == "VersionControlLabel")
680 labels.Add(VersionControlLabel.FromXml(this, results));
684 return labels.ToArray();
687 public Item[] QueryItemsById(int[] ids, int changeSet,
688 bool generateDownloadUrls)
690 Message msg = new Message(GetWebRequest (new Uri(Url)), "QueryItemsById");
692 msg.Body.WriteStartElement("itemIds");
693 foreach (int id in ids)
695 msg.Body.WriteElementString("int", Convert.ToString(id));
697 msg.Body.WriteEndElement();
699 msg.Body.WriteElementString("changeSet", Convert.ToString(changeSet));
700 msg.Body.WriteElementString("generateDownloadUrls",
701 generateDownloadUrls.ToString().ToLower());
703 List<Item> items = new List<Item>();
704 using (HttpWebResponse response = Invoke(msg))
706 XmlReader results = msg.ResponseReader(response);
708 while (results.Read())
710 if (results.NodeType == XmlNodeType.Element &&
711 results.Name == "Item")
712 items.Add(Item.FromXml(this, results));
716 return items.ToArray();
719 public ItemSecurity[] QueryItemPermissions(string[] identityNames, string[] items,
720 RecursionType recursion)
722 Message msg = new Message(GetWebRequest (new Uri(Url)), "QueryItemPermissions");
724 msg.Body.WriteStartElement("itemSpecs");
725 foreach (string item in items)
727 ItemSpec spec = new ItemSpec(item, recursion);
728 spec.ToXml(msg.Body, "ItemSpec");
730 msg.Body.WriteEndElement();
732 List<ItemSecurity> itemSecurities = new List<ItemSecurity>();
733 using (HttpWebResponse response = Invoke(msg))
735 XmlReader results = msg.ResponseReader(response);
737 while (results.Read())
739 if (results.NodeType == XmlNodeType.Element &&
740 results.Name == "ItemSecurity")
741 itemSecurities.Add(ItemSecurity.FromXml(this, results));
745 return itemSecurities.ToArray();
748 public PendingChange[] QueryPendingSets(string localWorkspaceName, string localWorkspaceOwner,
749 string queryWorkspaceName, string ownerName,
750 ItemSpec[] itemSpecs, bool generateDownloadUrls,
751 out Failure[] failures)
753 Message msg = new Message(GetWebRequest (new Uri(Url)), "QueryPendingSets");
754 msg.Body.WriteElementString("localWorkspaceName", localWorkspaceName);
755 msg.Body.WriteElementString("localWorkspaceOwner", localWorkspaceOwner);
756 msg.Body.WriteElementString("queryWorkspaceName", queryWorkspaceName);
757 msg.Body.WriteElementString("ownerName", ownerName);
759 msg.Body.WriteStartElement("itemSpecs");
760 foreach (ItemSpec item in itemSpecs)
762 item.ToXml(msg.Body, "ItemSpec");
764 msg.Body.WriteEndElement();
766 msg.Body.WriteElementString("generateDownloadUrls",
767 generateDownloadUrls.ToString().ToLower());
769 List<PendingChange> changes = new List<PendingChange>();
770 List<Failure> faillist = new List<Failure>();
772 using (HttpWebResponse response = Invoke(msg))
774 XmlReader results = msg.ResponseReader(response);
776 while (results.Read())
778 if (results.NodeType == XmlNodeType.Element)
780 switch (results.Name)
782 case "PendingChange":
783 changes.Add(PendingChange.FromXml(this, results));
784 break;
785 case "Failure":
786 faillist.Add(Failure.FromXml(this, results));
787 break;
793 failures = faillist.ToArray();
794 return changes.ToArray();
797 public Shelveset[] QueryShelvesets (string shelvesetName, string shelvesetOwner)
799 Message msg = new Message(GetWebRequest (new Uri(Url)), "QueryShelvesets");
800 msg.Body.WriteElementString("shelvesetName", shelvesetName);
801 msg.Body.WriteElementString("shelvesetOwner", shelvesetOwner);
803 List<Shelveset> shelvesets = new List<Shelveset>();
804 using (HttpWebResponse response = Invoke(msg))
806 XmlReader results = msg.ResponseReader(response);
808 while (results.Read())
810 if (results.NodeType == XmlNodeType.Element &&
811 results.Name == "Shelveset")
812 shelvesets.Add(Shelveset.FromXml(this, results));
816 shelvesets.Sort(ShelvesetGenericComparer.Instance);
817 return shelvesets.ToArray();
820 public Workspace QueryWorkspace(string workspaceName, string ownerName)
822 Message msg = new Message(GetWebRequest (new Uri(Url)), "QueryWorkspace");
823 msg.Body.WriteElementString("workspaceName", workspaceName);
824 msg.Body.WriteElementString("ownerName", ownerName);
826 Workspace workspace;
827 using (HttpWebResponse response = Invoke(msg))
829 XmlReader results = msg.ResponseReader(response);
830 workspace = Workspace.FromXml(this, results);
833 return workspace;
836 public Workspace[] QueryWorkspaces(string workspaceName, string ownerName,
837 string computer)
839 Message msg = new Message(GetWebRequest (new Uri(Url)), "QueryWorkspaces");
840 if (!String.IsNullOrEmpty(workspaceName)) msg.Body.WriteElementString("workspaceName", workspaceName);
841 if (!String.IsNullOrEmpty(ownerName)) msg.Body.WriteElementString("ownerName", ownerName);
842 if (!String.IsNullOrEmpty(computer)) msg.Body.WriteElementString("computer", computer);
844 List<Workspace> workspaces = new List<Workspace>();
845 using (HttpWebResponse response = Invoke(msg))
847 XmlReader results = msg.ResponseReader(response);
849 while (results.Read())
851 if (results.NodeType == XmlNodeType.Element &&
852 results.Name == "Workspace")
853 workspaces.Add(Workspace.FromXml(this, results));
857 workspaces.Sort();
858 return workspaces.ToArray();
861 // <?xml version=_T("1.0") encoding=_T("utf-8")?><soap:Envelope xmlns:xsi=_T("http://www.w3.org/2001/XMLSchema-instance") xmlns=_T("http://schemas.microsoft.com/TeamFoundation/2005/06/VersionControl/ClientServices/03") xmlns:soap=_T("http://www.w3.org/2003/05/soap-envelope")><soap:Body><UpdateWorkspace><oldWorkspaceName>neo</oldWorkspaceName><ownerName>DDI\JREED</ownerName><newWorkspace computer=_T("neo") name=_T("neo") owner=_T("DDI\JREED")><Comment /><LastAccessDate>0001-01-01T00:00:00</LastAccessDate><Folders><WorkingFolder local=_T("C:\MSOCache") item=_T("$/LSG-1.0") /></Folders></newWorkspace></UpdateWorkspace></soap:Body></soap:Envelope
862 public Workspace UpdateWorkspace(string oldWorkspaceName, string ownerName,
863 Workspace newWorkspace)
865 Message msg = new Message(GetWebRequest (new Uri(Url)), "UpdateWorkspace");
866 msg.Body.WriteElementString("oldWorkspaceName", oldWorkspaceName);
867 msg.Body.WriteElementString("ownerName", ownerName);
868 newWorkspace.ToXml(msg.Body, "newWorkspace");
870 Workspace workspace;
871 using (HttpWebResponse response = Invoke(msg))
873 XmlReader results = msg.ResponseReader(response);
874 workspace = Workspace.FromXml(this, results);
877 return workspace;
880 public GetOperation[] UndoPendingChanges(string workspaceName, string ownerName,
881 ItemSpec[] itemSpecs)
883 Message msg = new Message(GetWebRequest (new Uri(Url)), "UndoPendingChanges");
884 msg.Body.WriteElementString("workspaceName", workspaceName);
885 msg.Body.WriteElementString("ownerName", ownerName);
887 msg.Body.WriteStartElement("items");
888 foreach (ItemSpec item in itemSpecs)
890 item.ToXml(msg.Body, "ItemSpec");
892 msg.Body.WriteEndElement();
894 List<GetOperation> operations = new List<GetOperation>();
895 using (HttpWebResponse response = Invoke(msg))
897 XmlReader results = msg.ResponseReader(response);
899 while (results.Read())
901 if (results.NodeType == XmlNodeType.Element &&
902 results.Name == "GetOperation")
903 operations.Add(GetOperation.FromXml(ItemUrl, results));
907 return operations.ToArray();
910 public void UpdateLocalVersion(UpdateLocalVersionQueue queue)
912 Message msg = new Message(GetWebRequest (new Uri(Url)), "UpdateLocalVersion");
913 queue.ToXml(msg.Body, "UpdateLocalVersion");
915 HttpWebResponse response = Invoke(msg);
916 response.Close();
919 public VersionControlServer VersionControlServer
921 get { return versionControlServer; }
924 public string ItemUrl
926 get { return itemUrl; }
931 class TfsPath
933 private static bool runningOnUnix = true;
934 public static StringComparison PlatformComparison = StringComparison.InvariantCulture;
936 static TfsPath()
938 int p = (int) Environment.OSVersion.Platform;
939 if (!((p == 4) || (p == 128))) runningOnUnix = false;
941 if (!runningOnUnix) PlatformComparison = StringComparison.InvariantCultureIgnoreCase;
944 public static string ToPlatformPath(string path)
946 if (String.IsNullOrEmpty(path)) return path;
948 // TFS servers corrupt *nix type paths
949 if (!runningOnUnix) return path;
950 return path.Remove(0, 2).Replace('\\', '/');
953 public static string FromPlatformPath(string path)
955 if (String.IsNullOrEmpty(path)) return path;
957 // TFS servers corrupt *nix type paths
958 if (!runningOnUnix) return path;
959 return "C:" + path.Replace('/', '\\');