private void ProcessFeatureDescriptor(ShapeTableBuilder builder, FeatureDescriptor featureDescriptor) { var virtualPath = featureDescriptor.Extension.Location + "/" + featureDescriptor.Extension.Id + "/Placement.info"; var placementFile = _placementFileParser.Parse(virtualPath); if (placementFile != null) { ProcessPlacementFile(builder, featureDescriptor, placementFile); } }
private static IEnumerable<FeatureDescriptor> GetFeaturesForExtension(IDictionary<string, string> manifest, ExtensionDescriptorEntry entry) { var featureDescriptors = new List<FeatureDescriptor>(); var descriptor = entry.Descriptor; //默认特性 var defaultFeature = new FeatureDescriptor { Id = entry.Id, Name = GetValue(manifest, FeatureNameSection) ?? descriptor.Name, Priority = GetValue(manifest, PrioritySection) != null ? int.Parse(GetValue(manifest, PrioritySection)) : 0, Description = GetValue(manifest, FeatureDescriptionSection) ?? GetValue(manifest, DescriptionSection) ?? string.Empty, Dependencies = ParseFeatureDependenciesEntry(GetValue(manifest, DependenciesSection)), Extension = entry, Category = GetValue(manifest, CategorySection) }; featureDescriptors.Add(defaultFeature); //剩余特性 var featuresText = GetValue(manifest, FeaturesSection); if (string.IsNullOrWhiteSpace(featuresText)) return featureDescriptors; FeatureDescriptor featureDescriptor = null; using (var reader = new StringReader(featuresText)) { string line; while ((line = reader.ReadLine()) != null) { if (IsFeatureDeclaration(line)) { if (featureDescriptor != null) { if (!featureDescriptor.Equals(defaultFeature)) { featureDescriptors.Add(featureDescriptor); } } var featureDeclaration = line.Split(new[] { ":" }, StringSplitOptions.RemoveEmptyEntries); var featureDescriptorId = featureDeclaration[0].Trim(); if (string.Equals(featureDescriptorId, entry.Id, StringComparison.OrdinalIgnoreCase)) { featureDescriptor = defaultFeature; featureDescriptor.Name = descriptor.Name; } else { featureDescriptor = new FeatureDescriptor { Id = featureDescriptorId, Extension = entry }; } } else if (IsFeatureFieldDeclaration(line)) { if (featureDescriptor != null) { var featureField = line.Split(new[] { ":" }, 2, StringSplitOptions.None); var featureFieldLength = featureField.Length; if (featureFieldLength != 2) continue; for (var i = 0; i < featureFieldLength; i++) { featureField[i] = featureField[i].Trim(); } switch (featureField[0].ToLowerInvariant()) { case NameSection: featureDescriptor.Name = featureField[1]; break; case DescriptionSection: featureDescriptor.Description = featureField[1]; break; case CategorySection: featureDescriptor.Category = featureField[1]; break; case PrioritySection: featureDescriptor.Priority = int.Parse(featureField[1]); break; case DependenciesSection: featureDescriptor.Dependencies = ParseFeatureDependenciesEntry(featureField[1]); break; } } else { var message = string.Format("行 {0} 在清单文件中被忽略,来自扩展 {1}", line, entry.Id); throw new ArgumentException(message); } } else { var message = string.Format("行 {0} 在清单文件中被忽略,来自扩展 {1}", line, entry.Id); throw new ArgumentException(message); } } if (featureDescriptor != null && !featureDescriptor.Equals(defaultFeature)) featureDescriptors.Add(featureDescriptor); } return featureDescriptors; }
/// <summary> /// 如果该项目有关于这个问题的明确或隐含的依赖关系,则返回true /// </summary> internal static bool HasDependency(FeatureDescriptor item, FeatureDescriptor subject) { if (DefaultExtensionTypes.IsTheme(item.Extension.ExtensionType)) { if (DefaultExtensionTypes.IsModule(subject.Extension.ExtensionType)) { //主题含蓄地依赖于模块,以确保构建和覆盖排序 return true; } if (DefaultExtensionTypes.IsTheme(subject.Extension.ExtensionType)) { //主题取决于另一个如果这是它的基本主题 return item.Extension.Descriptor.GetBaseTheme() == subject.Id; } } //基于显式依赖关系返回 return item.Dependencies != null && item.Dependencies.Any(x => StringComparer.OrdinalIgnoreCase.Equals(x, subject.Id)); }
private bool FeatureIsEnabled(FeatureDescriptor fd) { return (DefaultExtensionTypes.IsTheme(fd.Extension.ExtensionType) && (fd.Id == "TheAdmin" || fd.Id == "SafeMode")) || _shellDescriptor.Features.Any(sf => sf.Name == fd.Id); }
/// <summary> /// 初始化一个新的特性描述符过滤器上下文。 /// </summary> /// <param name="feature">特性描述符。</param> public FeatureDescriptorFilterContext(FeatureDescriptor feature) { Feature = feature; Valid = true; }
private static void ProcessPlacementFile(ShapeTableBuilder builder, FeatureDescriptor featureDescriptor, PlacementFile placementFile) { var feature = new Feature { Descriptor = featureDescriptor }; //反转树成叶子的列表,并在堆栈 var entries = DrillDownShapeLocations(placementFile.Nodes, Enumerable.Empty<PlacementMatch>()); foreach (var entry in entries) { var shapeLocation = entry.Item1; var matches = entry.Item2.ToArray(); string shapeType; string differentiator; GetShapeType(shapeLocation, out shapeType, out differentiator); Func<ShapePlacementContext, bool> predicate = ctx => true; if (differentiator != string.Empty) { predicate = ctx => (ctx.Differentiator ?? string.Empty) == differentiator; } if (matches.Any()) { predicate = matches.SelectMany(match => match.Terms).Aggregate(predicate, BuildPredicate); } var placement = new PlacementInfo(); var segments = shapeLocation.Location.Split(';').Select(s => s.Trim()); foreach (var segment in segments) { if (!segment.Contains('=')) { placement.Location = segment; } else { var index = segment.IndexOf('='); var property = segment.Substring(0, index).ToLower(); var value = segment.Substring(index + 1); switch (property) { case "shape": placement.ShapeType = value; break; case "alternate": placement.Alternates = new[] { value }; break; case "wrapper": placement.Wrappers = new[] { value }; break; } } } builder.Describe(shapeType) .From(feature) .Placement(ctx => { var hit = predicate(ctx); //产生'调试'信息跟踪哪个文件起源的实际位置 if (hit) { var virtualPath = featureDescriptor.Extension.Location + "/" + featureDescriptor.Extension.Id + "/Placement.info"; ctx.Source = virtualPath; } return hit; }, placement); } }
private bool FeatureIsEnabled(FeatureDescriptor fd) { return _shellDescriptor.Features.Any(sf => sf.Name == fd.Id); }
private static bool FeatureIsTheme(FeatureDescriptor fd) { return DefaultExtensionTypes.IsTheme(fd.Extension.ExtensionType); }
private Feature LoadFeature(FeatureDescriptor featureDescriptor) { var extensionDescriptor = featureDescriptor.Extension; var featureId = featureDescriptor.Id; var extensionId = extensionDescriptor.Id; ExtensionEntry extensionEntry; try { extensionEntry = _cacheManager.Get(extensionId, ctx => { var entry = BuildEntry(extensionDescriptor); if (entry != null) { ctx.Monitor(_asyncTokenProvider.GetToken(monitor => { foreach (var loader in _loaders.Value) { loader.Monitor(entry.Descriptor, monitor); } })); } return entry; }); } catch (Exception ex) { Logger.Error(ex, "加载扩展 '{0}' 失败", extensionId); throw new RabbitException(T("加载扩展 '{0}' 失败。", extensionId), ex); } if (extensionEntry == null) { //如果该功能因为某种原因不能被编译,返回一个"null"的特性,即没有输出的类型的功能。 return new Feature { Descriptor = featureDescriptor, ExportedTypes = Enumerable.Empty<Type>() }; } var extensionTypes = _serviceTypeHarvester.GeTypes(extensionEntry.ExportedTypes); var featureTypes = extensionTypes.Where( i => string.Equals(GetSourceFeatureNameForType(i, extensionId), featureId, StringComparison.OrdinalIgnoreCase)).ToArray(); return new Feature { Descriptor = featureDescriptor, ExportedTypes = featureTypes }; }
private static int GetPriority(FeatureDescriptor featureDescriptor) { return featureDescriptor.Priority; }
private static bool HasDependency(FeatureDescriptor item, FeatureDescriptor subject) { return item.Dependencies != null && item.Dependencies.Any(x => StringComparer.OrdinalIgnoreCase.Equals(x, subject.Id)); }