SaveComponent.cs :  » Development » Sandcastle » Microsoft » Ddue » Tools » C# / CSharp Open Source

Home
C# / CSharp Open Source
1.2.6.4 mono .net core
2.2.6.4 mono core
3.Aspect Oriented Frameworks
4.Bloggers
5.Build Systems
6.Business Application
7.Charting Reporting Tools
8.Chat Servers
9.Code Coverage Tools
10.Content Management Systems CMS
11.CRM ERP
12.Database
13.Development
14.Email
15.Forum
16.Game
17.GIS
18.GUI
19.IDEs
20.Installers Generators
21.Inversion of Control Dependency Injection
22.Issue Tracking
23.Logging Tools
24.Message
25.Mobile
26.Network Clients
27.Network Servers
28.Office
29.PDF
30.Persistence Frameworks
31.Portals
32.Profilers
33.Project Management
34.RSS RDF
35.Rule Engines
36.Script
37.Search Engines
38.Sound Audio
39.Source Control
40.SQL Clients
41.Template Engines
42.Testing
43.UML
44.Web Frameworks
45.Web Service
46.Web Testing
47.Wiki Engines
48.Windows Presentation Foundation
49.Workflows
50.XML Parsers
C# / C Sharp
C# / C Sharp by API
C# / CSharp Tutorial
C# / CSharp Open Source » Development » Sandcastle 
Sandcastle » Microsoft » Ddue » Tools » SaveComponent.cs
// Copyright  Microsoft Corporation.
// This source file is subject to the Microsoft Permissive License.
// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
// All other rights reserved.

using System;
using System.Configuration;
using System.Text;
using System.Xml;
using System.Xml.XPath;

using System.IO;

namespace Microsoft.Ddue.Tools{

  public class SaveComponent : BuildComponent {

    private CustomContext context = new CustomContext();

    private XPathExpression path_expression;

        private XPathExpression select_expression;

    private XmlWriterSettings settings = new XmlWriterSettings();

    public SaveComponent (BuildAssembler assembler, XPathNavigator configuration) : base(assembler, configuration) {

      // load the target path format
      XPathNavigator save_node = configuration.SelectSingleNode("save");
      if (save_node == null) throw new ConfigurationErrorsException("When instantiating a save component, you must specify a the target file using the <save> element.");

      string base_value = save_node.GetAttribute("base", String.Empty);
      if (!String.IsNullOrEmpty(base_value)) {
        basePath = Path.GetFullPath(Environment.ExpandEnvironmentVariables(base_value));
      }

      string path_value = save_node.GetAttribute("path", String.Empty);
      if (String.IsNullOrEmpty(path_value)) WriteMessage(MessageLevel.Error, "Each save element must have a path attribute specifying an XPath that evaluates to the location to save the file.");
      path_expression = XPathExpression.Compile(path_value);

            string select_value = save_node.GetAttribute("select", String.Empty);
            if (!String.IsNullOrEmpty(select_value))
                select_expression = XPathExpression.Compile(select_value);

            settings.Encoding = Encoding.UTF8;

      string indent_value = save_node.GetAttribute("indent", String.Empty);
      if (!String.IsNullOrEmpty(indent_value)) settings.Indent = Convert.ToBoolean(indent_value);

      string omit_value = save_node.GetAttribute("omit-xml-declaration", String.Empty);
      if (!String.IsNullOrEmpty(omit_value)) settings.OmitXmlDeclaration = Convert.ToBoolean(omit_value);

            linkPath = save_node.GetAttribute("link", String.Empty);
            if (String.IsNullOrEmpty(linkPath)) linkPath = "../html";

      // encoding

      settings.CloseOutput = true;

    }

    private string basePath = null;

        private string linkPath = null;

    public override void Apply (XmlDocument document, string key) {

      // set the evaluation context
      context["key"] = key;

      XPathExpression path_xpath = path_expression.Clone();
      path_xpath.SetContext(context);

      // evaluate the path
      string path = document.CreateNavigator().Evaluate(path_xpath).ToString();
            string file = Path.GetFileName(path);
            
            string fileLinkPath = Path.Combine(linkPath, file);
            if (basePath != null) path = Path.Combine(basePath, path);
                       

            // *SECURIY* The path name may be derived from user entered meta data in Doc Studio and as such 
            // it is not trustworthy. To pass, the path must be inside the directory tree base_directory 
            // (which is the current directory if a path is not specified).

            // This test is causing problems
            /*
            string absoluteBasePath = (basePath == null) ? Directory.GetCurrentDirectory() : Path.GetFullPath(basePath);
            string targetPath = Path.GetDirectoryName(path);
            if (!targetPath.StartsWith(absoluteBasePath, StringComparison.CurrentCultureIgnoreCase)) {
                WriteMessage(MessageLevel.Error, string.Format("Cannot save document outside of base directory: {0}", targetPath));
                return;
            }
            */
            string targetDirectory = Path.GetDirectoryName(path);
            if (!Directory.Exists(targetDirectory)) Directory.CreateDirectory(targetDirectory);

            // save the document
            // select_expression determines which nodes get saved. If there is no select_expression
            // we simply save the root node as before. If there is a select_expression, we evaluate the
            // xpath expression and save the resulting node set. The select expression also enables the 
            // "literal-text" processing instruction, which outputs its content as unescaped text.
            if (select_expression == null) {
                XmlNode doctype = document.DocumentType;
                try {
                    //Console.WriteLine("path = '{0}'", path);
                    //document.Save(path);

                    using (XmlWriter writer = XmlWriter.Create(path, settings)) {
                        document.Save(writer);
                    }

                } catch (IOException e) {
                    WriteMessage(MessageLevel.Error, String.Format("An access error occured while attempting to save to the file '{0}'. The error message is: {1}", path, BuildComponentUtilities.GetExceptionMessage(e)));
                } catch (XmlException e) {
                    WriteMessage(MessageLevel.Error, String.Format("Invalid XML was written to the output file '{0}'. The error message is: '{1}'", path, BuildComponentUtilities.GetExceptionMessage(e)));
                }

                // Get the relative html path for HXF generation.
                int index = fileLinkPath.IndexOf('/');
                string htmlPath = fileLinkPath.Substring(index + 1, fileLinkPath.Length - (index + 1));
                
                FileCreatedEventArgs fe = new FileCreatedEventArgs(htmlPath, Path.GetDirectoryName(targetDirectory));
                OnComponentEvent(fe);
            }
            else {
                // IMPLEMENTATION NOTE: The separate StreamWriter is used to maintain XML indenting.
                // Without it the XmlWriter won't honor our indent settings after plain text nodes have been
                // written.
                settings.ConformanceLevel = ConformanceLevel.Auto;
                using (StreamWriter output = File.CreateText(path)) {
                    using (XmlWriter writer = XmlWriter.Create(output, settings)) {
                        XPathExpression select_xpath = select_expression.Clone();
                        select_xpath.SetContext(context);
                        XPathNodeIterator ni = document.CreateNavigator().Select(select_expression);
                        while (ni.MoveNext()) {
                            if (ni.Current.NodeType == XPathNodeType.ProcessingInstruction && ni.Current.Name.Equals("literal-text")) {
                                writer.Flush();
                                output.Write(ni.Current.Value);
                            }
                            else
                                ni.Current.WriteSubtree(writer);
                        }
                    }
                }
            }
    }
  }
}
www.java2v.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.