public override void SaveAs(ProvisioningTemplate template, string uri, ITemplateFormatter formatter, ITemplateProviderExtension[] extensions)
        {
            if (template == null)
            {
                throw new ArgumentNullException(nameof(template));
            }

            if (String.IsNullOrEmpty(uri))
            {
                throw new ArgumentException("uri");
            }

            if (formatter == null)
            {
                formatter = new XMLPnPSchemaFormatter();
            }

            SaveToConnector(template, uri, formatter, extensions);
        }
        public override ProvisioningHierarchy GetHierarchy(string uri)
        {
            if (uri == null)
            {
                throw new ArgumentNullException(nameof(uri));
            }

            ProvisioningHierarchy result = null;

            var stream = this.Connector.GetFileStream(uri);

            if (stream != null)
            {
                var formatter = new XMLPnPSchemaFormatter();

                ITemplateFormatter specificFormatter = formatter.GetSpecificFormatterInternal(ref stream);
                specificFormatter.Initialize(this);
                result = ((IProvisioningHierarchyFormatter)specificFormatter).ToProvisioningHierarchy(stream);
            }

            return(result);
        }
        public ProvisioningHierarchy GetHierarchy()
        {
            ProvisioningHierarchy result = null;

            var openXmlConnection = this.Connector as OpenXMLConnector;
            var fileName          = openXmlConnection.Info.Properties.TemplateFileName;

            if (!String.IsNullOrEmpty(fileName))
            {
                var stream = this.Connector.GetFileStream(fileName);

                if (stream != null)
                {
                    var formatter = new XMLPnPSchemaFormatter();

                    ITemplateFormatter specificFormatter = formatter.GetSpecificFormatterInternal(ref stream);
                    specificFormatter.Initialize(this);
                    result = ((IProvisioningHierarchyFormatter)specificFormatter).ToProvisioningHierarchy(stream);
                }
            }
            return(result);
        }
        public override ProvisioningTemplate GetTemplate(string uri, string identifier, ITemplateFormatter formatter, ITemplateProviderExtension[] extensions = null)
        {
            if (String.IsNullOrEmpty(uri))
            {
                throw new ArgumentException("uri");
            }

            if (formatter == null)
            {
                formatter = new XMLPnPSchemaFormatter();
                formatter.Initialize(this);
            }

            // Get the XML document from a File Stream
            Stream stream = this.Connector.GetFileStream(uri);

            if (stream == null)
            {
                throw new ApplicationException(string.Format(CoreResources.Provisioning_Formatter_Invalid_Template_URI, uri));
            }

            // Handle any pre-processing extension
            stream = PreProcessGetTemplateExtensions(extensions, stream);

            //Resolve xml includes if any
            stream = ResolveXIncludes(stream);

            // And convert it into a ProvisioningTemplate
            ProvisioningTemplate provisioningTemplate = formatter.ToProvisioningTemplate(stream, identifier);

            // Handle any post-processing extension
            provisioningTemplate = PostProcessGetTemplateExtensions(extensions, provisioningTemplate);

            // Store the identifier of this template, is needed for latter save operation
            this.Uri = uri;

            return(provisioningTemplate);
        }
        /// <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
            var validationResult = this.GetValidationResults(sourceStream);

            if (!validationResult.IsValid)
            {
                // TODO: Use resource file
                throw new ApplicationException("Template is not valid", new AggregateException(validationResult.Exceptions));
            }

            // 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
                {
                    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);
        }