/// <summary> /// Given the full path to a project, return the value of the <LinkedServerProject> property, /// expanded to a full path. /// </summary> /// <param name="projectPath">The full path to the project possibly containing this property.</param> /// <returns>The full path of the RIA link. It may be null or empty.</returns> private string LoadLinkFromProject(string projectPath) { var linkedServerProject = _projectFileReader.GetPropertyValue(projectPath, LinkedServerProjectPropertyName); // RIA Links are usually relative -- convert to full if (!string.IsNullOrEmpty(linkedServerProject)) { linkedServerProject = ProjectFileReader.ConvertToFullPath(linkedServerProject, projectPath); // Emit a message to help user see we found a SimpleEntity Link _logger.LogMessage(string.Format(CultureInfo.CurrentCulture, Resource.SimpleEntity_Link_Present, projectPath, linkedServerProject)); } return(linkedServerProject); }
/// <summary> /// Loads the internal state from the breadcrumb file passed to the ctor. /// </summary> /// <remarks> /// If the root project has been modified since the breadcrumb file /// was written, the entire cache is considered invalid and <c>false</c> is returned. /// If any cached project has been touched since the cache was last written, just /// is portion of the cache will be reloaded from the project file. /// </remarks> /// <returns>A <c>true</c> means the cache was loaded from the breadcrumb file successfully. /// If we detect the cache is out of date or does not exist, a <c>false</c> is returned. /// </returns> internal bool LoadCacheFromFile() { this.IsFileCacheCurrent = false; if (!File.Exists(this._historyFilePath)) { return(false); } // If the root project itself has been touched since the // time we wrote the file, we can't trust anything in our cache DateTime projectWriteTime = File.GetLastWriteTime(this._rootProjectPath); DateTime breadCrumbWriteTime = File.GetLastWriteTime(this._historyFilePath); if (projectWriteTime.CompareTo(breadCrumbWriteTime) > 0) { return(false); } // Read the breadcrumb file. // Format is: // One line per project: path, lastWriteTime, list of source files separated by commas string fileContents = File.ReadAllText(this._historyFilePath); string[] projectEntries = fileContents.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries); foreach (string projectEntry in projectEntries) { string[] projectItems = projectEntry.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); // Fewer than 2 is formatting problem -- maybe the file is corrupt. Just discard cache and rebuild. if (projectItems.Length < 2) { // Always clear out any partial results when returning false this.SourceFilesByProject.Clear(); return(false); } string projectPath = projectItems[0]; // If that project no longer exists, remove it from the cache but keep running if (!File.Exists(projectPath)) { continue; } List <string> files = new List <string>(); // Projects with no source files have only the first 2 items (name and timestamp). // Those will be added to our cache with an empty list to show that we know they // have no source files (otherwise, we would need to open them again to know). // Any project with some number of source files falls into the body of this 'if' if (projectItems.Length >= 3) { // Check whether the project file was touched since the last time // we analyzed it. Failure to parse last write time or discovery // the project has been touched more recently causes us to reload // just that project. Incidentally, the use of Ticks here is more // reliable than DateTime.ToString() which does not round-trip accurately. projectWriteTime = File.GetLastWriteTime(projectPath); long breadCrumbWriteTimeTicks = 0; if (!long.TryParse(projectItems[1], out breadCrumbWriteTimeTicks) || projectWriteTime.Ticks > breadCrumbWriteTimeTicks) { // Go load from the project file and ignore what we had cached files.AddRange(this._projectFileReader.LoadSourceFilesFromProject(projectPath)); } else { // The last write time shows the project has not changed since // we cached the results, so extract them from the text for (int i = 2; i < projectItems.Length; ++i) { string file = projectItems[i]; if (string.IsNullOrEmpty(file)) { continue; } // We write relative paths, so convert back to full string fullFilePath = ProjectFileReader.ConvertToFullPath(file, projectPath); // If the file has ceased to exist, but the project says it // does, we do not add it to our internal lists if (File.Exists(fullFilePath)) { files.Add(fullFilePath); } } } } this[projectPath] = files; } this.IsFileCacheCurrent = true; return(true); }