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);

                _shapeTableMonitors.Invoke(ctx => ctx.Monitor(x.Monitor), 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 UpdateEditorContext(IShape model, IContent content, IUpdateModel updater, string groupInfoId, IShapeFactory shapeFactory, ShapeTable shapeTable)
     : base(model, content, groupInfoId, shapeFactory)
 {
     ShapeTable = shapeTable;
     Updater = updater;
 }
        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);

                _shapeTableMonitors.Invoke(ctx => ctx.Monitor(x.Monitor), Logger);

                Logger.Information("Done building shape table");
                return result;
            });
        }
        static 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()) {
                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 (; ; ) {
                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);
            }
        }