show the difference between two versions for a specified path
[tfs.git] / class / Microsoft.TeamFoundation.VersionControl.Client / Repository.cs
blob8b47194f8e4d9e861cb93e1cceeb693a933c8af2
1 //
2 // Microsoft.TeamFoundation.VersionControl.Client.Repository
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.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 CheckInFile(string workspaceName, string ownerName, PendingChange change)
67 UploadFile(workspaceName, ownerName, change, "Checkin");
70 public void ShelveFile(string workspaceName, string ownerName, PendingChange change)
72 UploadFile(workspaceName, ownerName, change, "Shelve");
75 private void UploadFile(string workspaceName, string ownerName, PendingChange change,
76 string commandName)
78 FileInfo fi = new FileInfo(change.LocalItem);
79 long len = fi.Length;
81 UploadFile upload = new UploadFile(uploadUrl, Credentials, commandName);
82 upload.AddValue(RepositoryConstants.ServerItemField, change.ServerItem);
83 upload.AddValue(RepositoryConstants.WorkspaceNameField, workspaceName);
84 upload.AddValue(RepositoryConstants.WorkspaceOwnerField, ownerName);
85 upload.AddValue(RepositoryConstants.LengthField, len.ToString());
86 upload.AddValue(RepositoryConstants.HashField, Convert.ToBase64String(change.UploadHashValue));
88 // send byte range
89 // TODO: handle files to large to fit in a single POST
90 upload.AddValue(RepositoryConstants.RangeField,
91 String.Format("bytes=0-{0}/{1}", len-1, len));
93 upload.AddFile(change.LocalItem);
95 WebResponse response;
97 try
99 response = upload.Send();
101 catch (WebException ex)
103 response = ex.Response;
104 HttpWebResponse http_response = response as HttpWebResponse;
105 if (http_response == null || http_response.StatusCode != HttpStatusCode.InternalServerError)
106 throw ex;
109 // Get the stream associated with the response.
110 //Stream receiveStream = response.GetResponseStream ();
111 //StreamReader readStream = new StreamReader(receiveStream, Encoding.UTF8);
112 //Console.WriteLine (readStream.ReadToEnd ());
114 response.Close();
115 //readStream.Close();
118 protected HttpWebResponse Invoke (Message message)
120 message.End();
121 HttpWebResponse response = GetWebResponse(message.Request) as HttpWebResponse;
123 if (response == null)
125 throw new TeamFoundationServerException("No response from server");
128 if (response.StatusCode == HttpStatusCode.Unauthorized)
130 string msg = String.Format("TF30063: You are not authorized to access {0} ({1}).\n--> Did you supply the correct username, password, and domain?",
131 (new Uri(this.Url)).Host, message.MethodName);
133 //StreamReader readStream = new StreamReader(response.GetResponseStream(), Encoding.UTF8);
134 // Console.Error.WriteLine (readStream.ReadToEnd ());
135 //readStream.Close();
137 throw new TeamFoundationServerException(msg);
140 if (response.StatusCode == HttpStatusCode.InternalServerError)
142 throw new VersionControlException(GetExceptionMessage(response));
145 return response;
148 public string GetExceptionMessage(HttpWebResponse response)
150 StreamReader sr = new StreamReader(response.GetResponseStream(), new UTF8Encoding (false), false);
151 XmlReader reader = new XmlTextReader(sr);
152 string msg = String.Empty;
153 while (reader.Read())
155 if (reader.NodeType == XmlNodeType.Element && reader.Name == "faultstring")
157 msg = reader.ReadElementContentAsString();
158 break;
162 response.Close();
163 return msg;
166 public int CheckIn(Workspace workspace, string[] serverItems, string comment,
167 ref SortedList<string, bool> undoneServerItems)
169 Message msg = new Message(GetWebRequest (new Uri(Url)), "CheckIn");
171 msg.Body.WriteElementString("workspaceName", workspace.Name);
172 msg.Body.WriteElementString("ownerName", workspace.OwnerName);
174 msg.Body.WriteStartElement("serverItems");
175 foreach (string serverItem in serverItems)
176 msg.Body.WriteElementString("string", serverItem);
177 msg.Body.WriteEndElement();
179 // write info subtree
180 msg.Body.WriteStartElement("info");
182 DateTime dt = new DateTime(0);
183 msg.Body.WriteAttributeString("date", dt.ToString("s"));
185 msg.Body.WriteAttributeString("cset", "0");
186 msg.Body.WriteAttributeString("owner", workspace.OwnerName);
187 msg.Body.WriteElementString("Comment", comment);
188 msg.Body.WriteElementString("CheckinNote", "");
189 msg.Body.WriteElementString("PolicyOverride", "");
190 msg.Body.WriteElementString("CheckinOptions", "ValidateCheckinOwner");
191 msg.Body.WriteEndElement();
193 int cset = 0;
194 using (HttpWebResponse response = Invoke(msg))
196 XmlReader results = msg.ResponseReader(response);
197 cset = Convert.ToInt32(results.GetAttribute("cset"));
199 List<Failure> failures = new List<Failure>();
201 //TODO: read <ImplicitItems />
202 //<CheckInResponse xmlns="http://schemas.microsoft.com/TeamFoundation/2005/06/VersionControl/ClientServices/03"><CheckInResult cset="11486"><UndoneServerItems /><ImplicitItems /></CheckInResult><failures /></CheckInResponse>
203 while (results.Read())
205 if (results.NodeType == XmlNodeType.Element)
207 switch (results.Name)
209 case "Failure":
210 failures.Add(Failure.FromXml(this, results));
211 break;
212 case "string":
213 undoneServerItems.Add(results.ReadString(), true);
214 break;
219 foreach (Failure failure in failures)
221 versionControlServer.OnNonFatalError(workspace, failure);
225 return cset;
228 public void CreateTeamProjectFolder(TeamProjectFolderOptions teamProjectOptions)
230 Message msg = new Message(GetWebRequest (new Uri(Url)), "CreateTeamProjectFolder");
231 teamProjectOptions.ToXml(msg.Body, "");
232 HttpWebResponse response = Invoke(msg);
233 response.Close();
236 public Workspace CreateWorkspace(Workspace workspace)
238 Message msg = new Message(GetWebRequest (new Uri(Url)), "CreateWorkspace");
239 workspace.ToXml(msg.Body, "workspace");
241 Workspace newWorkspace;
242 using (HttpWebResponse response = Invoke(msg))
244 XmlReader results = msg.ResponseReader(response);
245 newWorkspace = Workspace.FromXml(this, results);
248 return newWorkspace;
251 [System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://schemas.microsoft.com/TeamFoundation/2005/06/VersionControl/ClientServices/03/DeleteShelveset", 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)]
252 public void DeleteShelveset(string shelvesetName, string ownerName)
254 this.Invoke("DeleteShelveset", new object[] { shelvesetName, ownerName});
257 [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)]
258 public void DeleteWorkspace(string workspaceName, string ownerName)
260 this.Invoke("DeleteWorkspace", new object[] { workspaceName, ownerName});
263 public LabelResult[] LabelItem(Workspace workspace, VersionControlLabel label,
264 LabelItemSpec[] labelSpecs, LabelChildOption children)
266 Message msg = new Message(GetWebRequest (new Uri(Url)), "LabelItem");
268 msg.Body.WriteElementString("workspaceName", workspace.Name);
269 msg.Body.WriteElementString("workspaceOwner", workspace.OwnerName);
270 label.ToXml(msg.Body, "label");
272 msg.Body.WriteStartElement("labelSpecs");
273 foreach (LabelItemSpec labelSpec in labelSpecs)
275 labelSpec.ToXml(msg.Body, "LabelItemSpec");
277 msg.Body.WriteEndElement();
279 msg.Body.WriteElementString("children", children.ToString());
281 List<LabelResult> labelResults = new List<LabelResult>();
282 List<Failure> faillist = new List<Failure>();
284 using (HttpWebResponse response = Invoke(msg))
286 XmlReader results = msg.ResponseReader(response);
288 while (results.Read())
290 if (results.NodeType == XmlNodeType.Element)
292 switch (results.Name)
294 case "LabelResult":
295 labelResults.Add(LabelResult.FromXml(this, results));
296 break;
297 case "Failure":
298 faillist.Add(Failure.FromXml(this, results));
299 break;
305 foreach (Failure failure in faillist)
307 versionControlServer.OnNonFatalError(workspace, failure);
310 return labelResults.ToArray();
313 public void Shelve(Workspace workspace, Shelveset shelveset,
314 string[] serverItems, ShelvingOptions options)
316 Message msg = new Message(GetWebRequest (new Uri(Url)), "Shelve");
318 msg.Body.WriteElementString("workspaceName", workspace.Name);
319 msg.Body.WriteElementString("workspaceOwner", workspace.OwnerName);
321 msg.Body.WriteStartElement("serverItems");
322 foreach (string serverItem in serverItems)
323 msg.Body.WriteElementString("string", serverItem);
324 msg.Body.WriteEndElement();
326 shelveset.ToXml(msg.Body, "shelveset");
328 bool replace = (options & ShelvingOptions.Replace) == ShelvingOptions.Replace;
329 msg.Body.WriteElementString("replace", replace.ToString().ToLower());
331 using (HttpWebResponse response = Invoke(msg))
333 msg.ResponseReader(response);
337 public LabelResult[] UnlabelItem(Workspace workspace, string labelName,
338 string labelScope, ItemSpec[] itemSpecs,
339 VersionSpec version)
341 Message msg = new Message(GetWebRequest (new Uri(Url)), "UnlabelItem");
343 msg.Body.WriteElementString("workspaceName", workspace.Name);
344 msg.Body.WriteElementString("workspaceOwner", workspace.OwnerName);
345 msg.Body.WriteElementString("labelName", labelName);
347 if (!String.IsNullOrEmpty(labelScope))
348 msg.Body.WriteElementString("labelScope", labelScope);
350 msg.Body.WriteStartElement("items");
351 foreach (ItemSpec itemSpec in itemSpecs)
353 itemSpec.ToXml(msg.Body, "ItemSpec");
355 msg.Body.WriteEndElement();
357 version.ToXml(msg.Body, "version");
359 List<LabelResult> labelResults = new List<LabelResult>();
360 List<Failure> faillist = new List<Failure>();
362 using (HttpWebResponse response = Invoke(msg))
364 XmlReader results = msg.ResponseReader(response);
366 while (results.Read())
368 if (results.NodeType == XmlNodeType.Element)
370 switch (results.Name)
372 case "LabelResult":
373 labelResults.Add(LabelResult.FromXml(this, results));
374 break;
375 case "Failure":
376 faillist.Add(Failure.FromXml(this, results));
377 break;
383 foreach (Failure failure in faillist)
385 versionControlServer.OnNonFatalError(workspace, failure);
388 return labelResults.ToArray();
391 public GetOperation[] Get(string workspaceName, string ownerName,
392 GetRequest[] requests, bool force, bool noGet) {
394 Message msg = new Message(GetWebRequest (new Uri(Url)), "Get");
395 msg.Body.WriteElementString("workspaceName", workspaceName);
396 msg.Body.WriteElementString("ownerName", ownerName);
398 msg.Body.WriteStartElement("requests");
399 foreach (GetRequest request in requests)
401 request.ToXml(msg.Body, "");
403 msg.Body.WriteEndElement();
405 msg.Body.WriteElementString("force", force.ToString().ToLower());
406 msg.Body.WriteElementString("noGet", noGet.ToString().ToLower());
408 List<GetOperation> operations = new List<GetOperation>();
409 using (HttpWebResponse response = Invoke(msg))
411 XmlReader results = msg.ResponseReader(response);
413 while (results.Read())
415 if (results.NodeType == XmlNodeType.Element &&
416 results.Name == "GetOperation")
417 operations.Add(GetOperation.FromXml(ItemUrl, results));
421 return operations.ToArray();
424 public RepositoryProperties GetRepositoryProperties()
426 Message msg = new Message(GetWebRequest (new Uri(Url)), "GetRepositoryProperties");
427 RepositoryProperties properties;
428 using (HttpWebResponse response = Invoke(msg))
430 XmlReader results = msg.ResponseReader(response);
431 properties = RepositoryProperties.FromXml(this, results);
434 return properties;
437 public GetOperation[] PendChanges(Workspace workspace, ChangeRequest[] changes)
439 Message msg = new Message(GetWebRequest (new Uri(Url)), "PendChanges");
441 msg.Body.WriteElementString("workspaceName", workspace.Name);
442 msg.Body.WriteElementString("ownerName", workspace.OwnerName);
443 msg.Body.WriteStartElement("changes");
444 foreach (ChangeRequest change in changes)
446 change.ToXml(msg.Body, "");
448 msg.Body.WriteEndElement();
450 List<GetOperation> operations = new List<GetOperation>();
451 List<Failure> faillist = new List<Failure>();
453 using (HttpWebResponse response = Invoke(msg))
455 XmlReader results = msg.ResponseReader(response);
457 while (results.Read())
459 if (results.NodeType == XmlNodeType.Element)
461 switch (results.Name)
463 case "GetOperation":
464 operations.Add(GetOperation.FromXml(ItemUrl, results));
465 break;
466 case "Failure":
467 faillist.Add(Failure.FromXml(this, results));
468 break;
474 foreach (Failure failure in faillist)
476 versionControlServer.OnNonFatalError(workspace, failure);
479 return operations.ToArray();
482 public Annotation[] QueryAnnotation(string annotationName, string annotatedItem, int version)
484 Message msg = new Message(GetWebRequest (new Uri(Url)), "QueryAnnotation");
486 msg.Body.WriteElementString("annotationName", annotationName);
487 msg.Body.WriteElementString("annotatedItem", annotatedItem);
488 msg.Body.WriteElementString("version", Convert.ToString(version));
490 List<Annotation> labels = new List<Annotation>();
491 using (HttpWebResponse response = Invoke(msg))
493 XmlReader results = msg.ResponseReader(response);
495 while (results.Read())
497 if (results.NodeType == XmlNodeType.Element &&
498 results.Name == "Annotation")
499 labels.Add(Annotation.FromXml(this, results));
503 return labels.ToArray();
506 public BranchHistoryTreeItem[][] QueryBranches(string workspaceName, string workspaceOwner,
507 ItemSpec[] itemSpecs, VersionSpec versionSpec)
509 Message msg = new Message(GetWebRequest (new Uri(Url)), "QueryBranches");
511 if (!String.IsNullOrEmpty(workspaceName)) msg.Body.WriteElementString("workspaceName", workspaceName);
512 if (!String.IsNullOrEmpty(workspaceOwner)) msg.Body.WriteElementString("workspaceOwner", workspaceOwner);
513 msg.Body.WriteStartElement("items");
514 foreach (ItemSpec itemSpec in itemSpecs)
515 itemSpec.ToXml(msg.Body, "ItemSpec");
516 msg.Body.WriteEndElement();
518 versionSpec.ToXml(msg.Body, "version");
520 List<BranchHistoryTreeItem[]> tree = new List<BranchHistoryTreeItem[]>();
521 using (HttpWebResponse response = Invoke(msg))
523 XmlReader results = msg.ResponseReader(response);
524 while (results.Read())
526 if (results.NodeType == XmlNodeType.Element &&
527 results.Name == "ArrayOfBranchRelative")
529 List<BranchRelative> branches = new List<BranchRelative>();
530 while (results.Read())
532 if (results.NodeType == XmlNodeType.EndElement &&
533 results.Name == "ArrayOfBranchRelative") break;
534 if (results.NodeType == XmlNodeType.Element &&
535 results.Name == "BranchRelative")
536 branches.Add(BranchRelative.FromXml(this, results));
539 if (branches.Count > 0)
541 List<BranchHistoryTreeItem> items = new List<BranchHistoryTreeItem>();
542 items.Add(new BranchHistoryTreeItem(branches.ToArray()));
543 tree.Add(items.ToArray());
549 return tree.ToArray();
552 public Changeset QueryChangeset(int changesetId, bool includeChanges,
553 bool generateDownloadUrls)
555 Message msg = new Message(GetWebRequest (new Uri(Url)), "QueryChangeset");
557 msg.Body.WriteElementString("changesetId", Convert.ToString(changesetId));
558 msg.Body.WriteElementString("includeChanges", Convert.ToString(includeChanges).ToLower());
559 msg.Body.WriteElementString("generateDownloadUrls", Convert.ToString(generateDownloadUrls).ToLower());
561 Changeset changeset = null;
563 using (HttpWebResponse response = Invoke(msg))
565 XmlReader results = msg.ResponseReader(response);
566 changeset = Changeset.FromXml(this, results);
569 return changeset;
572 public int QueryHistory (string workspaceName, string workspaceOwner,
573 ItemSpec itemSpec, VersionSpec version,
574 string user, VersionSpec versionFrom,
575 VersionSpec versionTo, int maxCount,
576 bool includeFiles, bool slotMode,
577 bool generateDownloadUrls, ref List<Changeset> changes)
579 Message msg = new Message(GetWebRequest (new Uri(Url)), "QueryHistory");
581 if (!String.IsNullOrEmpty(workspaceName)) msg.Body.WriteElementString("workspaceName", workspaceName);
582 if (!String.IsNullOrEmpty(workspaceOwner)) msg.Body.WriteElementString("workspaceOwner", workspaceOwner);
584 itemSpec.ToXml(msg.Body, "itemSpec");
585 if (version != null) version.ToXml(msg.Body, "versionItem");
586 if (versionFrom != null) versionFrom.ToXml(msg.Body, "versionFrom");
587 if (versionTo != null) versionTo.ToXml(msg.Body, "versionTo");
589 if (!String.IsNullOrEmpty(user)) msg.Body.WriteElementString("user", user);
590 msg.Body.WriteElementString("maxCount", Convert.ToString(maxCount));
591 msg.Body.WriteElementString("includeFiles", Convert.ToString(includeFiles).ToLower());
592 msg.Body.WriteElementString("generateDownloadUrls", Convert.ToString(generateDownloadUrls).ToLower());
593 msg.Body.WriteElementString("slotMode", Convert.ToString(slotMode).ToLower());
595 int cnt = 0;
596 using (HttpWebResponse response = Invoke(msg))
598 XmlReader results = msg.ResponseReader(response);
600 while (results.Read())
602 if (results.NodeType == XmlNodeType.Element &&
603 results.Name == "Changeset")
605 changes.Add(Changeset.FromXml(this, results));
606 cnt++;
611 return cnt;
614 public ItemSet[] QueryItems(string workspaceName, string workspaceOwner,
615 ItemSpec[] itemSpecs, VersionSpec versionSpec,
616 DeletedState deletedState, ItemType itemType,
617 bool generateDownloadUrls)
619 Message msg = new Message(GetWebRequest (new Uri(Url)), "QueryItems");
621 if (!String.IsNullOrEmpty(workspaceName)) msg.Body.WriteElementString("workspaceName", workspaceName);
622 if (!String.IsNullOrEmpty(workspaceOwner)) msg.Body.WriteElementString("workspaceOwner", workspaceOwner);
623 msg.Body.WriteStartElement("items");
624 foreach (ItemSpec itemSpec in itemSpecs)
625 itemSpec.ToXml(msg.Body, "ItemSpec");
626 msg.Body.WriteEndElement();
628 versionSpec.ToXml(msg.Body, "version");
630 msg.Body.WriteElementString("deletedState",
631 deletedState.ToString());
632 msg.Body.WriteElementString("itemType",
633 itemType.ToString());
634 msg.Body.WriteElementString("generateDownloadUrls",
635 generateDownloadUrls.ToString().ToLower());
637 List<ItemSet> itemSet = new List<ItemSet>();
638 using (HttpWebResponse response = Invoke(msg))
640 XmlReader results = msg.ResponseReader(response);
642 while (results.Read())
644 if (results.NodeType == XmlNodeType.Element &&
645 results.Name == "ItemSet")
646 itemSet.Add(ItemSet.FromXml(this, results));
650 return itemSet.ToArray();
653 public ExtendedItem[][] QueryItemsExtended(string workspaceName, string workspaceOwner,
654 ItemSpec[] itemSpecs,
655 DeletedState deletedState, ItemType itemType)
657 Message msg = new Message(GetWebRequest (new Uri(Url)), "QueryItemsExtended");
659 if (!String.IsNullOrEmpty(workspaceName)) msg.Body.WriteElementString("workspaceName", workspaceName);
660 if (!String.IsNullOrEmpty(workspaceOwner)) msg.Body.WriteElementString("workspaceOwner", workspaceOwner);
662 msg.Body.WriteStartElement("items");
663 foreach (ItemSpec itemSpec in itemSpecs)
665 itemSpec.ToXml(msg.Body, "ItemSpec");
667 msg.Body.WriteEndElement();
669 msg.Body.WriteElementString("deletedState",
670 deletedState.ToString());
671 msg.Body.WriteElementString("itemType",
672 itemType.ToString());
674 List< ExtendedItem[] > listOfItemArrays = new List<ExtendedItem[] >();
675 using (HttpWebResponse response = Invoke(msg))
677 XmlReader results = msg.ResponseReader(response);
678 while (results.Read())
680 if (results.NodeType == XmlNodeType.Element &&
681 results.Name == "ArrayOfExtendedItem")
683 List<ExtendedItem> items = new List<ExtendedItem>();
684 while (results.Read())
686 //Console.WriteLine(" " + results.Name + ":" + results.NodeType);
687 if (results.NodeType == XmlNodeType.EndElement &&
688 results.Name == "ArrayOfExtendedItem") break;
689 if (results.NodeType == XmlNodeType.Element &&
690 results.Name == "ExtendedItem")
691 items.Add(ExtendedItem.FromXml(this, results));
693 listOfItemArrays.Add(items.ToArray());
698 return listOfItemArrays.ToArray();
701 public VersionControlLabel[] QueryLabels(string workspaceName, string workspaceOwner,
702 string labelName, string labelScope,
703 string owner, string filterItem,
704 VersionSpec versionFilterItem,
705 bool includeItems, bool generateDownloadUrls)
707 Message msg = new Message(GetWebRequest (new Uri(Url)), "QueryLabels");
709 if (!String.IsNullOrEmpty(workspaceName)) msg.Body.WriteElementString("workspaceName", workspaceName);
710 if (!String.IsNullOrEmpty(workspaceOwner)) msg.Body.WriteElementString("workspaceOwner", workspaceOwner);
711 if (!String.IsNullOrEmpty(labelName)) msg.Body.WriteElementString("labelName", labelName);
712 if (!String.IsNullOrEmpty(labelScope)) msg.Body.WriteElementString("labelScope", labelScope);
713 if (!String.IsNullOrEmpty(owner)) msg.Body.WriteElementString("owner", owner);
714 if (!String.IsNullOrEmpty(filterItem)) msg.Body.WriteElementString("filterItem", filterItem);
716 if (null != versionFilterItem) versionFilterItem.ToXml(msg.Body, "versionFilterItem");
717 msg.Body.WriteElementString("includeItems", includeItems.ToString().ToLower());
718 msg.Body.WriteElementString("generateDownloadUrls", generateDownloadUrls.ToString().ToLower());
720 List<VersionControlLabel> labels = new List<VersionControlLabel>();
721 using (HttpWebResponse response = Invoke(msg))
723 XmlReader results = msg.ResponseReader(response);
725 while (results.Read())
727 if (results.NodeType == XmlNodeType.Element &&
728 results.Name == "VersionControlLabel")
729 labels.Add(VersionControlLabel.FromXml(this, results));
733 return labels.ToArray();
736 public Item[] QueryItemsById(int[] ids, int changeSet,
737 bool generateDownloadUrls)
739 Message msg = new Message(GetWebRequest (new Uri(Url)), "QueryItemsById");
741 msg.Body.WriteStartElement("itemIds");
742 foreach (int id in ids)
744 msg.Body.WriteElementString("int", Convert.ToString(id));
746 msg.Body.WriteEndElement();
748 msg.Body.WriteElementString("changeSet", Convert.ToString(changeSet));
749 msg.Body.WriteElementString("generateDownloadUrls",
750 generateDownloadUrls.ToString().ToLower());
752 List<Item> items = new List<Item>();
753 using (HttpWebResponse response = Invoke(msg))
755 XmlReader results = msg.ResponseReader(response);
757 while (results.Read())
759 if (results.NodeType == XmlNodeType.Element &&
760 results.Name == "Item")
761 items.Add(Item.FromXml(this, results));
765 return items.ToArray();
768 public ItemSecurity[] QueryItemPermissions(string[] identityNames, string[] items,
769 RecursionType recursion)
771 Message msg = new Message(GetWebRequest (new Uri(Url)), "QueryItemPermissions");
773 msg.Body.WriteStartElement("itemSpecs");
774 foreach (string item in items)
776 ItemSpec spec = new ItemSpec(item, recursion);
777 spec.ToXml(msg.Body, "ItemSpec");
779 msg.Body.WriteEndElement();
781 List<ItemSecurity> itemSecurities = new List<ItemSecurity>();
782 using (HttpWebResponse response = Invoke(msg))
784 XmlReader results = msg.ResponseReader(response);
786 while (results.Read())
788 if (results.NodeType == XmlNodeType.Element &&
789 results.Name == "ItemSecurity")
790 itemSecurities.Add(ItemSecurity.FromXml(this, results));
794 return itemSecurities.ToArray();
797 public ChangesetMerge[] QueryMerges(string workspaceName, string workspaceOwner,
798 ItemSpec source, VersionSpec versionSource,
799 ItemSpec target, VersionSpec versionTarget,
800 VersionSpec versionFrom, VersionSpec versionTo,
801 int maxChangesets)
803 Message msg = new Message(GetWebRequest (new Uri(Url)), "QueryMerges");
805 if (!String.IsNullOrEmpty(workspaceName)) msg.Body.WriteElementString("workspaceName", workspaceName);
806 if (!String.IsNullOrEmpty(workspaceOwner)) msg.Body.WriteElementString("workspaceOwner", workspaceOwner);
808 if (source != null) source.ToXml(msg.Body, "source");
809 if (versionSource != null) versionSource.ToXml(msg.Body, "versionSource");
811 target.ToXml(msg.Body, "target");
812 versionTarget.ToXml(msg.Body, "versionTarget");
814 if (versionFrom != null) versionFrom.ToXml(msg.Body, "versionFrom");
815 if (versionTo != null) versionTo.ToXml(msg.Body, "versionTo");
817 msg.Body.WriteElementString("maxChangesets", Convert.ToString(maxChangesets));
819 List<ChangesetMerge> merges = new List<ChangesetMerge>();
820 Dictionary<int, Changeset> changesets = new Dictionary<int, Changeset>();
821 using (HttpWebResponse response = Invoke(msg))
823 XmlReader results = msg.ResponseReader(response);
825 while (results.Read())
827 if (results.NodeType != XmlNodeType.Element) continue;
829 if (results.Name == "ChangesetMerge")
831 merges.Add(ChangesetMerge.FromXml(this, results));
833 else if (results.Name == "Changeset")
835 Changeset changeset = Changeset.FromXml(this, results);
836 changesets.Add(changeset.ChangesetId, changeset);
841 foreach (ChangesetMerge merge in merges)
843 Changeset changeset;
844 if (changesets.TryGetValue(merge.TargetVersion, out changeset))
845 merge.TargetChangeset = changeset;
848 return merges.ToArray();
851 public PendingChange[] QueryPendingSets(string localWorkspaceName, string localWorkspaceOwner,
852 string queryWorkspaceName, string ownerName,
853 ItemSpec[] itemSpecs, bool generateDownloadUrls,
854 out Failure[] failures)
856 Message msg = new Message(GetWebRequest (new Uri(Url)), "QueryPendingSets");
857 msg.Body.WriteElementString("localWorkspaceName", localWorkspaceName);
858 msg.Body.WriteElementString("localWorkspaceOwner", localWorkspaceOwner);
859 msg.Body.WriteElementString("queryWorkspaceName", queryWorkspaceName);
860 msg.Body.WriteElementString("ownerName", ownerName);
862 msg.Body.WriteStartElement("itemSpecs");
863 foreach (ItemSpec item in itemSpecs)
865 item.ToXml(msg.Body, "ItemSpec");
867 msg.Body.WriteEndElement();
869 msg.Body.WriteElementString("generateDownloadUrls",
870 generateDownloadUrls.ToString().ToLower());
872 List<PendingChange> changes = new List<PendingChange>();
873 List<Failure> faillist = new List<Failure>();
875 using (HttpWebResponse response = Invoke(msg))
877 XmlReader results = msg.ResponseReader(response);
879 while (results.Read())
881 if (results.NodeType == XmlNodeType.Element)
883 switch (results.Name)
885 case "PendingChange":
886 changes.Add(PendingChange.FromXml(this, results));
887 break;
888 case "Failure":
889 faillist.Add(Failure.FromXml(this, results));
890 break;
896 failures = faillist.ToArray();
897 return changes.ToArray();
900 public Shelveset[] QueryShelvesets (string shelvesetName, string shelvesetOwner)
902 Message msg = new Message(GetWebRequest (new Uri(Url)), "QueryShelvesets");
903 if (!String.IsNullOrEmpty(shelvesetName)) msg.Body.WriteElementString("shelvesetName", shelvesetName);
904 msg.Body.WriteElementString("ownerName", shelvesetOwner);
906 List<Shelveset> shelvesets = new List<Shelveset>();
907 using (HttpWebResponse response = Invoke(msg))
909 XmlReader results = msg.ResponseReader(response);
911 while (results.Read())
913 if (results.NodeType == XmlNodeType.Element &&
914 results.Name == "Shelveset")
915 shelvesets.Add(Shelveset.FromXml(this, results));
919 shelvesets.Sort(ShelvesetGenericComparer.Instance);
920 return shelvesets.ToArray();
923 public Workspace QueryWorkspace(string workspaceName, string ownerName)
925 Message msg = new Message(GetWebRequest (new Uri(Url)), "QueryWorkspace");
926 msg.Body.WriteElementString("workspaceName", workspaceName);
927 msg.Body.WriteElementString("ownerName", ownerName);
929 Workspace workspace;
930 using (HttpWebResponse response = Invoke(msg))
932 XmlReader results = msg.ResponseReader(response);
933 workspace = Workspace.FromXml(this, results);
936 return workspace;
939 public Workspace[] QueryWorkspaces(string workspaceName, string ownerName,
940 string computer)
942 Message msg = new Message(GetWebRequest (new Uri(Url)), "QueryWorkspaces");
943 if (!String.IsNullOrEmpty(workspaceName)) msg.Body.WriteElementString("workspaceName", workspaceName);
944 if (!String.IsNullOrEmpty(ownerName)) msg.Body.WriteElementString("ownerName", ownerName);
945 if (!String.IsNullOrEmpty(computer)) msg.Body.WriteElementString("computer", computer);
947 List<Workspace> workspaces = new List<Workspace>();
948 using (HttpWebResponse response = Invoke(msg))
950 XmlReader results = msg.ResponseReader(response);
952 while (results.Read())
954 if (results.NodeType == XmlNodeType.Element &&
955 results.Name == "Workspace")
956 workspaces.Add(Workspace.FromXml(this, results));
960 workspaces.Sort();
961 return workspaces.ToArray();
964 public Workspace UpdateWorkspace(string oldWorkspaceName, string ownerName,
965 Workspace newWorkspace)
967 Message msg = new Message(GetWebRequest (new Uri(Url)), "UpdateWorkspace");
968 msg.Body.WriteElementString("oldWorkspaceName", oldWorkspaceName);
969 msg.Body.WriteElementString("ownerName", ownerName);
970 newWorkspace.ToXml(msg.Body, "newWorkspace");
972 Workspace workspace;
973 using (HttpWebResponse response = Invoke(msg))
975 XmlReader results = msg.ResponseReader(response);
976 workspace = Workspace.FromXml(this, results);
979 return workspace;
982 public GetOperation[] UndoPendingChanges(string workspaceName, string ownerName,
983 ItemSpec[] itemSpecs)
985 Message msg = new Message(GetWebRequest (new Uri(Url)), "UndoPendingChanges");
986 msg.Body.WriteElementString("workspaceName", workspaceName);
987 msg.Body.WriteElementString("ownerName", ownerName);
989 msg.Body.WriteStartElement("items");
990 foreach (ItemSpec item in itemSpecs)
992 item.ToXml(msg.Body, "ItemSpec");
994 msg.Body.WriteEndElement();
996 List<GetOperation> operations = new List<GetOperation>();
997 using (HttpWebResponse response = Invoke(msg))
999 XmlReader results = msg.ResponseReader(response);
1001 while (results.Read())
1003 if (results.NodeType == XmlNodeType.Element &&
1004 results.Name == "GetOperation")
1005 operations.Add(GetOperation.FromXml(ItemUrl, results));
1009 return operations.ToArray();
1012 public void UpdateLocalVersion(UpdateLocalVersionQueue queue)
1014 Message msg = new Message(GetWebRequest (new Uri(Url)), "UpdateLocalVersion");
1015 queue.ToXml(msg.Body, "UpdateLocalVersion");
1017 HttpWebResponse response = Invoke(msg);
1018 response.Close();
1021 public VersionControlServer VersionControlServer
1023 get { return versionControlServer; }
1026 public string ItemUrl
1028 get { return itemUrl; }
1033 class TfsPath
1035 private static bool runningOnUnix = true;
1036 public static StringComparison PlatformComparison = StringComparison.InvariantCulture;
1038 static TfsPath()
1040 int p = (int) Environment.OSVersion.Platform;
1041 if (!((p == 4) || (p == 128))) runningOnUnix = false;
1043 if (!runningOnUnix) PlatformComparison = StringComparison.InvariantCultureIgnoreCase;
1046 public static string ToPlatformPath(string path)
1048 if (String.IsNullOrEmpty(path)) return path;
1050 // TFS servers corrupt *nix type paths
1051 if (!runningOnUnix) return path;
1052 return path.Remove(0, 2).Replace('\\', '/');
1055 public static string FromPlatformPath(string path)
1057 if (String.IsNullOrEmpty(path)) return path;
1059 // TFS servers corrupt *nix type paths
1060 if (!runningOnUnix) return path;
1061 return "C:" + path.Replace('/', '\\');