The Labs \ Source Viewer \ SSCLI \ System.Xml.Xsl.XsltOld \ Stylesheet

  1. //------------------------------------------------------------------------------
  2. // <copyright file="Stylesheet.cs" company="Microsoft">
  3. //
  4. // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
  5. //
  6. // The use and distribution terms for this software are contained in the file
  7. // named license.txt, which can be found in the root of this distribution.
  8. // By using this software in any fashion, you are agreeing to be bound by the
  9. // terms of this license.
  10. //
  11. // You must not remove this notice, or any other, from this software.
  12. //
  13. // </copyright>
  14. //------------------------------------------------------------------------------
  15. namespace System.Xml.Xsl.XsltOld
  16. {
  17.     using Res = System.Xml.Utils.Res;
  18.     using System;
  19.     using System.Diagnostics;
  20.     using System.Xml;
  21.     using System.Xml.XPath;
  22.     using System.Collections;
  23.    
  24.     internal class Stylesheet
  25.     {
  26.         private ArrayList imports = new ArrayList();
  27.         private Hashtable modeManagers;
  28.         private Hashtable templateNameTable = new Hashtable();
  29.         private Hashtable attributeSetTable;
  30.         private int templateCount;
  31.         //private ArrayList preserveSpace;
  32.         private Hashtable queryKeyTable;
  33.         private ArrayList whitespaceList;
  34.         private bool whitespace;
  35.         private Hashtable scriptObjectTypes = new Hashtable();
  36.         private TemplateManager templates;
  37.        
  38.        
  39.         private class WhitespaceElement
  40.         {
  41.             private int key;
  42.             private double priority;
  43.             private bool preserveSpace;
  44.            
  45.             internal double Priority {
  46.                 get { return this.priority; }
  47.             }
  48.            
  49.             internal int Key {
  50.                 get { return this.key; }
  51.             }
  52.            
  53.             internal bool PreserveSpace {
  54.                 get { return this.preserveSpace; }
  55.             }
  56.            
  57.             internal WhitespaceElement(int Key, double priority, bool PreserveSpace)
  58.             {
  59.                 this.key = Key;
  60.                 this.priority = priority;
  61.                 this.preserveSpace = PreserveSpace;
  62.             }
  63.            
  64.             internal void ReplaceValue(bool PreserveSpace)
  65.             {
  66.                 this.preserveSpace = PreserveSpace;
  67.             }
  68.         }
  69.        
  70.         internal bool Whitespace {
  71.             get { return this.whitespace; }
  72.         }
  73.         internal ArrayList Imports {
  74.             get { return this.imports; }
  75.         }
  76.         internal Hashtable AttributeSetTable {
  77.             get { return this.attributeSetTable; }
  78.         }
  79.        
  80.         internal void AddSpace(Compiler compiler, string query, double Priority, bool PreserveSpace)
  81.         {
  82.             WhitespaceElement elem;
  83.             if (this.queryKeyTable != null) {
  84.                 if (this.queryKeyTable.Contains(query)) {
  85.                     elem = (WhitespaceElement)this.queryKeyTable[query];
  86.                     elem.ReplaceValue(PreserveSpace);
  87.                     return;
  88.                 }
  89.             }
  90.             else {
  91.                 this.queryKeyTable = new Hashtable();
  92.                 this.whitespaceList = new ArrayList();
  93.             }
  94.             int key = compiler.AddQuery(query);
  95.             elem = new WhitespaceElement(key, Priority, PreserveSpace);
  96.             this.queryKeyTable[query] = elem;
  97.             this.whitespaceList.Add(elem);
  98.         }
  99.        
  100.         internal void SortWhiteSpace()
  101.         {
  102.             if (this.queryKeyTable != null) {
  103.                 for (int i = 0; i < this.whitespaceList.Count; i++) {
  104.                     for (int j = this.whitespaceList.Count - 1; j > i; j--) {
  105.                         WhitespaceElement elem1;
  106.                         WhitespaceElement elem2;
  107.                         elem1 = (WhitespaceElement)this.whitespaceList[j - 1];
  108.                         elem2 = (WhitespaceElement)this.whitespaceList[j];
  109.                         if (elem2.Priority < elem1.Priority) {
  110.                             this.whitespaceList[j - 1] = elem2;
  111.                             this.whitespaceList[j] = elem1;
  112.                         }
  113.                     }
  114.                 }
  115.                 this.whitespace = true;
  116.             }
  117.             if (this.imports != null) {
  118.                 for (int importIndex = this.imports.Count - 1; importIndex >= 0; importIndex--) {
  119.                     Stylesheet stylesheet = (Stylesheet)this.imports[importIndex];
  120.                     if (stylesheet.Whitespace) {
  121.                         stylesheet.SortWhiteSpace();
  122.                         this.whitespace = true;
  123.                     }
  124.                 }
  125.             }
  126.         }
  127.        
  128.         internal bool PreserveWhiteSpace(Processor proc, XPathNavigator node)
  129.         {
  130.             // last one should win. I.E. We starting from the end. I.E. Lowest priority should go first
  131.             if (this.whitespaceList != null) {
  132.                 for (int i = this.whitespaceList.Count - 1; 0 <= i; i--) {
  133.                     WhitespaceElement elem = (WhitespaceElement)this.whitespaceList[i];
  134.                     if (proc.Matches(node, elem.Key)) {
  135.                         return elem.PreserveSpace;
  136.                     }
  137.                 }
  138.             }
  139.             if (this.imports != null) {
  140.                 for (int importIndex = this.imports.Count - 1; importIndex >= 0; importIndex--) {
  141.                     Stylesheet stylesheet = (Stylesheet)this.imports[importIndex];
  142.                     if (!stylesheet.PreserveWhiteSpace(proc, node))
  143.                         return false;
  144.                 }
  145.             }
  146.             return true;
  147.         }
  148.        
  149.         internal void AddAttributeSet(AttributeSetAction attributeSet)
  150.         {
  151.             Debug.Assert(attributeSet.Name != null);
  152.             if (this.attributeSetTable == null) {
  153.                 this.attributeSetTable = new Hashtable();
  154.             }
  155.             Debug.Assert(this.attributeSetTable != null);
  156.            
  157.             if (this.attributeSetTable.ContainsKey(attributeSet.Name) == false) {
  158.                 this.attributeSetTable[attributeSet.Name] = attributeSet;
  159.             }
  160.             else {
  161.                 // merge the attribute-sets
  162.                 ((AttributeSetAction)this.attributeSetTable[attributeSet.Name]).Merge(attributeSet);
  163.             }
  164.         }
  165.        
  166.         internal void AddTemplate(TemplateAction template)
  167.         {
  168.             XmlQualifiedName mode = template.Mode;
  169.            
  170.             //
  171.             // Ensure template has a unique name
  172.             //
  173.            
  174.             Debug.Assert(this.templateNameTable != null);
  175.            
  176.             if (template.Name != null) {
  177.                 if (this.templateNameTable.ContainsKey(template.Name) == false) {
  178.                     this.templateNameTable[template.Name] = template;
  179.                 }
  180.                 else {
  181.                     throw XsltException.Create(Res.Xslt_DupTemplateName, template.Name.ToString());
  182.                 }
  183.             }
  184.            
  185.            
  186.             if (template.MatchKey != Compiler.InvalidQueryKey) {
  187.                 if (this.modeManagers == null) {
  188.                     this.modeManagers = new Hashtable();
  189.                 }
  190.                 Debug.Assert(this.modeManagers != null);
  191.                
  192.                 if (mode == null) {
  193.                     mode = XmlQualifiedName.Empty;
  194.                 }
  195.                
  196.                 TemplateManager manager = (TemplateManager)this.modeManagers[mode];
  197.                
  198.                 if (manager == null) {
  199.                     manager = new TemplateManager(this, mode);
  200.                    
  201.                     this.modeManagers[mode] = manager;
  202.                    
  203.                     if (mode.IsEmpty) {
  204.                         Debug.Assert(this.templates == null);
  205.                         this.templates = manager;
  206.                     }
  207.                 }
  208.                 Debug.Assert(manager != null);
  209.                
  210.                 template.TemplateId = ++this.templateCount;
  211.                 manager.AddTemplate(template);
  212.             }
  213.         }
  214.        
  215.         internal void ProcessTemplates()
  216.         {
  217.             if (this.modeManagers != null) {
  218.                 IDictionaryEnumerator enumerator = this.modeManagers.GetEnumerator();
  219.                 while (enumerator.MoveNext()) {
  220.                     Debug.Assert(enumerator.Value is TemplateManager);
  221.                     TemplateManager manager = (TemplateManager)enumerator.Value;
  222.                     manager.ProcessTemplates();
  223.                 }
  224.             }
  225.            
  226.             if (this.imports != null) {
  227.                 for (int importIndex = this.imports.Count - 1; importIndex >= 0; importIndex--) {
  228.                     Debug.Assert(this.imports[importIndex] is Stylesheet);
  229.                     Stylesheet stylesheet = (Stylesheet)this.imports[importIndex];
  230.                     Debug.Assert(stylesheet != null);
  231.                    
  232.                     //
  233.                     // Process templates in imported stylesheet
  234.                     //
  235.                    
  236.                     stylesheet.ProcessTemplates();
  237.                 }
  238.             }
  239.         }
  240.        
  241.        
  242.         internal void ReplaceNamespaceAlias(Compiler compiler)
  243.         {
  244.             if (this.modeManagers != null) {
  245.                 IDictionaryEnumerator enumerator = this.modeManagers.GetEnumerator();
  246.                 while (enumerator.MoveNext()) {
  247.                     TemplateManager manager = (TemplateManager)enumerator.Value;
  248.                     if (manager.templates != null) {
  249.                         for (int i = 0; i < manager.templates.Count; i++) {
  250.                             TemplateAction template = (TemplateAction)manager.templates[i];
  251.                             template.ReplaceNamespaceAlias(compiler);
  252.                         }
  253.                     }
  254.                 }
  255.             }
  256.             if (this.templateNameTable != null) {
  257.                 IDictionaryEnumerator enumerator = this.templateNameTable.GetEnumerator();
  258.                 while (enumerator.MoveNext()) {
  259.                     TemplateAction template = (TemplateAction)enumerator.Value;
  260.                     template.ReplaceNamespaceAlias(compiler);
  261.                 }
  262.             }
  263.             if (this.imports != null) {
  264.                 for (int importIndex = this.imports.Count - 1; importIndex >= 0; importIndex--) {
  265.                     Stylesheet stylesheet = (Stylesheet)this.imports[importIndex];
  266.                     stylesheet.ReplaceNamespaceAlias(compiler);
  267.                 }
  268.             }
  269.         }
  270.        
  271.         internal TemplateAction FindTemplate(Processor processor, XPathNavigator navigator, XmlQualifiedName mode)
  272.         {
  273.             Debug.Assert(processor != null && navigator != null);
  274.             Debug.Assert(mode != null);
  275.             TemplateAction action = null;
  276.            
  277.             //
  278.             // Try to find template within this stylesheet first
  279.             //
  280.             if (this.modeManagers != null) {
  281.                 TemplateManager manager = (TemplateManager)this.modeManagers[mode];
  282.                
  283.                 if (manager != null) {
  284.                     Debug.Assert(manager.Mode.Equals(mode));
  285.                     action = manager.FindTemplate(processor, navigator);
  286.                 }
  287.             }
  288.            
  289.             //
  290.             // If unsuccessful, search in imported documents from backwards
  291.             //
  292.            
  293.             if (action == null) {
  294.                 action = FindTemplateImports(processor, navigator, mode);
  295.             }
  296.            
  297.             return action;
  298.         }
  299.        
  300.         internal TemplateAction FindTemplateImports(Processor processor, XPathNavigator navigator, XmlQualifiedName mode)
  301.         {
  302.             TemplateAction action = null;
  303.            
  304.             //
  305.             // Do we have imported stylesheets?
  306.             //
  307.            
  308.             if (this.imports != null) {
  309.                 for (int importIndex = this.imports.Count - 1; importIndex >= 0; importIndex--) {
  310.                     Debug.Assert(this.imports[importIndex] is Stylesheet);
  311.                     Stylesheet stylesheet = (Stylesheet)this.imports[importIndex];
  312.                     Debug.Assert(stylesheet != null);
  313.                    
  314.                     //
  315.                     // Search in imported stylesheet
  316.                     //
  317.                    
  318.                     action = stylesheet.FindTemplate(processor, navigator, mode);
  319.                    
  320.                     if (action != null) {
  321.                         return action;
  322.                     }
  323.                 }
  324.             }
  325.            
  326.             return action;
  327.         }
  328.        
  329.         internal TemplateAction FindTemplate(Processor processor, XPathNavigator navigator)
  330.         {
  331.             Debug.Assert(processor != null && navigator != null);
  332.             Debug.Assert(this.templates == null && this.modeManagers == null || this.templates == this.modeManagers[XmlQualifiedName.Empty]);
  333.            
  334.             TemplateAction action = null;
  335.            
  336.             //
  337.             // Try to find template within this stylesheet first
  338.             //
  339.            
  340.             if (this.templates != null) {
  341.                 action = this.templates.FindTemplate(processor, navigator);
  342.             }
  343.            
  344.             //
  345.             // If unsuccessful, search in imported documents from backwards
  346.             //
  347.            
  348.             if (action == null) {
  349.                 action = FindTemplateImports(processor, navigator);
  350.             }
  351.            
  352.             return action;
  353.         }
  354.        
  355.         internal TemplateAction FindTemplate(XmlQualifiedName name)
  356.         {
  357.             //Debug.Assert(this.templateNameTable == null);
  358.            
  359.             TemplateAction action = null;
  360.            
  361.             //
  362.             // Try to find template within this stylesheet first
  363.             //
  364.            
  365.             if (this.templateNameTable != null) {
  366.                 action = (TemplateAction)this.templateNameTable[name];
  367.             }
  368.            
  369.             //
  370.             // If unsuccessful, search in imported documents from backwards
  371.             //
  372.            
  373.             if (action == null && this.imports != null) {
  374.                 for (int importIndex = this.imports.Count - 1; importIndex >= 0; importIndex--) {
  375.                     Debug.Assert(this.imports[importIndex] is Stylesheet);
  376.                     Stylesheet stylesheet = (Stylesheet)this.imports[importIndex];
  377.                     Debug.Assert(stylesheet != null);
  378.                    
  379.                     //
  380.                     // Search in imported stylesheet
  381.                     //
  382.                    
  383.                     action = stylesheet.FindTemplate(name);
  384.                    
  385.                     if (action != null) {
  386.                         return action;
  387.                     }
  388.                 }
  389.             }
  390.            
  391.             return action;
  392.         }
  393.        
  394.         internal TemplateAction FindTemplateImports(Processor processor, XPathNavigator navigator)
  395.         {
  396.             TemplateAction action = null;
  397.            
  398.             //
  399.             // Do we have imported stylesheets?
  400.             //
  401.            
  402.             if (this.imports != null) {
  403.                 for (int importIndex = this.imports.Count - 1; importIndex >= 0; importIndex--) {
  404.                     Debug.Assert(this.imports[importIndex] is Stylesheet);
  405.                     Stylesheet stylesheet = (Stylesheet)this.imports[importIndex];
  406.                     Debug.Assert(stylesheet != null);
  407.                    
  408.                     //
  409.                     // Search in imported stylesheet
  410.                     //
  411.                    
  412.                     action = stylesheet.FindTemplate(processor, navigator);
  413.                    
  414.                     if (action != null) {
  415.                         return action;
  416.                     }
  417.                 }
  418.             }
  419.            
  420.             return action;
  421.         }
  422.        
  423.         internal Hashtable ScriptObjectTypes {
  424.             get { return this.scriptObjectTypes; }
  425.         }
  426.     }
  427. }

Developer Fusion