/// <summary> /// Gets the package feed from the location. This will first attempt to look up a matching instance in the AllFeeds collection (so that multiple requests for the same feed return a single object) It asks the recognizer to identify the location, and creates a specific subclass instance based on the results. If it cannot identify or read the target, the task will return null. /// </summary> /// <param name="location"> The feed location (url, file, directory). </param> /// <returns> A Task with a return value of the PackageFeed. May be null if invalid. </returns> /// <remarks> /// </remarks> internal static Task <PackageFeed> GetPackageFeedFromLocation(string location) { if (InstalledPackageFeed.CanonicalLocation.Equals(location, StringComparison.CurrentCultureIgnoreCase)) { return(((PackageFeed)InstalledPackageFeed.Instance).AsResultTask()); } if (SessionPackageFeed.CanonicalLocation.Equals(location, StringComparison.CurrentCultureIgnoreCase)) { return(((PackageFeed)SessionPackageFeed.Instance).AsResultTask()); } if (PackageManagerSettings.PerFeedSettings[location.UrlEncodeJustBackslashes(), "state"].GetEnumValue <FeedState>() == FeedState.Ignored) { return(((PackageFeed)null).AsResultTask()); } return(Recognizer.Recognize(location).ContinueWith(antecedent => { var info = antecedent.Result; PackageFeed result = null; string locationKey = null; if (info.IsPackageFeed) { if (info.IsFolder) { locationKey = Path.Combine(info.FullPath, info.Filter); if (AllFeeds.ContainsKey(locationKey)) { return AllFeeds[locationKey]; } result = new DirectoryPackageFeed(info.FullPath, info.Filter); } else if (info.IsFile) { if (AllFeeds.ContainsKey(info.FullPath)) { return AllFeeds[info.FullPath]; } if (info.IsAtom) { result = new AtomPackageFeed(info.FullPath); } /* * if (info.IsArchive) { * result = new ArchivePackageFeed(info.FullPath); * } * */ } // TODO: URL based feeds else if (info.IsURL) { if (AllFeeds.ContainsKey(info.FullUrl.AbsoluteUri)) { return AllFeeds[info.FullUrl.AbsoluteUri]; } if (info.IsAtom) { result = new AtomPackageFeed(info.FullUrl, info.FullPath); } } } else if (info.IsPackageFile) { // SessionPackageFeed.Instance.Add(Package.GetPackageFromFilename(info.FullPath)); result = new DirectoryPackageFeed(Path.GetDirectoryName(info.FullPath), Path.GetFileName(info.FullPath)); // Hack of the day: // Since, I have to look up this file as a feed again later, based on the original path (likely, an http:// location) // we have to forcably set the location in the feed itself to reflect this. result.Location = location; locationKey = location; } if (result != null) { result.RecognitionInfo = info; lock (AllFeeds) { if (!AllFeeds.ContainsKey(locationKey ?? result.Location)) { AllFeeds.Add(locationKey ?? result.Location, result); } else { result = AllFeeds[locationKey ?? result.Location]; } // GS01: TODO: This is a crappy way of avoiding a deadlock when the same feed has been requested twice by two different threads. } } return result; }, TaskContinuationOptions.AttachedToParent)); }
/// <summary> /// Gets the package feed from the location. This will first attempt to look up a matching instance in the AllFeeds collection (so that multiple requests for the same feed return a single object) It asks the recognizer to identify the location, and creates a specific subclass instance based on the results. If it cannot identify or read the target, the task will return null. /// </summary> /// <param name="location"> The feed location (url, file, directory). </param> /// <returns> A Task with a return value of the PackageFeed. May be null if invalid. </returns> /// <remarks> /// </remarks> internal static Task<PackageFeed> GetPackageFeedFromLocation(string location) { if (InstalledPackageFeed.CanonicalLocation.Equals(location, StringComparison.CurrentCultureIgnoreCase)) { return ((PackageFeed)InstalledPackageFeed.Instance).AsResultTask(); } if (SessionPackageFeed.CanonicalLocation.Equals(location, StringComparison.CurrentCultureIgnoreCase)) { return ((PackageFeed)SessionPackageFeed.Instance).AsResultTask(); } if (PackageManagerSettings.PerFeedSettings[location.UrlEncodeJustBackslashes(), "state"].GetEnumValue<FeedState>() == FeedState.Ignored) { return ((PackageFeed)null).AsResultTask(); } return Recognizer.Recognize(location).ContinueWith(antecedent => { var info = antecedent.Result; PackageFeed result = null; string locationKey = null; if (info.IsPackageFeed) { if (info.IsFolder) { locationKey = Path.Combine(info.FullPath, info.Filter); if (AllFeeds.ContainsKey(locationKey)) { return AllFeeds[locationKey]; } result = new DirectoryPackageFeed(info.FullPath, info.Filter); } else if (info.IsFile) { if (AllFeeds.ContainsKey(info.FullPath)) { return AllFeeds[info.FullPath]; } if (info.IsAtom) { result = new AtomPackageFeed(info.FullPath); } /* if (info.IsArchive) { result = new ArchivePackageFeed(info.FullPath); } * */ } // TODO: URL based feeds else if (info.IsURL) { if (AllFeeds.ContainsKey(info.FullUrl.AbsoluteUri)) { return AllFeeds[info.FullUrl.AbsoluteUri]; } if (info.IsAtom) { result = new AtomPackageFeed(info.FullUrl, info.FullPath); } } } else if (info.IsPackageFile) { // SessionPackageFeed.Instance.Add(Package.GetPackageFromFilename(info.FullPath)); result = new DirectoryPackageFeed(Path.GetDirectoryName(info.FullPath), Path.GetFileName(info.FullPath)); // Hack of the day: // Since, I have to look up this file as a feed again later, based on the original path (likely, an http:// location) // we have to forcably set the location in the feed itself to reflect this. result.Location = location; locationKey = location; } if (result != null) { result.RecognitionInfo = info; lock (AllFeeds) { if (!AllFeeds.ContainsKey(locationKey ?? result.Location)) { AllFeeds.Add(locationKey ?? result.Location, result); } else { result = AllFeeds[locationKey ?? result.Location]; } // GS01: TODO: This is a crappy way of avoiding a deadlock when the same feed has been requested twice by two different threads. } } return result; }, TaskContinuationOptions.AttachedToParent); }