private static void LoadTemplateFiles(ErrorContainer errors, CanvasDocument app, string packagesPath, out Dictionary <string, ControlTemplate> loadedTemplates)
        {
            loadedTemplates = new Dictionary <string, ControlTemplate>();
            var templateList = new List <TemplatesJson.TemplateJson>();

            foreach (var file in new DirectoryReader(packagesPath).EnumerateFiles(string.Empty, "*.xml", searchSubdirectories: false))
            {
                var xmlContents = file.GetContents();
                if (!ControlTemplateParser.TryParseTemplate(new TemplateStore(), xmlContents, app._properties.DocumentAppType, loadedTemplates, out var parsedTemplate, out var templateName))
                {
                    errors.GenericError($"Unable to parse template file {file._relativeName}");
                    throw new DocumentException();
                }
                // Some control templates specify a name with an initial capital letter (e.g. rating control)
                // However, the server doesn't always use that. If the template name doesn't match the one we wrote
                // as the file name, adjust the template name to lowercase
                if (!file._relativeName.StartsWith(templateName))
                {
                    templateName = templateName.ToLower();
                }

                templateList.Add(new TemplatesJson.TemplateJson()
                {
                    Name = templateName, Template = xmlContents, Version = parsedTemplate.Version
                });
            }

            // Also add Screen and App templates (not xml, constructed in code on the server)
            GlobalTemplates.AddCodeOnlyTemplates(new TemplateStore(), loadedTemplates, app._properties.DocumentAppType);

            app._templates = new TemplatesJson()
            {
                UsedTemplates = templateList.ToArray()
            };
        }
Example #2
0
        internal void ApplyAfterMsAppLoadTransforms(ErrorContainer errors)
        {
            // Update volatile documentproperties
            _entropy.SetProperties(_properties);

            // Shard templates, parse for default values
            var templateDefaults = new Dictionary <string, ControlTemplate>();

            foreach (var template in _templates.UsedTemplates)
            {
                if (!ControlTemplateParser.TryParseTemplate(_templateStore, template.Template, _properties.DocumentAppType, templateDefaults, out _, out _))
                {
                    errors.GenericError($"Unable to parse template file {template.Name}");
                    throw new DocumentException();
                }
            }

            // Also add Screen and App templates (not xml, constructed in code on the server)
            GlobalTemplates.AddCodeOnlyTemplates(_templateStore, templateDefaults, _properties.DocumentAppType);

            // PCF templates
            if (_pcfControls.Count == 0)
            {
                foreach (var kvp in _templateStore.Contents)
                {
                    if (kvp.Value.IsPcfControl && kvp.Value.DynamicControlDefinitionJson != null)
                    {
                        _pcfControls.Add(kvp.Key, PcfControl.GetPowerAppsControlFromJson(kvp.Value));
                        kvp.Value.DynamicControlDefinitionJson = null;
                    }
                }
            }

            var componentInstanceTransform = new ComponentInstanceTransform(errors);
            var componentDefTransform      = new ComponentDefinitionTransform(errors, _templateStore, componentInstanceTransform);

            // Transform component definitions and populate template set of component instances that need updates
            foreach (var ctrl in _components)
            {
                AddComponentDefaults(ctrl.Value, templateDefaults);
                componentDefTransform.AfterRead(ctrl.Value);
            }

            var transformer = new SourceTransformer(this, errors, templateDefaults, new Theme(_themes), componentInstanceTransform, _editorStateStore, _templateStore, _entropy);

            foreach (var ctrl in _screens.Concat(_components))
            {
                transformer.ApplyAfterRead(ctrl.Value);
            }

            StabilizeAssetFilePaths(errors);

            // Persist the original order of resource entries in Resources.json in the entropy.
            this.PersistOrderingOfResourcesJsonEntries();
        }
Example #3
0
        internal void ApplyBeforeMsAppWriteTransforms(ErrorContainer errors)
        {
            // Update volatile documentproperties
            _entropy.GetProperties(_properties);

            // Shard templates, parse for default values
            var templateDefaults = new Dictionary <string, ControlTemplate>();

            foreach (var template in _templates.UsedTemplates)
            {
                if (!ControlTemplateParser.TryParseTemplate(_templateStore, template.Template, _properties.DocumentAppType, templateDefaults, out _, out _))
                {
                    errors.GenericError($"Unable to parse template file {template.Name}");
                    throw new DocumentException();
                }
            }

            // Also add Screen and App templates (not xml, constructed in code on the server)
            GlobalTemplates.AddCodeOnlyTemplates(_templateStore, templateDefaults, _properties.DocumentAppType);

            // Generate DynamicControlDefinitionJson for power apps controls
            foreach (var kvp in _pcfControls)
            {
                if (_templateStore.TryGetTemplate(kvp.Key, out var template))
                {
                    template.DynamicControlDefinitionJson = PcfControl.GenerateDynamicControlDefinition(kvp.Value);
                }
                else
                {
                    // Validation for accidental deletion of ocf control templates.
                    errors.ValidationError($"Could not find Pcf Control Template with name: {kvp.Key} in pkgs/PcfControlTemplates directory. " +
                                           $"If it was intentionally deleted, please delete the entry from ControlTemplates.json along with its references from source files.");
                }
            }

            var componentInstanceTransform = new ComponentInstanceTransform(errors);
            var componentDefTransform      = new ComponentDefinitionTransform(errors, _templateStore, componentInstanceTransform);

            // Transform component definitions and populate template set of component instances that need updates
            foreach (var ctrl in _components)
            {
                componentDefTransform.BeforeWrite(ctrl.Value);
                AddComponentDefaults(ctrl.Value, templateDefaults);
            }

            var transformer = new SourceTransformer(this, errors, templateDefaults, new Theme(_themes), componentInstanceTransform, _editorStateStore, _templateStore, _entropy);

            foreach (var ctrl in _screens.Concat(_components))
            {
                transformer.ApplyBeforeWrite(ctrl.Value);
            }

            RestoreAssetFilePaths();
        }
Example #4
0
 private static ControlInfoJson.Item GetDataComponentDefinition(IEnumerable <ControlInfoJson> topParents, string templateGuid, ErrorContainer errors)
 {
     foreach (var topParent in topParents)
     {
         if (topParent.TopParent.Template.Name == templateGuid)
         {
             return(topParent.TopParent);
         }
     }
     errors.GenericError("Could not find DataComponent Definition for template " + templateGuid);
     throw new DocumentException();
 }
        internal void ApplyBeforeMsAppWriteTransforms(ErrorContainer errors)
        {
            // Update volatile documentproperties
            _entropy.GetProperties(_properties);

            // Shard templates, parse for default values
            var templateDefaults = new Dictionary <string, ControlTemplate>();

            foreach (var template in _templates.UsedTemplates)
            {
                if (!ControlTemplateParser.TryParseTemplate(_templateStore, template.Template, _properties.DocumentAppType, templateDefaults, out _, out _))
                {
                    errors.GenericError($"Unable to parse template file {template.Name}");
                    throw new DocumentException();
                }
            }

            // Also add Screen and App templates (not xml, constructed in code on the server)
            GlobalTemplates.AddCodeOnlyTemplates(_templateStore, templateDefaults, _properties.DocumentAppType);

            var componentInstanceTransform = new ComponentInstanceTransform(errors);
            var componentDefTransform      = new ComponentDefinitionTransform(errors, _templateStore, componentInstanceTransform);

            // Transform component definitions and populate template set of component instances that need updates
            foreach (var ctrl in _components)
            {
                componentDefTransform.BeforeWrite(ctrl.Value);
                AddComponentDefaults(ctrl.Value, templateDefaults);
            }

            var transformer = new SourceTransformer(errors, templateDefaults, new Theme(_themes), componentInstanceTransform, _editorStateStore, _templateStore, _entropy);

            foreach (var ctrl in _screens.Concat(_components))
            {
                transformer.ApplyBeforeWrite(ctrl.Value);
            }

            RestoreAssetFilePaths();
        }