예제 #1
0
        public PnPSerializationScope(Type schemaTemplateType)
        {
            // Save the scope information
            this._baseSchemaNamespace    = schemaTemplateType.Namespace;
            this._baseSchemaAssemblyName = schemaTemplateType.Assembly.FullName;

            // Save the previous scope, if any
            this._previous = Current;

            // Set the new scope to this
            Current = this;
        }
예제 #2
0
        public ProvisioningTemplate ToProvisioningTemplate(Stream template, string identifier)
        {
            using (var scope = new PnPSerializationScope(typeof(TSchemaTemplate)))
            {
                // Prepare a variable to hold the resulting ProvisioningTemplate instance
                var result = new ProvisioningTemplate();

                // Prepare a variable to hold the single source formatted template
                var source = ProcessInputStream(template, identifier, result);

                DeserializeTemplate(source, result);

                return(result);
            }
        }
        /// <summary>
        /// Serializes an in-memory ProvisioningTemplate into a Stream (the XML)
        /// </summary>
        /// <param name="template">The ProvisioningTemplate to serialize</param>
        /// <returns>The resulting Stream (the XML)</returns>
        public Stream ToFormattedTemplate(ProvisioningTemplate template)
        {
            if (template == null)
            {
                throw new ArgumentNullException(nameof(template));
            }

            using (var scope = new PnPSerializationScope(typeof(TSchemaTemplate)))
            {
                var    result = new TSchemaTemplate();
                Stream output = null;

                // Process the template to generate the output stream
                output = ProcessOutputStream(template, result);

                return(output);
            }
        }
        /// <summary>
        /// Deserializes a Stream of bytes (the XML) into a Provisioning Template, based on an optional identifier
        /// </summary>
        /// <param name="template">The source Stream of bytes (the XML)</param>
        /// <param name="identifier">An optional identifier for the template to deserialize</param>
        /// <returns>The deserialized Provisioning Template</returns>
        public ProvisioningTemplate ToProvisioningTemplate(Stream template, string identifier)
        {
            using (var scope = new PnPSerializationScope(typeof(TSchemaTemplate)))
            {
                // Prepare a variable to hold the resulting ProvisioningTemplate instance
                var result = new ProvisioningTemplate();

                // Prepare a variable to hold the single source formatted template
                // We provide the result instance of ProvisioningTemplate in order
                // to configure the tenant/hierarchy level items
                // We get back the XML-based object to use with the other serializers
                var source = ProcessInputStream(template, identifier, result);

                // We process the chain of deserialization
                // with the Provisioning-level serializers
                DeserializeTemplate(source, result);

                return(result);
            }
        }
        /// <summary>
        /// Deserializes a source Stream (the XML) into a ProvisioningHierarchy
        /// </summary>
        /// <param name="hierarchy">The source Stream (the XML)</param>
        /// <returns>The resulting ProvisioningHierarchy object</returns>
        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);
                }

                #region Process Provisioning level serializers

                // Get all serializers to run in automated mode, ordered by DeserializationSequence
                var serializers = GetSerializersForCurrentContext(SerializerScope.Provisioning, a => a?.DeserializationSequence);

                // Invoke all the serializers
                InvokeSerializers(dummyTemplate, wrapper, serializers, SerializationAction.Deserialize);

                #endregion

                #region Process Tenant level serializers

                // Get all serializers to run in automated mode, ordered by DeserializationSequence
                serializers = GetSerializersForCurrentContext(SerializerScope.Tenant, a => a?.DeserializationSequence);

                // Invoke all the serializers
                InvokeSerializers(dummyTemplate, wrapper, serializers, SerializationAction.Deserialize);

                #endregion

                #region Process ProvisioningHierarchy level serializers

                // Get all serializers to run in automated mode, ordered by DeserializationSequence
                serializers = GetSerializersForCurrentContext(SerializerScope.ProvisioningHierarchy, a => a?.DeserializationSequence);

                // Invoke all the serializers
                InvokeSerializers(dummyTemplate, wrapper, serializers, SerializationAction.Deserialize);

                #endregion

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

            return(resultHierarchy);
        }
        /// <summary>
        /// Serializes a ProvisioningHierarchy into a Stream (the XML)
        /// </summary>
        /// <param name="hierarchy">The ProvisioningHierarchy to serialize</param>
        /// <returns>The resulting Stream (the XML)</returns>
        public Stream ToFormattedHierarchy(ProvisioningHierarchy hierarchy)
        {
            if (hierarchy == null)
            {
                throw new ArgumentNullException(nameof(hierarchy));
            }

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

                // Prepare the output wrapper
                Type   wrapperType;
                object wrapper, templatesItem;
                Array  templates;

                ProcessOutputHierarchy(dummyTemplate, out wrapperType, out wrapper, out templates, out templatesItem);

                // Handle the Sequences, if any
                // Get all ProvisioningHierarchy-level serializers to run in automated mode, ordered by SerializationSequence
                var serializers = GetSerializersForCurrentContext(SerializerScope.ProvisioningHierarchy, a => a?.SerializationSequence);

                // Invoke all the ProvisioningHierarchy-level serializers
                InvokeSerializers(dummyTemplate, wrapper, serializers, SerializationAction.Serialize);

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

                // Add every single template to the output
                var provisioningTemplates = Array.CreateInstance(typeof(TSchemaTemplate), hierarchy.Templates.Count);
                for (int c = 0; c < hierarchy.Templates.Count; c++)
                {
                    // Prepare variable to hold the output template
                    var outputTemplate = new TSchemaTemplate();

                    // Serialize the real templates
                    SerializeTemplate(hierarchy.Templates[c], outputTemplate);

                    // Add the serialized template to the output
                    provisioningTemplates.SetValue(outputTemplate, c);
                }

                templatesItem.SetPublicInstancePropertyValue("ProvisioningTemplate", provisioningTemplates);

                templates.SetValue(templatesItem, 0);

                wrapper.SetPublicInstancePropertyValue("Templates", templates);

                // Serialize the XML-based object into a Stream
                XmlSerializerNamespaces ns =
                    new XmlSerializerNamespaces();
                ns.Add(((IXMLSchemaFormatter)this).NamespacePrefix,
                       ((IXMLSchemaFormatter)this).NamespaceUri);

                MemoryStream  output        = new MemoryStream();
                XmlSerializer xmlSerializer = new XmlSerializer(wrapperType);
                if (ns != null)
                {
                    xmlSerializer.Serialize(output, wrapper, ns);
                }
                else
                {
                    xmlSerializer.Serialize(output, wrapper);
                }

                // Re-base the Stream and return it
                output.Position = 0;
                return(output);
            }
        }
예제 #7
0
        public Stream ToFormattedTemplate(ProvisioningTemplate template)
        {
            if (template == null)
            {
                throw new ArgumentNullException(nameof(template));
            }

            using (var scope = new PnPSerializationScope(typeof(TSchemaTemplate)))
            {
                var result = new TSchemaTemplate();

                // Create the wrapper
                var    wrapperType = Type.GetType($"{PnPSerializationScope.Current?.BaseSchemaNamespace}.Provisioning, {PnPSerializationScope.Current?.BaseSchemaAssemblyName}", true);
                Object wrapper     = Activator.CreateInstance(wrapperType);

                // Create the Preferences
                var    preferencesType = Type.GetType($"{PnPSerializationScope.Current?.BaseSchemaNamespace}.Preferences, {PnPSerializationScope.Current?.BaseSchemaAssemblyName}", true);
                Object preferences     = Activator.CreateInstance(preferencesType);

                wrapper.GetType().GetProperty("Preferences",
                                              System.Reflection.BindingFlags.Instance |
                                              System.Reflection.BindingFlags.Public |
                                              System.Reflection.BindingFlags.IgnoreCase).SetValue(wrapper, preferences);

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

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

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

                // Configure the Generator
                preferences.GetType().GetProperty("Generator",
                                                  System.Reflection.BindingFlags.Instance |
                                                  System.Reflection.BindingFlags.Public |
                                                  System.Reflection.BindingFlags.IgnoreCase).SetValue(preferences, this.GetType().Assembly.FullName);

                // Configure the output Template
                var templatesType = Type.GetType($"{PnPSerializationScope.Current?.BaseSchemaNamespace}.Templates, {PnPSerializationScope.Current?.BaseSchemaAssemblyName}", true);
                var templates     = Array.CreateInstance(templatesType, 1);
                var templatesItem = Activator.CreateInstance(templatesType);

                templatesItem.GetType().GetProperty("ID",
                                                    System.Reflection.BindingFlags.Instance |
                                                    System.Reflection.BindingFlags.Public |
                                                    System.Reflection.BindingFlags.IgnoreCase).SetValue(templatesItem, $"CONTAINER-{template.Id}");

                var provisioningTemplates = Array.CreateInstance(typeof(TSchemaTemplate), 1);
                provisioningTemplates.SetValue(result, 0);

                templatesItem.GetType().GetProperty("ProvisioningTemplate",
                                                    System.Reflection.BindingFlags.Instance |
                                                    System.Reflection.BindingFlags.Public |
                                                    System.Reflection.BindingFlags.IgnoreCase).SetValue(templatesItem, provisioningTemplates);

                templates.SetValue(templatesItem, 0);

                wrapperType.GetProperty("Templates",
                                        System.Reflection.BindingFlags.Instance |
                                        System.Reflection.BindingFlags.Public |
                                        System.Reflection.BindingFlags.IgnoreCase).SetValue(wrapper, templates);

                SerializeTemplate(template, result);

                XmlSerializerNamespaces ns =
                    new XmlSerializerNamespaces();
                ns.Add(((IXMLSchemaFormatter)this).NamespacePrefix,
                       ((IXMLSchemaFormatter)this).NamespaceUri);

                MemoryStream  output        = new MemoryStream();
                XmlSerializer xmlSerializer = new XmlSerializer(wrapperType);
                if (ns != null)
                {
                    xmlSerializer.Serialize(output, wrapper, ns);
                }
                else
                {
                    xmlSerializer.Serialize(output, wrapper);
                }

                output.Position = 0;
                return(output);
            }
        }
예제 #8
0
        public Stream ToFormattedHierarchy(ProvisioningHierarchy hierarchy)
        {
            if (hierarchy == null)
            {
                throw new ArgumentNullException(nameof(hierarchy));
            }

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

                // Prepare the output wrapper
                Type   wrapperType;
                object wrapper, templatesItem;
                Array  templates;

                ProcessOutputHierarchy(dummyTemplate, out wrapperType, out wrapper, out templates, out templatesItem);

                // Handle the Sequences, if any
                var ts = new SequenceSerializer();
                ts.Serialize(dummyTemplate, wrapper);

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

                // Add every single template to the output
                var provisioningTemplates = Array.CreateInstance(typeof(TSchemaTemplate), hierarchy.Templates.Count);
                for (int c = 0; c < hierarchy.Templates.Count; c++)
                {
                    // Prepare variable to hold the output template
                    var outputTemplate = new TSchemaTemplate();

                    // Serialize the real templates
                    SerializeTemplate(hierarchy.Templates[c], outputTemplate);

                    // Add the serialized template to the output
                    provisioningTemplates.SetValue(outputTemplate, c);
                }

                templatesItem.GetType().GetProperty("ProvisioningTemplate",
                                                    System.Reflection.BindingFlags.Instance |
                                                    System.Reflection.BindingFlags.Public |
                                                    System.Reflection.BindingFlags.IgnoreCase).SetValue(templatesItem, provisioningTemplates);

                templates.SetValue(templatesItem, 0);

                wrapperType.GetProperty("Templates",
                                        System.Reflection.BindingFlags.Instance |
                                        System.Reflection.BindingFlags.Public |
                                        System.Reflection.BindingFlags.IgnoreCase).SetValue(wrapper, templates);

                XmlSerializerNamespaces ns =
                    new XmlSerializerNamespaces();
                ns.Add(((IXMLSchemaFormatter)this).NamespacePrefix,
                       ((IXMLSchemaFormatter)this).NamespaceUri);

                MemoryStream  output        = new MemoryStream();
                XmlSerializer xmlSerializer = new XmlSerializer(wrapperType);
                if (ns != null)
                {
                    xmlSerializer.Serialize(output, wrapper, ns);
                }
                else
                {
                    xmlSerializer.Serialize(output, wrapper);
                }

                output.Position = 0;
                return(output);
            }
        }