PageRenderTime 51ms CodeModel.GetById 22ms RepoModel.GetById 1ms app.codeStats 0ms

/Dev/code/TfsAdminTools/SCWrapper.cs

http://TfsAdminToolkit.codeplex.com
C# | 965 lines | 824 code | 137 blank | 4 comment | 63 complexity | a388513e06a32413afce3ed40a4a5601 MD5 | raw file
  1. namespace Sogeti.SourceControlWrapper
  2. {
  3. using System;
  4. using System.Collections;
  5. using System.Collections.Generic;
  6. using System.Collections.ObjectModel;
  7. using System.ComponentModel;
  8. using System.Globalization;
  9. using System.IO;
  10. using System.Linq;
  11. using System.Text.RegularExpressions;
  12. using System.Windows.Data;
  13. using System.Xml;
  14. using Microsoft.TeamFoundation.Client;
  15. using Microsoft.TeamFoundation.VersionControl.Client;
  16. using Microsoft.TeamFoundation.VersionControl.Common;
  17. using mskold.TfsAdminToolKit;
  18. using Sogeti.VSExtention;
  19. public enum fileSizeUnits
  20. {
  21. bytes,
  22. KB,
  23. MB,
  24. GB,
  25. TB,
  26. PB
  27. }
  28. public class EnumDescriptionConverter : IValueConverter
  29. {
  30. #region IValueConverter Members
  31. public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
  32. {
  33. if (value is fileSizeUnits)
  34. {
  35. if (targetType == typeof(IEnumerable) && parameter.ToString() == "List")
  36. {
  37. List<string> lst = new List<string>();
  38. foreach (var item in Enum.GetNames(value.GetType()))
  39. {
  40. lst.Add(item);
  41. }
  42. return lst;
  43. }
  44. else
  45. {
  46. foreach (var item in Enum.GetValues(typeof(fileSizeUnits)))
  47. {
  48. var asstring = (item as Enum).ToString();
  49. if (asstring == value.ToString())
  50. {
  51. return item;
  52. }
  53. }
  54. }
  55. }
  56. return (value as Enum).ToString();
  57. }
  58. public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
  59. {
  60. if (targetType == typeof(fileSizeUnits))
  61. {
  62. foreach (var item in Enum.GetValues(targetType))
  63. {
  64. var asstring = (item as Enum).ToString();
  65. if (asstring == (string)value)
  66. {
  67. return item;
  68. }
  69. }
  70. }
  71. else
  72. {
  73. foreach (var item in Enum.GetValues(targetType))
  74. {
  75. var asstring = (item as Enum).ToString();
  76. if (asstring == (string)value)
  77. {
  78. return item;
  79. }
  80. }
  81. }
  82. return null;
  83. }
  84. #endregion
  85. }
  86. public class DivideBy2Converter : IValueConverter
  87. {
  88. #region IValueConverter Members
  89. public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
  90. {
  91. if (value is int || value is double)
  92. {
  93. double d = 0;
  94. double.TryParse(value.ToString(), out d);
  95. return d * System.Convert.ToDouble(parameter, CultureInfo.InvariantCulture);
  96. }
  97. return 0;
  98. }
  99. public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
  100. {
  101. return null;
  102. }
  103. #endregion
  104. }
  105. public class FileSizeConverter : IValueConverter
  106. {
  107. #region IValueConverter Members
  108. public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
  109. {
  110. if (value is int || value is double || value is long)
  111. {
  112. return SCFileSize.SizeTxt(System.Convert.ToInt64(value));
  113. }
  114. return 0;
  115. }
  116. public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
  117. {
  118. return null;
  119. }
  120. #endregion
  121. }
  122. public class SearchCondition
  123. {
  124. private bool isCaseSensitive;
  125. private Regex regexpSearch;
  126. private string txtSearch;
  127. private bool useRegexp;
  128. public SearchCondition(string pattern, bool caseSensive, bool useReqExpMatching)
  129. {
  130. isCaseSensitive = caseSensive;
  131. useRegexp = useReqExpMatching;
  132. if (useRegexp)
  133. {
  134. regexpSearch = new Regex(pattern);
  135. }
  136. else
  137. {
  138. txtSearch = pattern;
  139. }
  140. }
  141. public bool Matches(string s)
  142. {
  143. bool ret = false;
  144. if (s == null)
  145. {
  146. return false;
  147. }
  148. if (useRegexp)
  149. {
  150. ret = regexpSearch.IsMatch(s);
  151. }
  152. else
  153. {
  154. if (!isCaseSensitive)
  155. {
  156. ret = s.ToUpper().Contains(txtSearch.ToUpper());
  157. }
  158. else
  159. {
  160. ret = s.Contains(txtSearch);
  161. }
  162. }
  163. return ret;
  164. }
  165. public int MatchStart(string s)
  166. {
  167. int ret=-1;
  168. if (useRegexp)
  169. {
  170. ret = regexpSearch.Match(s).Index;
  171. }
  172. else
  173. {
  174. if (!isCaseSensitive)
  175. {
  176. ret = s.ToUpper().IndexOf(txtSearch.ToUpper());
  177. }
  178. else
  179. {
  180. ret = s.IndexOf(txtSearch);
  181. }
  182. }
  183. return ret;
  184. }
  185. public int MatchEnd(string s)
  186. {
  187. int ret=-1;
  188. if (useRegexp)
  189. {
  190. Match theMatch= regexpSearch.Match(s);
  191. ret = theMatch.Index + theMatch.Length;
  192. }
  193. else
  194. {
  195. if (!isCaseSensitive)
  196. {
  197. ret = s.ToUpper().IndexOf(txtSearch.ToUpper())+txtSearch.Length;
  198. }
  199. else
  200. {
  201. ret = s.IndexOf(txtSearch)+txtSearch.Length;
  202. }
  203. }
  204. return ret;
  205. }
  206. }
  207. public class Wildcard : Regex
  208. {
  209. public Wildcard(string pattern)
  210. : base(WildcardToRegex(pattern))
  211. {
  212. }
  213. public Wildcard(string pattern, RegexOptions options)
  214. : base(WildcardToRegex(pattern), options)
  215. {
  216. }
  217. public static string WildcardToRegex(string pattern)
  218. {
  219. string s=null;
  220. if(pattern.StartsWith("@"))
  221. {
  222. s= pattern.Substring(2);
  223. }
  224. else
  225. {
  226. s= "^(" + Regex.Escape(pattern).Replace("\\*", ".*").Replace("\\?", ".").Replace(";", "|") + ")$";
  227. }
  228. return s;
  229. }
  230. }
  231. public class SCFileSize
  232. {
  233. public static string SizeTxt(long theSize)
  234. {
  235. string s = string.Empty;
  236. long d = theSize;
  237. if (theSize != 0)
  238. {
  239. string[] size = Enum.GetNames(typeof(fileSizeUnits));
  240. long last = d;
  241. int i = 0;
  242. do
  243. {
  244. last = d;
  245. d = d / 1024;
  246. i++;
  247. } while (d > 1);
  248. s = string.Format("{0:#,0.##} {1}", last, size[i - 1]);
  249. }
  250. return s;
  251. }
  252. public static long GetSizeInBytes(long size, fileSizeUnits unit)
  253. {
  254. long d = size;
  255. string[] sizeLst = Enum.GetNames(typeof(fileSizeUnits));
  256. int i = 0;
  257. while (sizeLst[i] != unit.ToString())
  258. {
  259. d *= 1024;
  260. i++;
  261. }
  262. return d;
  263. }
  264. }
  265. public class WI
  266. {
  267. public string AreaPath;
  268. public string Description;
  269. public string IterationPath;
  270. public string Title;
  271. public string Type;
  272. public Dictionary<string, object> customFields;
  273. public WI()
  274. {
  275. customFields = new Dictionary<string, object>();
  276. }
  277. }
  278. public class SCFolder : INotifyPropertyChanged
  279. {
  280. public SCFolder()
  281. {
  282. Folders = new List<SCFolder>();
  283. FileTypes = new Dictionary<string, long>();
  284. InclusiveFileTypes = new Dictionary<string, long>();
  285. }
  286. public string FolderName
  287. {
  288. get { return FolderPath.Split('/').Last(); }
  289. }
  290. public bool IsSelected
  291. {
  292. get
  293. {
  294. return _isSelected;
  295. }
  296. set
  297. {
  298. _isSelected = value;
  299. NotifyPropertyChanged("IsSelected");
  300. }
  301. }
  302. public string FolderPath { get; set; }
  303. public long SizeInclusive { get; set; }
  304. public long SizeExclusive { get; set; }
  305. public List<SCFolder> Folders { get; set; }
  306. public Dictionary<string, long> FileTypes { get; set; }
  307. public Dictionary<string, long> InclusiveFileTypes { get; set; }
  308. public string SizeTxt
  309. {
  310. get { return SCFileSize.SizeTxt(SizeInclusive); }
  311. }
  312. #region INotifyPropertyChanged Members
  313. public event PropertyChangedEventHandler PropertyChanged;
  314. #endregion
  315. public void AddFolder(SCFolder fld)
  316. {
  317. Folders.Add(fld);
  318. NotifyPropertyChanged("Folders");
  319. }
  320. public void SetInclusiveSize()
  321. {
  322. long inclusive = 0;
  323. InclusiveFileTypes.Clear();
  324. foreach (string key in FileTypes.Keys)
  325. {
  326. InclusiveFileTypes.Add(key, FileTypes[key]);
  327. }
  328. foreach (SCFolder fld in Folders)
  329. {
  330. inclusive += fld.SizeInclusive;
  331. foreach (string key in fld.InclusiveFileTypes.Keys)
  332. {
  333. if (!InclusiveFileTypes.Keys.Contains(key))
  334. {
  335. InclusiveFileTypes.Add(key, 0);
  336. }
  337. InclusiveFileTypes[key] += fld.InclusiveFileTypes[key];
  338. }
  339. }
  340. SizeInclusive = inclusive + SizeExclusive;
  341. NotifyPropertyChanged("SizeTxt");
  342. }
  343. public void NotifyPropertyChanged(string info)
  344. {
  345. if (PropertyChanged != null)
  346. {
  347. PropertyChanged(this, new PropertyChangedEventArgs(info));
  348. }
  349. }
  350. private bool _isSelected;
  351. }
  352. public class SCFile : INotifyPropertyChanged
  353. {
  354. public SCFile()
  355. {
  356. }
  357. public string FileName
  358. {
  359. get { return FilePath.Split('/').Last(); }
  360. }
  361. public string FilePath { get; set; }
  362. public string Committer { get; set; }
  363. public DateTime CheckInDate { get; set; }
  364. public string Comment { get; set; }
  365. public bool Deleted { get; set; }
  366. public int ChangesetId { get; set; }
  367. public int ItemId { get; set; }
  368. public long Size { get; set; }
  369. public string SizeTxt
  370. {
  371. get { return SCFileSize.SizeTxt(Size); }
  372. }
  373. public string PreviewText
  374. {
  375. get;set;
  376. }
  377. #region INotifyPropertyChanged Members
  378. public event PropertyChangedEventHandler PropertyChanged;
  379. #endregion
  380. public static void AddFileToList(SCFile file, List<SCFile> lst)
  381. {
  382. lst.Add(file);
  383. file.NotifyPropertyChanged("FoundFiles");
  384. }
  385. public void NotifyPropertyChanged(string info)
  386. {
  387. if (PropertyChanged != null)
  388. {
  389. PropertyChanged(this, new PropertyChangedEventArgs(info));
  390. }
  391. }
  392. public string FileExt
  393. {
  394. get
  395. {
  396. return FileName.Substring(FileName.LastIndexOf('.')+1);
  397. }
  398. }
  399. public string FileNameWithoutExt
  400. {
  401. get
  402. {
  403. return FileName.Substring(0, FileName.LastIndexOf('.'));
  404. }
  405. }
  406. }
  407. public class SCWrapper
  408. {
  409. protected VersionControlServer scSrv;
  410. protected string teamProjectName;
  411. protected TfsTeamProjectCollection tpCollection;
  412. public SCWrapper(string tpCollectionUrl, string aTeamProjectName)
  413. {
  414. tpCollection = new TfsTeamProjectCollection(new Uri(tpCollectionUrl));
  415. teamProjectName = aTeamProjectName;
  416. scSrv = (VersionControlServer)tpCollection.GetService(typeof(VersionControlServer));
  417. }
  418. public SCWrapper(TeamExplorerIntergator teamExplorer)
  419. {
  420. tpCollection = teamExplorer.tpCollection;
  421. teamProjectName = teamExplorer.tpName;
  422. scSrv = (VersionControlServer)tpCollection.GetService(typeof(VersionControlServer));
  423. }
  424. public string RootFolder()
  425. {
  426. return scSrv.GetTeamProject(teamProjectName).ServerItem;
  427. }
  428. public List<SCFolder> GetRootFolders()
  429. {
  430. List<SCFolder> lst = new List<SCFolder>();
  431. ItemSet items = scSrv.GetItems("$\\", RecursionType.OneLevel);
  432. foreach (Item itm in items.Items)
  433. {
  434. if (itm.ServerItem != @"$/")
  435. {
  436. if (itm.ItemType == ItemType.Folder)
  437. {
  438. lst.Add(new SCFolder { FolderPath = itm.ServerItem });
  439. }
  440. }
  441. }
  442. return lst;
  443. }
  444. public void CalcSize(ref SCFolder fld)
  445. {
  446. ItemSet items = scSrv.GetItems(fld.FolderPath, VersionSpec.Latest, RecursionType.OneLevel, DeletedState.NonDeleted, ItemType.Any);
  447. long totalExclusive = 0;
  448. long totalInclusive = 0;
  449. foreach (Item itm in items.Items)
  450. {
  451. switch (itm.ItemType)
  452. {
  453. case ItemType.File:
  454. long size = itm.ContentLength;
  455. totalExclusive += size;
  456. string fileExt = itm.ServerItem.Split('.').Last();
  457. if (!fld.FileTypes.Keys.Contains(fileExt))
  458. {
  459. fld.FileTypes.Add(fileExt, 0);
  460. }
  461. fld.FileTypes[fileExt] += size;
  462. break;
  463. case ItemType.Folder:
  464. if (itm.ServerItem != fld.FolderPath)
  465. {
  466. SCFolder child = new SCFolder { FolderPath = itm.ServerItem };
  467. CalcSize(ref child);
  468. fld.SetInclusiveSize();
  469. fld.AddFolder(child);
  470. totalInclusive += child.SizeInclusive;
  471. }
  472. break;
  473. }
  474. }
  475. fld.SizeExclusive = totalExclusive;
  476. fld.SetInclusiveSize();
  477. }
  478. public void DownLoadFile(string filename, int itemId, int changesetId)
  479. {
  480. Item itm = scSrv.GetItem(itemId, changesetId);
  481. itm.DownloadFile(filename);
  482. }
  483. public List<SCFile> SearchForFile(SCFolder fld, Wildcard fileNameFilter, long minSize)
  484. {
  485. ItemSet items = scSrv.GetItems(fld.FolderPath, VersionSpec.Latest, RecursionType.OneLevel, DeletedState.NonDeleted, ItemType.Any);
  486. List<SCFile> lst = new List<SCFile>();
  487. foreach (Item itm in items.Items)
  488. {
  489. switch (itm.ItemType)
  490. {
  491. case ItemType.File:
  492. if (itm.ContentLength > minSize)
  493. {
  494. if (fileNameFilter.IsMatch(itm.ServerItem))
  495. {
  496. SCFile file = new SCFile();
  497. file.ItemId = itm.ItemId;
  498. file.ChangesetId = itm.ChangesetId;
  499. file.FilePath = itm.ServerItem;
  500. file.Size = itm.ContentLength;
  501. Changeset chgSet = itm.VersionControlServer.GetChangeset(itm.ChangesetId);
  502. file.Committer = chgSet.Committer;
  503. file.CheckInDate = itm.CheckinDate;
  504. file.Comment = chgSet.Comment;
  505. if (itm.DeletionId != null)
  506. {
  507. file.Deleted = itm.DeletionId != 0;
  508. }
  509. SCFile.AddFileToList(file, lst);
  510. }
  511. }
  512. break;
  513. case ItemType.Folder:
  514. if (itm.ServerItem != fld.FolderPath)
  515. {
  516. SCFolder child = new SCFolder { FolderPath = itm.ServerItem };
  517. lst.AddRange(SearchForFile(child, fileNameFilter, minSize));
  518. }
  519. break;
  520. }
  521. }
  522. return lst;
  523. }
  524. public List<SCFile> SearchForCheckIn(SCFolder fld, Wildcard user, Wildcard comment, Wildcard fileNameFilter, SearchCondition search, bool bSearchInHistory, CancelCallbackNotify callback)
  525. {
  526. QueryHistoryParameters qhp = new QueryHistoryParameters(fld.FolderPath, RecursionType.None);
  527. List<SCFile> lstFoundFiles= new List<SCFile>();
  528. IEnumerable<Changeset> changesets = null;
  529. int i = 0;
  530. foreach (Changeset chgset in changesets)
  531. {
  532. i++;
  533. if (user.IsMatch(chgset.Committer))
  534. {
  535. if (callback.DoCallback((double)i / changesets.Count(), chgset.ChangesetId.ToString(), ref lstFoundFiles))
  536. {
  537. return lstFoundFiles;
  538. }
  539. if (comment.IsMatch(chgset.Comment))
  540. {
  541. SCFile file = new SCFile();
  542. file.ChangesetId = chgset.ChangesetId;
  543. file.Comment = chgset.Comment.ToString();
  544. file.FilePath = chgset.Committer;
  545. SCFile.AddFileToList(file, lstFoundFiles);
  546. }
  547. }
  548. }
  549. return lstFoundFiles;
  550. }
  551. public bool FileExist(string fileName)
  552. {
  553. return scSrv.ServerItemExists(fileName, ItemType.File);
  554. }
  555. public Stream Get(string filename)
  556. {
  557. Item itm = scSrv.GetItem(filename);
  558. return itm.DownloadFile();
  559. }
  560. public void Save(string filename, XmlDocument xml)
  561. {
  562. // Using temporary directory for the workspace mapping
  563. var dir = new DirectoryInfo(Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()));
  564. string serverPath = filename.Substring(0, filename.LastIndexOf(@"/"));
  565. string fileNamePart = filename.Replace(serverPath + @"/", string.Empty);
  566. if (!dir.Exists)
  567. {
  568. dir.Create();
  569. }
  570. try
  571. {
  572. // Query for workspaces and delete if found.
  573. string username = null;
  574. if (tpCollection.Credentials is System.Net.NetworkCredential)
  575. {
  576. System.Net.NetworkCredential nw = tpCollection.Credentials as System.Net.NetworkCredential;
  577. if (nw.UserName != string.Empty)
  578. {
  579. username = nw.Domain + @"\" + nw.UserName;
  580. }
  581. }
  582. if (username == null)
  583. {
  584. username = Environment.UserName;
  585. }
  586. var ws = scSrv.QueryWorkspaces("temp", username, Environment.MachineName).FirstOrDefault();
  587. if (ws != null)
  588. {
  589. ws.Delete();
  590. }
  591. // Create the workspace with a mapping to the temporary folder.
  592. ws = scSrv.CreateWorkspace("temp", username, string.Empty, new WorkingFolder[] { new WorkingFolder(serverPath, dir.FullName) });
  593. ws.Get(new GetRequest(filename, RecursionType.None, VersionSpec.Latest), GetOptions.None);
  594. // Create a file and add it as a pending change.
  595. var file = Path.Combine(dir.FullName, fileNamePart);
  596. FileInfo fi = new FileInfo(file);
  597. if (fi.Exists)
  598. {
  599. fi.Attributes = FileAttributes.Normal;
  600. xml.Save(file);
  601. ws.PendEdit(file);
  602. }
  603. else
  604. {
  605. xml.Save(file);
  606. ws.PendAdd(file);
  607. }
  608. // Finally check-in, don't trigger a Continuous Integration build and override gated check-in.
  609. var wip = new WorkspaceCheckInParameters(ws.GetPendingChanges(), "***NO_CI***")
  610. {
  611. // Enable the override of gated check-in when the server supports gated check-ins.
  612. OverrideGatedCheckIn =
  613. ((CheckInOptions2)scSrv.SupportedFeatures & CheckInOptions2.OverrideGatedCheckIn) ==
  614. CheckInOptions2.OverrideGatedCheckIn,
  615. PolicyOverride = new PolicyOverrideInfo("Check-in from IterationnManaager.", null)
  616. };
  617. ws.CheckIn(wip);
  618. }
  619. finally
  620. {
  621. if (dir.Exists)
  622. {
  623. dir.Attributes = FileAttributes.Normal;
  624. dir.Delete(true);
  625. }
  626. }
  627. }
  628. public List<SCFile> SearchForFileContent(List<SCFolder> fldLst, Wildcard fileNameFilter, SearchCondition search, bool bSearchInHistory, CancelCallbackNotify callback)
  629. {
  630. int i = 0;
  631. List<SCFile> lstFoundFiles = new List<SCFile>();
  632. foreach (SCFolder fld in fldLst)
  633. {
  634. callback.DoCallback((double)i / fldLst.Count(), fld.FolderPath, ref lstFoundFiles);
  635. CancelCallbackNotify notify = new CancelCallbackNotify();
  636. notify._delegate = callback._delegate;
  637. notify.start = callback.current;
  638. notify.range = callback.range/fldLst.Count;
  639. notify.isCanceled = callback.isCanceled;
  640. lstFoundFiles.AddRange(SearchForFileContent(fld, fileNameFilter, search, bSearchInHistory, notify));
  641. i ++;
  642. if (notify.isCanceled)
  643. {
  644. break;
  645. }
  646. }
  647. return lstFoundFiles;
  648. }
  649. public List<SCFile> SearchForFileContent(SCFolder fld, Wildcard fileNameFilter, SearchCondition search, bool bSearchInHistory, CancelCallbackNotify callback)
  650. {
  651. ItemSet items = scSrv.GetItems(fld.FolderPath, VersionSpec.Latest, RecursionType.OneLevel, DeletedState.Any, ItemType.Any);
  652. List<SCFile> lstFoundFiles = new List<SCFile>();
  653. Regex t = new Regex(@"^(.*\.vb|.*\.xaml)$");
  654. bool b = t.IsMatch("foo.vb");
  655. int i = 0;
  656. foreach (Item itmLatest in items.Items)
  657. {
  658. if (callback.isCanceled)
  659. {
  660. break;
  661. }
  662. switch (itmLatest.ItemType)
  663. {
  664. case ItemType.File:
  665. i++;
  666. if (fileNameFilter.IsMatch(itmLatest.ServerItem))
  667. {
  668. if (callback.DoCallback((double)i / items.Items.Count(), itmLatest.ServerItem, ref lstFoundFiles))
  669. {
  670. return lstFoundFiles;
  671. }
  672. else
  673. if (bSearchInHistory)
  674. {
  675. foreach (Changeset ch in scSrv.QueryHistory(itmLatest.ServerItem,
  676. VersionSpec.Latest,
  677. 0,
  678. RecursionType.Full,
  679. string.Empty,
  680. null,
  681. VersionSpec.Latest,
  682. int.MaxValue,
  683. true,
  684. true))
  685. {
  686. Item myItm = scSrv.GetItem(itmLatest.ItemId, ch.ChangesetId);
  687. if (myItm != null)
  688. {
  689. FindInItem(search, ref lstFoundFiles, myItm);
  690. }
  691. }
  692. }
  693. else
  694. {
  695. FindInItem(search, ref lstFoundFiles, itmLatest);
  696. }
  697. }
  698. break;
  699. case ItemType.Folder:
  700. if (itmLatest.ServerItem != fld.FolderPath)
  701. {
  702. i++;
  703. if (callback.DoCallback((double)i / items.Items.Count(), itmLatest.ServerItem, ref lstFoundFiles))
  704. {
  705. return lstFoundFiles;
  706. }
  707. else
  708. {
  709. SCFolder child = new SCFolder { FolderPath = itmLatest.ServerItem };
  710. CancelCallbackNotify subCallback = new CancelCallbackNotify();
  711. subCallback._delegate = callback._delegate;
  712. subCallback.start = callback.current;
  713. subCallback.range = 1.0 / (items.Items.Count() - 1);
  714. lstFoundFiles.AddRange( SearchForFileContent(child, fileNameFilter, search, bSearchInHistory, subCallback));
  715. }
  716. }
  717. break;
  718. }
  719. }
  720. callback.DoCallback(1, "Done searching " + fld.FolderPath, ref lstFoundFiles);
  721. return lstFoundFiles;
  722. }
  723. private static void FindInItem(SearchCondition search, ref List<SCFile> lstFoundFiles,Item itm)
  724. {
  725. try
  726. {
  727. Stream fileStream = itm.DownloadFile();
  728. StreamReader r = new StreamReader(fileStream);
  729. int lineNo = 0;
  730. do
  731. {
  732. lineNo++;
  733. string s = r.ReadLine();
  734. if (search.Matches(s))
  735. {
  736. SCFile file = new SCFile();
  737. file.FilePath = itm.ServerItem;
  738. file.Size = itm.ContentLength;
  739. file.ItemId = itm.ItemId;
  740. file.ChangesetId = itm.ChangesetId;
  741. file.Comment = lineNo.ToString();
  742. file.PreviewText = ReadPreviewTextFromStream(itm, lineNo, search, 5);
  743. lstFoundFiles.Add(file);
  744. break;
  745. }
  746. } while (!r.EndOfStream);
  747. r.Dispose();
  748. fileStream.Dispose();
  749. }
  750. catch (Exception ex)
  751. {
  752. SCFile file = new SCFile();
  753. file.FilePath = itm.ServerItem;
  754. file.Size = itm.ContentLength;
  755. file.Comment ="ERROR reading file content: " + ex.Message;
  756. lstFoundFiles.Add(file);
  757. }
  758. }
  759. private static string ReadPreviewTextFromStream( Item itm, int lineNo, SearchCondition search, int showExtraLines)
  760. {
  761. string preview = string.Empty;
  762. Stream fileStream = itm.DownloadFile();
  763. StreamReader rTmp = new StreamReader(fileStream);
  764. int readToLine= lineNo;
  765. if (readToLine > showExtraLines)
  766. {
  767. readToLine -= showExtraLines;
  768. }
  769. else{
  770. readToLine=0;
  771. }
  772. for(int i=0; i<readToLine ; i++)
  773. {
  774. rTmp.ReadLine(); //Just waste them
  775. }
  776. for (int i = 0; i < showExtraLines * 2 && !rTmp.EndOfStream; i++)
  777. {
  778. string s= rTmp.ReadLine() + "\r\n";
  779. if (search.Matches(s))
  780. {
  781. int start = search.MatchStart(s);
  782. int end = search.MatchEnd(s);
  783. string pre = s.Substring(0, start);
  784. string hit = s.Substring(start, end - start);
  785. string post = s.Substring(end);
  786. s = string.Format(@"{0}<Bold><Span Background=""Salmon"">{1}</Span></Bold>{2}", pre, hit, post);
  787. }
  788. preview += s;
  789. }
  790. rTmp.Dispose();
  791. fileStream.Dispose();
  792. return preview;
  793. }
  794. }
  795. }