public UpdateEditorContext(IShape model, IContent content, IUpdateModel updater, string groupInfoId, IShapeFactory shapeFactory, ShapeTable shapeTable, string path) : base(model, content, groupInfoId, shapeFactory) { ShapeTable = shapeTable; Updater = updater; Path = path; }
private static PlacementInfo FindPlacementImpl(ShapeTable shapeTable, IShape shape, string differentiator, string displayType) { ShapeDescriptor descriptor; var shapeType = shape.Metadata.Type; if (shapeTable.Descriptors.TryGetValue(shapeType, out descriptor)) { var placementContext = new ShapePlacementContext { Shape = shape, DisplayType = displayType, Differentiator = differentiator }; var placement = descriptor.Placement(placementContext); if (placement != null) { placement.Source = placementContext.Source; return placement; } } return null; }
public ShapeTable GetShapeTable(string themeName) { return(_cacheManager.Get(themeName ?? "", x => { Logger.Information("Start building shape table"); var alterationSets = _parallelCacheContext.RunInParallel(_bindingStrategies, bindingStrategy => { Feature strategyDefaultFeature = bindingStrategy.Metadata.ContainsKey("Feature") ? (Feature)bindingStrategy.Metadata["Feature"] : null; var builder = new ShapeTableBuilder(strategyDefaultFeature); bindingStrategy.Value.Discover(builder); return builder.BuildAlterations().ToReadOnlyCollection(); }); var alterations = alterationSets .SelectMany(shapeAlterations => shapeAlterations) .Where(alteration => IsModuleOrRequestedTheme(alteration, themeName)) .OrderByDependenciesAndPriorities(AlterationHasDependency, GetPriority) .ToList(); var descriptors = alterations.GroupBy(alteration => alteration.ShapeType, StringComparer.OrdinalIgnoreCase) .Select(group => group.Aggregate( new ShapeDescriptor { ShapeType = group.Key }, (descriptor, alteration) => { alteration.Alter(descriptor); return descriptor; })).ToList(); foreach (var descriptor in descriptors) { foreach (var alteration in alterations.Where(a => a.ShapeType == descriptor.ShapeType).ToList()) { var local = new ShapeDescriptor { ShapeType = descriptor.ShapeType }; alteration.Alter(local); descriptor.BindingSources.Add(local.BindingSource); } } var result = new ShapeTable { Descriptors = descriptors.ToDictionary(sd => sd.ShapeType, StringComparer.OrdinalIgnoreCase), Bindings = descriptors.SelectMany(sd => sd.Bindings).ToDictionary(kv => kv.Key, kv => kv.Value, StringComparer.OrdinalIgnoreCase), }; _shapeTableEventHandlers.Invoke(ctx => ctx.ShapeTableCreated(result), Logger); Logger.Information("Done building shape table"); return result; })); }
protected override void Register(ContainerBuilder builder) { var defaultShapeTable = new ShapeTable { Descriptors = new Dictionary<string, ShapeDescriptor>(StringComparer.OrdinalIgnoreCase), Bindings = new Dictionary<string, ShapeBinding>(StringComparer.OrdinalIgnoreCase) }; builder.Register(ctx => defaultShapeTable); builder.RegisterType<DefaultDisplayManagerTests.TestWorkContextAccessor>().As<IWorkContextAccessor>(); builder.RegisterType<DefaultShapeFactory>().As<IShapeFactory>(); builder.RegisterType<DefaultShapeTableManager>().As<IShapeTableManager>(); builder.RegisterType<LayoutWorkContext>().As<IWorkContextStateProvider>(); builder.RegisterType<ShapeTableLocator>().As<IShapeTableLocator>(); builder.RegisterType<DefaultDisplayManager>().As<IDisplayManager>(); builder.RegisterType<DefaultDisplayManagerTests.TestShapeTableManager>().As<IShapeTableManager>(); builder.RegisterType<CoreShapes>().As<IShapeTableProvider>(); }
public ShapeTable GetShapeTable(string themeName) { return _cacheManager.Get(themeName ?? "", x => { Logger.Information("Start building shape table"); var alterationSets = _parallelCacheContext.RunInParallel(_bindingStrategies, bindingStrategy => { Feature strategyDefaultFeature = bindingStrategy.Metadata.ContainsKey("Feature") ? (Feature)bindingStrategy.Metadata["Feature"] : null; var builder = new ShapeTableBuilder(strategyDefaultFeature); bindingStrategy.Value.Discover(builder); return builder.BuildAlterations().ToReadOnlyCollection(); }); var alterations = alterationSets .SelectMany(shapeAlterations => shapeAlterations) .Where(alteration => IsModuleOrRequestedTheme(alteration, themeName)) .OrderByDependenciesAndPriorities(AlterationHasDependency, GetPriority) .ToList(); var descriptors = alterations.GroupBy(alteration => alteration.ShapeType, StringComparer.OrdinalIgnoreCase) .Select(group => group.Aggregate( new ShapeDescriptor { ShapeType = group.Key }, (descriptor, alteration) => { alteration.Alter(descriptor); return descriptor; })).ToList(); foreach(var descriptor in descriptors) { foreach(var alteration in alterations.Where(a => a.ShapeType == descriptor.ShapeType).ToList()) { var local = new ShapeDescriptor { ShapeType = descriptor.ShapeType }; alteration.Alter(local); descriptor.BindingSources.Add(local.BindingSource); } } var result = new ShapeTable { Descriptors = descriptors.ToDictionary(sd => sd.ShapeType, StringComparer.OrdinalIgnoreCase), Bindings = descriptors.SelectMany(sd => sd.Bindings).ToDictionary(kv => kv.Key, kv => kv.Value, StringComparer.OrdinalIgnoreCase), }; _shapeTableEventHandlers.Invoke(ctx => ctx.ShapeTableCreated(result), Logger); Logger.Information("Done building shape table"); return result; }); }
public ShapeFactoryTests() { IServiceCollection serviceCollection = new ServiceCollection(); serviceCollection.AddScoped<ILoggerFactory, StubLoggerFactory>(); serviceCollection.AddScoped<IShapeFactory, DefaultShapeFactory>(); serviceCollection.AddScoped<IExtensionManager, StubExtensionManager>(); serviceCollection.AddScoped<IShapeTableManager, TestShapeTableManager>(); var defaultShapeTable = new ShapeTable { Descriptors = new Dictionary<string, ShapeDescriptor>(StringComparer.OrdinalIgnoreCase), Bindings = new Dictionary<string, ShapeBinding>(StringComparer.OrdinalIgnoreCase) }; serviceCollection.AddInstance(defaultShapeTable); _serviceProvider = serviceCollection.BuildServiceProvider(); }
public void ShapeTableCreated(ShapeTable shapeTable) { var typeDefinitions = _contentDefinitionManager.Value.ListTypeDefinitions(); var allPlacements = typeDefinitions.SelectMany(td => td.GetPlacement(PlacementType.Editor).Select(p => new TypePlacement { Placement = p, ContentType = td.Name }) ); // group all placement settings by shape type var shapePlacements = allPlacements.GroupBy(x => x.Placement.ShapeType).ToDictionary(x => x.Key, y=> y.ToList()); // create a new predicate in a ShapeTableDescriptor has a custom placement foreach(var shapeType in shapeTable.Descriptors.Keys) { List<TypePlacement> customPlacements; if(shapePlacements.TryGetValue(shapeType, out customPlacements)) { var descriptor = shapeTable.Descriptors[shapeType]; // there are some custom placements, build a predicate var placement = descriptor.Placement; if(!customPlacements.Any()) { continue; } descriptor.Placement = ctx => { if(ctx.DisplayType == null) { foreach(var customPlacement in customPlacements) { var type = customPlacement.ContentType; var differentiator = customPlacement.Placement.Differentiator; if (((ctx.Differentiator ?? String.Empty) == (differentiator ?? String.Empty)) && ctx.ContentType == type) { var location = customPlacement.Placement.Zone; if (!String.IsNullOrEmpty(customPlacement.Placement.Position)) { location = String.Concat(location, ":", customPlacement.Placement.Position); } return new PlacementInfo { Location = location }; } } } return placement(ctx); }; } } }
public ShapeHelperTests() { IServiceCollection serviceCollection = new ServiceCollection(); serviceCollection.AddScoped<ILoggerFactory, StubLoggerFactory>(); serviceCollection.AddScoped<IHttpContextAccessor, StubHttpContextAccessor>(); serviceCollection.AddScoped<IHtmlDisplay, DefaultIHtmlDisplay>(); serviceCollection.AddScoped<IExtensionManager, StubExtensionManager>(); serviceCollection.AddScoped<IShapeFactory, DefaultShapeFactory>(); serviceCollection.AddScoped<IShapeTableManager, TestShapeTableManager>(); var defaultShapeTable = new ShapeTable { Descriptors = new Dictionary<string, ShapeDescriptor>(StringComparer.OrdinalIgnoreCase), Bindings = new Dictionary<string, ShapeBinding>(StringComparer.OrdinalIgnoreCase) }; serviceCollection.AddSingleton(defaultShapeTable); _serviceProvider = serviceCollection.BuildServiceProvider(); }
public ShapeTableBindings(ShapeTable shapeTable) { _shapeTable = shapeTable; }
private bool TryGetDescriptorBinding(string shapeType, IEnumerable<string> shapeAlternates, ShapeTable shapeTable, out ShapeBinding shapeBinding) { // shape alternates are optional, fully qualified binding names // the earliest added alternates have the lowest priority // the descriptor returned is based on the binding that is matched, so it may be an entirely // different descriptor if the alternate has a different base name foreach (var shapeAlternate in shapeAlternates.Reverse()) { foreach (var shapeBindingResolver in _shapeBindingResolvers) { if(shapeBindingResolver.TryGetDescriptorBinding(shapeAlternate, out shapeBinding)) { return true; } } if (shapeTable.Bindings.TryGetValue(shapeAlternate, out shapeBinding)) { return true; } } // when no alternates match, the shapeType is used to find the longest matching binding // the shapetype name can break itself into shorter fallbacks at double-underscore marks // so the shapetype itself may contain a longer alternate forms that falls back to a shorter one var shapeTypeScan = shapeType; for (; ; ) { foreach (var shapeBindingResolver in _shapeBindingResolvers) { if (shapeBindingResolver.TryGetDescriptorBinding(shapeTypeScan, out shapeBinding)) { return true; } } if (shapeTable.Bindings.TryGetValue(shapeTypeScan, out shapeBinding)) { return true; } var delimiterIndex = shapeTypeScan.LastIndexOf("__"); if (delimiterIndex < 0) { shapeBinding = null; return false; } shapeTypeScan = shapeTypeScan.Substring(0, delimiterIndex); } }
public ShapeTable GetShapeTable(string themeName) { var cacheKey = $"ShapeTable:{themeName}"; ShapeTable shapeTable; if (!_memoryCache.TryGetValue(cacheKey, out shapeTable)) { if (_logger.IsEnabled(LogLevel.Information)) { _logger.LogInformation("Start building shape table"); } IList <IReadOnlyList <ShapeAlteration> > alterationSets = new List <IReadOnlyList <ShapeAlteration> >(); foreach (var bindingStrategy in _bindingStrategies) { Feature strategyDefaultFeature = _typeFeatureProvider.GetFeatureForDependency(bindingStrategy.GetType()); var builder = new ShapeTableBuilder(strategyDefaultFeature); bindingStrategy.Discover(builder); var builtAlterations = builder.BuildAlterations().ToReadOnlyCollection(); if (builtAlterations.Any()) { alterationSets.Add(builtAlterations); } } var alterations = alterationSets .SelectMany(shapeAlterations => shapeAlterations) .Where(alteration => IsModuleOrRequestedTheme(alteration, themeName)) .OrderByDependenciesAndPriorities(AlterationHasDependency, GetPriority) .ToList(); var descriptors = alterations.GroupBy(alteration => alteration.ShapeType, StringComparer.OrdinalIgnoreCase) .Select(group => group.Aggregate( new ShapeDescriptor { ShapeType = group.Key }, (descriptor, alteration) => { alteration.Alter(descriptor); return(descriptor); })).ToList(); foreach (var descriptor in descriptors) { foreach (var alteration in alterations.Where(a => a.ShapeType == descriptor.ShapeType).ToList()) { var local = new ShapeDescriptor { ShapeType = descriptor.ShapeType }; alteration.Alter(local); descriptor.BindingSources.Add(local.BindingSource); } } shapeTable = new ShapeTable { Descriptors = descriptors.ToDictionary(sd => sd.ShapeType, StringComparer.OrdinalIgnoreCase), Bindings = descriptors.SelectMany(sd => sd.Bindings).ToDictionary(kv => kv.Key, kv => kv.Value, StringComparer.OrdinalIgnoreCase), }; //await _eventBus.NotifyAsync<IShapeTableEventHandler>(x => x.ShapeTableCreated(result)); if (_logger.IsEnabled(LogLevel.Information)) { _logger.LogInformation("Done building shape table"); } _memoryCache.Set(cacheKey, shapeTable, new MemoryCacheEntryOptions { Priority = CacheItemPriority.NeverRemove }); } return(shapeTable); }
public ShapeTable GetShapeTable(string themeName) { // Use a lazy initialized factory to prevent multiple threads from building // the same table in parallel as it is costly return(_shapeTables.GetOrAdd(themeName ?? "", new Lazy <ShapeTable>(() => { if (_logger.IsEnabled(LogLevel.Information)) { _logger.LogInformation("Start building shape table"); } IList <IReadOnlyList <ShapeAlteration> > alterationSets = new List <IReadOnlyList <ShapeAlteration> >(); foreach (var bindingStrategy in _bindingStrategies) { Feature strategyDefaultFeature = _typeFeatureProvider.GetFeatureForDependency(bindingStrategy.GetType()); var builder = new ShapeTableBuilder(strategyDefaultFeature); bindingStrategy.Discover(builder); var builtAlterations = builder.BuildAlterations().ToReadOnlyCollection(); if (builtAlterations.Any()) { alterationSets.Add(builtAlterations); } } var alterations = alterationSets .SelectMany(shapeAlterations => shapeAlterations) .Where(alteration => IsModuleOrRequestedTheme(alteration, themeName)) .OrderByDependenciesAndPriorities(AlterationHasDependency, GetPriority) .ToList(); var descriptors = alterations.GroupBy(alteration => alteration.ShapeType, StringComparer.OrdinalIgnoreCase) .Select(group => group.Aggregate( new ShapeDescriptor { ShapeType = group.Key }, (descriptor, alteration) => { alteration.Alter(descriptor); return descriptor; })).ToList(); foreach (var descriptor in descriptors) { foreach (var alteration in alterations.Where(a => a.ShapeType == descriptor.ShapeType).ToList()) { var local = new ShapeDescriptor { ShapeType = descriptor.ShapeType }; alteration.Alter(local); descriptor.BindingSources.Add(local.BindingSource); } } var result = new ShapeTable { Descriptors = descriptors.ToDictionary(sd => sd.ShapeType, StringComparer.OrdinalIgnoreCase), Bindings = descriptors.SelectMany(sd => sd.Bindings).ToDictionary(kv => kv.Key, kv => kv.Value, StringComparer.OrdinalIgnoreCase), }; //await _eventBus.NotifyAsync<IShapeTableEventHandler>(x => x.ShapeTableCreated(result)); if (_logger.IsEnabled(LogLevel.Information)) { _logger.LogInformation("Done building shape table"); } return result; })).Value); }
public ShapeTable GetShapeTable(string themeId) { var cacheKey = $"ShapeTable:{themeId}"; ShapeTable shapeTable; if (!_memoryCache.TryGetValue(cacheKey, out shapeTable)) { if (_logger.IsEnabled(LogLevel.Information)) { _logger.LogInformation("Start building shape table"); } var excludedFeatures = _shapeDescriptors.Count == 0 ? new List <string>() : _shapeDescriptors.Select(kv => kv.Value.Feature.Id).Distinct().ToList(); foreach (var bindingStrategy in _bindingStrategies) { IFeatureInfo strategyFeature = _typeFeatureProvider.GetFeatureForDependency(bindingStrategy.GetType()); if (!(bindingStrategy is IShapeTableHarvester) && excludedFeatures.Contains(strategyFeature.Id)) { continue; } var builder = new ShapeTableBuilder(strategyFeature, excludedFeatures); bindingStrategy.Discover(builder); var builtAlterations = builder.BuildAlterations(); BuildDescriptors(bindingStrategy, builtAlterations); } var enabledFeatureIds = _shellFeaturesManager.GetEnabledFeaturesAsync().Result.Select(fd => fd.Id).ToList(); var descriptors = _shapeDescriptors .Where(sd => IsEnabledModuleOrRequestedTheme(sd.Value, themeId, enabledFeatureIds)) .OrderByDependenciesAndPriorities(DescriptorHasDependency, GetPriority) .GroupBy(sd => sd.Value.ShapeType, StringComparer.OrdinalIgnoreCase) .Select(group => new ShapeDescriptorIndex ( shapeType: group.Key, alterationKeys: group.Select(kv => kv.Key), descriptors: _shapeDescriptors )); shapeTable = new ShapeTable { Descriptors = descriptors.Cast <ShapeDescriptor>().ToDictionary(sd => sd.ShapeType, StringComparer.OrdinalIgnoreCase), Bindings = descriptors.SelectMany(sd => sd.Bindings).ToDictionary(kv => kv.Key, kv => kv.Value, StringComparer.OrdinalIgnoreCase) }; if (_logger.IsEnabled(LogLevel.Information)) { _logger.LogInformation("Done building shape table"); } _memoryCache.Set(cacheKey, shapeTable, new MemoryCacheEntryOptions { Priority = CacheItemPriority.NeverRemove }); } return(shapeTable); }
public UpdateContentEditorContext(IShape model, IContent content, string displayType, IUpdateModel updater, string groupId, IShapeFactory shapeFactory, ShapeTable shapeTable, ModelShapeContext parentContext = null) : base(model, content, updater, groupId, shapeFactory, shapeTable) { DisplayType = displayType; ParentContext = parentContext; }
public ShapeTable GetShapeTable(string themeName) { var cacheKey = $"ShapeTable:{themeName}"; ShapeTable shapeTable; if (!_memoryCache.TryGetValue(cacheKey, out shapeTable)) { if (_logger.IsEnabled(LogLevel.Information)) { _logger.LogInformation("Start building shape table"); } IList<IReadOnlyList<ShapeAlteration>> alterationSets = new List<IReadOnlyList<ShapeAlteration>>(); foreach (var bindingStrategy in _bindingStrategies) { Feature strategyDefaultFeature = _typeFeatureProvider.GetFeatureForDependency(bindingStrategy.GetType()); var builder = new ShapeTableBuilder(strategyDefaultFeature); bindingStrategy.Discover(builder); var builtAlterations = builder.BuildAlterations().ToReadOnlyCollection(); if (builtAlterations.Any()) { alterationSets.Add(builtAlterations); } } var alterations = alterationSets .SelectMany(shapeAlterations => shapeAlterations) .Where(alteration => IsModuleOrRequestedTheme(alteration, themeName)) .OrderByDependenciesAndPriorities(AlterationHasDependency, GetPriority) .ToList(); var descriptors = alterations.GroupBy(alteration => alteration.ShapeType, StringComparer.OrdinalIgnoreCase) .Select(group => group.Aggregate( new ShapeDescriptor { ShapeType = group.Key }, (descriptor, alteration) => { alteration.Alter(descriptor); return descriptor; })).ToList(); foreach (var descriptor in descriptors) { foreach (var alteration in alterations.Where(a => a.ShapeType == descriptor.ShapeType).ToList()) { var local = new ShapeDescriptor { ShapeType = descriptor.ShapeType }; alteration.Alter(local); descriptor.BindingSources.Add(local.BindingSource); } } shapeTable = new ShapeTable { Descriptors = descriptors.ToDictionary(sd => sd.ShapeType, StringComparer.OrdinalIgnoreCase), Bindings = descriptors.SelectMany(sd => sd.Bindings).ToDictionary(kv => kv.Key, kv => kv.Value, StringComparer.OrdinalIgnoreCase), }; //await _eventBus.NotifyAsync<IShapeTableEventHandler>(x => x.ShapeTableCreated(result)); if (_logger.IsEnabled(LogLevel.Information)) { _logger.LogInformation("Done building shape table"); } _memoryCache.Set(cacheKey, shapeTable, new MemoryCacheEntryOptions { Priority = CacheItemPriority.NeverRemove }); } return shapeTable; }
public ShapeTable GetShapeTable(string themeName) { // Use a lazy initialized factory to prevent multiple threads from building // the same table in parallel as it is costly return _shapeTables.GetOrAdd(themeName ?? "", new Lazy<ShapeTable>(() => { _logger.LogInformation("Start building shape table"); IList<IReadOnlyList<ShapeAlteration>> alterationSets = new List<IReadOnlyList<ShapeAlteration>>(); foreach (var bindingStrategy in _bindingStrategies) { Feature strategyDefaultFeature = _typeFeatureProvider.GetFeatureForDependency(bindingStrategy.GetType()); var builder = new ShapeTableBuilder(strategyDefaultFeature); bindingStrategy.Discover(builder); var builtAlterations = builder.BuildAlterations().ToReadOnlyCollection(); if (builtAlterations.Any()) { alterationSets.Add(builtAlterations); } } var alterations = alterationSets .SelectMany(shapeAlterations => shapeAlterations) .Where(alteration => IsModuleOrRequestedTheme(alteration, themeName)) .OrderByDependenciesAndPriorities(AlterationHasDependency, GetPriority) .ToList(); var descriptors = alterations.GroupBy(alteration => alteration.ShapeType, StringComparer.OrdinalIgnoreCase) .Select(group => group.Aggregate( new ShapeDescriptor { ShapeType = group.Key }, (descriptor, alteration) => { alteration.Alter(descriptor); return descriptor; })).ToList(); foreach (var descriptor in descriptors) { foreach (var alteration in alterations.Where(a => a.ShapeType == descriptor.ShapeType).ToList()) { var local = new ShapeDescriptor { ShapeType = descriptor.ShapeType }; alteration.Alter(local); descriptor.BindingSources.Add(local.BindingSource); } } var result = new ShapeTable { Descriptors = descriptors.ToDictionary(sd => sd.ShapeType, StringComparer.OrdinalIgnoreCase), Bindings = descriptors.SelectMany(sd => sd.Bindings).ToDictionary(kv => kv.Key, kv => kv.Value, StringComparer.OrdinalIgnoreCase), }; //await _eventBus.NotifyAsync<IShapeTableEventHandler>(x => x.ShapeTableCreated(result)); _logger.LogInformation("Done building shape table"); return result; })).Value; }
public TestShapeTableManager(ShapeTable defaultShapeTable) { _defaultShapeTable = defaultShapeTable; }
public void ShapeTableCreated(ShapeTable shapeTable) { foreach (var descriptor in shapeTable.Descriptors.Values) { var existingPlacement = descriptor.Placement; descriptor.Placement = ctx => { var placements = GetPlacements(); if (!placements.ContainsKey(descriptor.ShapeType)) return existingPlacement(ctx); var declarations = placements[descriptor.ShapeType]; foreach (var declaration in declarations) { if (declaration.Predicate(ctx)) return declaration.Placement; } return existingPlacement(ctx); }; } }