Beispiel #1
0
        protected Object ProcessInputStream(Stream template, string identifier, ProvisioningTemplate result)
        {
            if (template == null)
            {
                throw new ArgumentNullException(nameof(template));
            }

            // Crate a copy of the source stream
            MemoryStream sourceStream = new MemoryStream();

            template.CopyTo(sourceStream);
            sourceStream.Position = 0;

            // Check the provided template against the XML schema
            if (!this.IsValid(sourceStream))
            {
                // TODO: Use resource file
                throw new ApplicationException("The provided template is not valid!");
            }

            sourceStream.Position = 0;
            XDocument  xml = XDocument.Load(sourceStream);
            XNamespace pnp = this.NamespaceUri;

            // Prepare a variable to hold the single source formatted template
            TSchemaTemplate source = default(TSchemaTemplate);

            // Determine if we're working on a wrapped ProvisioningTemplate or not
            if (xml.Root.Name == pnp + "Provisioning")
            {
                // Deserialize the whole wrapper
                Object        wrapper       = null;
                var           wrapperType   = Type.GetType($"{PnPSerializationScope.Current?.BaseSchemaNamespace}.Provisioning, {PnPSerializationScope.Current?.BaseSchemaAssemblyName}", true);
                XmlSerializer xmlSerializer = new XmlSerializer(wrapperType);
                using (var reader = xml.Root.CreateReader())
                {
                    wrapper = xmlSerializer.Deserialize(reader);
                }

                // Handle the Parameters of the schema wrapper, if any
                var tps = new TemplateParametersSerializer();
                tps.Deserialize(wrapper, result);

                // Handle the Localizations of the schema wrapper, if any
                var ls = new LocalizationsSerializer();
                ls.Deserialize(wrapper, result);

                // Handle the Tenant-wide settings of the schema wrapper, if any
                var ts = new TenantSerializer();
                ts.Deserialize(wrapper, result);

                // Get the list of templates, if any, wrapped by the wrapper
                var wrapperTemplates = wrapperType.GetProperty("Templates",
                                                               System.Reflection.BindingFlags.Instance |
                                                               System.Reflection.BindingFlags.Public |
                                                               System.Reflection.BindingFlags.IgnoreCase).GetValue(wrapper);

                if (wrapperTemplates != null)
                {
                    // Search for the requested Provisioning Template
                    foreach (var templates in (IEnumerable)wrapperTemplates)
                    {
                        // Let's see if we have an in-place template with the provided ID or if we don't have a provided ID at all
                        var provisioningTemplates = templates.GetType()
                                                    .GetProperty("ProvisioningTemplate",
                                                                 System.Reflection.BindingFlags.Instance |
                                                                 System.Reflection.BindingFlags.Public |
                                                                 System.Reflection.BindingFlags.IgnoreCase).GetValue(templates);

                        if (provisioningTemplates != null)
                        {
                            foreach (var t in (IEnumerable)provisioningTemplates)
                            {
                                var templateId = (String)t.GetType().GetProperty("ID",
                                                                                 System.Reflection.BindingFlags.Instance |
                                                                                 System.Reflection.BindingFlags.Public |
                                                                                 System.Reflection.BindingFlags.IgnoreCase).GetValue(t);

                                if ((templateId != null && templateId == identifier) || String.IsNullOrEmpty(identifier))
                                {
                                    source = (TSchemaTemplate)t;
                                }
                            }

                            if (source == null)
                            {
                                var provisioningTemplateFiles = templates.GetType()
                                                                .GetProperty("ProvisioningTemplateFile",
                                                                             System.Reflection.BindingFlags.Instance |
                                                                             System.Reflection.BindingFlags.Public |
                                                                             System.Reflection.BindingFlags.IgnoreCase).GetValue(templates);

                                // If we don't have a template, but there are external file references
                                if (source == null && provisioningTemplateFiles != null)
                                {
                                    foreach (var f in (IEnumerable)provisioningTemplateFiles)
                                    {
                                        var templateId = (String)f.GetType().GetProperty("ID",
                                                                                         System.Reflection.BindingFlags.Instance |
                                                                                         System.Reflection.BindingFlags.Public |
                                                                                         System.Reflection.BindingFlags.IgnoreCase).GetValue(f);

                                        if ((templateId != null && templateId == identifier) || String.IsNullOrEmpty(identifier))
                                        {
                                            // Let's see if we have an external file for the template
                                            var externalFile = (String)f.GetType().GetProperty("File",
                                                                                               System.Reflection.BindingFlags.Instance |
                                                                                               System.Reflection.BindingFlags.Public |
                                                                                               System.Reflection.BindingFlags.IgnoreCase).GetValue(f);

                                            Stream externalFileStream = this.Provider.Connector.GetFileStream(externalFile);
                                            xml = XDocument.Load(externalFileStream);

                                            if (xml.Root.Name != pnp + "ProvisioningTemplate")
                                            {
                                                throw new ApplicationException("Invalid external file format. Expected a ProvisioningTemplate file!");
                                            }
                                            else
                                            {
                                                source = XMLSerializer.Deserialize <TSchemaTemplate>(xml);
                                            }
                                        }
                                    }
                                }
                            }
                        }

                        if (source != null)
                        {
                            break;
                        }
                    }
                }
            }
            else if (xml.Root.Name == pnp + "ProvisioningTemplate")
            {
                var IdAttribute = xml.Root.Attribute("ID");

                // If there is a provided ID, and if it doesn't equal the current ID
                if (!String.IsNullOrEmpty(identifier) &&
                    IdAttribute != null &&
                    IdAttribute.Value != identifier)
                {
                    // TODO: Use resource file
                    throw new ApplicationException("The provided template identifier is not available!");
                }
                else
                {
                    source = XMLSerializer.Deserialize <TSchemaTemplate>(xml);
                }
            }

            return(source);
        }
Beispiel #2
0
        public ProvisioningHierarchy ToProvisioningHierarchy(Stream hierarchy)
        {
            // Create a copy of the source stream
            MemoryStream sourceStream = new MemoryStream();

            hierarchy.Position = 0;
            hierarchy.CopyTo(sourceStream);
            sourceStream.Position = 0;

            // Check the provided template against the XML schema
            if (!this.IsValid(sourceStream))
            {
                // TODO: Use resource file
                throw new ApplicationException("The provided provisioning file is not valid!");
            }

            // Prepare the output variable
            ProvisioningHierarchy resultHierarchy = new ProvisioningHierarchy();

            // Determine if the file is a provisioning hierarchy
            sourceStream.Position = 0;
            XDocument xml = XDocument.Load(sourceStream);

            if (xml.Root.Name.LocalName != "Provisioning")
            {
                throw new ApplicationException("The provided provisioning file is not a Hierarchy!");
            }

            // Determine the specific formatter needed for the current provisioning file
            var innerFormatter = XMLPnPSchemaFormatter.GetSpecificFormatter(
                xml.Root.Name.NamespaceName);

            // Process all the provisioning templates included in the hierarchy, if any
            XmlNamespaceManager nsManager = new XmlNamespaceManager(new System.Xml.NameTable());

            nsManager.AddNamespace("pnp", xml.Root.Name.NamespaceName);

            // Start with templates embedded in the provisioning file
            var templates = xml.XPathSelectElements("/pnp:Provisioning/pnp:Templates/pnp:ProvisioningTemplate", nsManager).ToList();

            foreach (var template in templates)
            {
                // Save the single template into a MemoryStream
                MemoryStream templateStream = new MemoryStream();
                template.Save(templateStream);
                templateStream.Position = 0;

                // Process the single template with the classic technique
                var provisioningTemplate = innerFormatter.ToProvisioningTemplate(templateStream);

                // Add the generated template to the resulting hierarchy
                resultHierarchy.Templates.Add(provisioningTemplate);
            }

            // Then process any external file reference
            var templateFiles = xml.XPathSelectElements("/pnp:Provisioning/pnp:Templates/pnp:ProvisioningTemplateFile", nsManager).ToList();

            foreach (var template in templateFiles)
            {
                var templateID   = template.Attribute("ID")?.Value;
                var templateFile = template.Attribute("File")?.Value;
                if (!String.IsNullOrEmpty(templateFile) && !String.IsNullOrEmpty(templateID))
                {
                    // Process the single template file with the classic technique
                    var provisioningTemplate = this._provider.GetTemplate(templateFile);
                    provisioningTemplate.Id = templateID;

                    // Add the generated template to the resulting hierarchy
                    resultHierarchy.Templates.Add(provisioningTemplate);
                }
            }

            // And now process the top level children elements
            // using schema specific serializers

            using (var scope = new PnPSerializationScope(typeof(TSchemaTemplate)))
            {
                // We prepare a dummy template to leverage the existing serialization infrastructure
                var dummyTemplate = new ProvisioningTemplate();
                dummyTemplate.Id = $"DUMMY-{Guid.NewGuid()}";
                resultHierarchy.Templates.Add(dummyTemplate);

                // Deserialize the whole wrapper
                Object        wrapper       = null;
                var           wrapperType   = Type.GetType($"{PnPSerializationScope.Current?.BaseSchemaNamespace}.Provisioning, {PnPSerializationScope.Current?.BaseSchemaAssemblyName}", true);
                XmlSerializer xmlSerializer = new XmlSerializer(wrapperType);
                using (var reader = xml.Root.CreateReader())
                {
                    wrapper = xmlSerializer.Deserialize(reader);
                }

                // Handle the Parameters of the schema wrapper, if any
                var tps = new TemplateParametersSerializer();
                tps.Deserialize(wrapper, dummyTemplate);

                // Handle the Localizations of the schema wrapper, if any
                var ls = new LocalizationsSerializer();
                ls.Deserialize(wrapper, dummyTemplate);

                // Handle the Tenant-wide settings of the schema wrapper, if any
                var ts = new TenantSerializer();
                ts.Deserialize(wrapper, dummyTemplate);

                // Handle the Sequences
                var ss = new SequenceSerializer();
                ss.Deserialize(wrapper, dummyTemplate);

                // Handle the Provisioning Hierarchy properties
                var phs = new ProvisioningHierarchySerializer();
                phs.Deserialize(wrapper, dummyTemplate);

                // Remove the dummy template from the hierarchy
                resultHierarchy.Templates.Remove(dummyTemplate);
            }

            return(resultHierarchy);
        }