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

  1. //------------------------------------------------------------------------------
  2. // <copyright file="RootAction.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.Collections;
  21.     using System.Collections.Generic;
  22.     using System.Globalization;
  23.     using System.Xml;
  24.     using System.Xml.XPath;
  25.     using System.Xml.Xsl.Runtime;
  26.     using MS.Internal.Xml.XPath;
  27.     using System.Security;
  28.    
  29.     internal class Key
  30.     {
  31.         XmlQualifiedName name;
  32.         int matchKey;
  33.         int useKey;
  34.         ArrayList keyNodes;
  35.        
  36.         public Key(XmlQualifiedName name, int matchkey, int usekey)
  37.         {
  38.             this.name = name;
  39.             this.matchKey = matchkey;
  40.             this.useKey = usekey;
  41.             this.keyNodes = null;
  42.         }
  43.        
  44.         public XmlQualifiedName Name {
  45.             get { return this.name; }
  46.         }
  47.         public int MatchKey {
  48.             get { return this.matchKey; }
  49.         }
  50.         public int UseKey {
  51.             get { return this.useKey; }
  52.         }
  53.        
  54.         public void AddKey(XPathNavigator root, Hashtable table)
  55.         {
  56.             if (this.keyNodes == null) {
  57.                 this.keyNodes = new ArrayList();
  58.             }
  59.             this.keyNodes.Add(new DocumentKeyList(root, table));
  60.         }
  61.        
  62.         public Hashtable GetKeys(XPathNavigator root)
  63.         {
  64.             if (this.keyNodes != null) {
  65.                 for (int i = 0; i < keyNodes.Count; i++) {
  66.                     if (((DocumentKeyList)keyNodes[i]).RootNav.IsSamePosition(root)) {
  67.                         return ((DocumentKeyList)keyNodes[i]).KeyTable;
  68.                     }
  69.                 }
  70.             }
  71.             return null;
  72.         }
  73.        
  74.         public Key Clone()
  75.         {
  76.             return new Key(name, matchKey, useKey);
  77.         }
  78.     }
  79.    
  80.     internal struct DocumentKeyList
  81.     {
  82.         XPathNavigator rootNav;
  83.         Hashtable keyTable;
  84.        
  85.         public DocumentKeyList(XPathNavigator rootNav, Hashtable keyTable)
  86.         {
  87.             this.rootNav = rootNav;
  88.             this.keyTable = keyTable;
  89.         }
  90.        
  91.         public XPathNavigator RootNav {
  92.             get { return this.rootNav; }
  93.         }
  94.         public Hashtable KeyTable {
  95.             get { return this.keyTable; }
  96.         }
  97.     }
  98.    
  99.     internal class RootAction : TemplateBaseAction
  100.     {
  101.         private const int QueryInitialized = 2;
  102.         private const int RootProcessed = 3;
  103.        
  104.         private Hashtable attributeSetTable = new Hashtable();
  105.         private Hashtable decimalFormatTable = new Hashtable();
  106.         private List<Key> keyList;
  107.         private XsltOutput output;
  108.         public Stylesheet builtInSheet;
  109.         public PermissionSet permissions;
  110.        
  111.         internal XsltOutput Output {
  112.             get {
  113.                 if (this.output == null) {
  114.                     this.output = new XsltOutput();
  115.                 }
  116.                 return this.output;
  117.             }
  118.         }
  119.        
  120. /*
  121.         * Compile
  122.         */       
  123.         internal override void Compile(Compiler compiler)
  124.         {
  125.                 /*inInclude*/            CompileDocument(compiler, false);
  126.         }
  127.        
  128.         internal void InsertKey(XmlQualifiedName name, int MatchKey, int UseKey)
  129.         {
  130.             if (this.keyList == null) {
  131.                 this.keyList = new List<Key>();
  132.             }
  133.             this.keyList.Add(new Key(name, MatchKey, UseKey));
  134.         }
  135.        
  136.         internal AttributeSetAction GetAttributeSet(XmlQualifiedName name)
  137.         {
  138.             AttributeSetAction action = (AttributeSetAction)this.attributeSetTable[name];
  139.             if (action == null) {
  140.                 throw XsltException.Create(Res.Xslt_NoAttributeSet, name.ToString());
  141.             }
  142.             return action;
  143.         }
  144.        
  145.        
  146.         public void PorcessAttributeSets(Stylesheet rootStylesheet)
  147.         {
  148.             MirgeAttributeSets(rootStylesheet);
  149.            
  150.             // As we mentioned we need to invert all lists.
  151.             foreach (AttributeSetAction attSet in this.attributeSetTable.Values) {
  152.                 if (attSet.containedActions != null) {
  153.                     attSet.containedActions.Reverse();
  154.                 }
  155.             }
  156.            
  157.             // ensures there are no cycles in the attribute-sets use dfs marking method
  158.             CheckAttributeSets_RecurceInList(new Hashtable(), this.attributeSetTable.Keys);
  159.         }
  160.        
  161.         private void MirgeAttributeSets(Stylesheet stylesheet)
  162.         {
  163.             // mirge stylesheet.AttributeSetTable to this.AttributeSetTable
  164.            
  165.             if (stylesheet.AttributeSetTable != null) {
  166.                 foreach (AttributeSetAction srcAttSet in stylesheet.AttributeSetTable.Values) {
  167.                     ArrayList srcAttList = srcAttSet.containedActions;
  168.                     AttributeSetAction dstAttSet = (AttributeSetAction)this.attributeSetTable[srcAttSet.Name];
  169.                     if (dstAttSet == null) {
  170.                         dstAttSet = new AttributeSetAction();
  171.                         {
  172.                             dstAttSet.name = srcAttSet.Name;
  173.                             dstAttSet.containedActions = new ArrayList();
  174.                         }
  175.                         this.attributeSetTable[srcAttSet.Name] = dstAttSet;
  176.                     }
  177.                     ArrayList dstAttList = dstAttSet.containedActions;
  178.                     // We adding attributes in reverse order for purpuse. In the mirged list most importent attset shoud go last one
  179.                     // so we'll need to invert dstAttList finaly.
  180.                     if (srcAttList != null) {
  181.                         for (int src = srcAttList.Count - 1; 0 <= src; src--) {
  182.                             // We can ignore duplicate attibutes here.
  183.                             dstAttList.Add(srcAttList[src]);
  184.                         }
  185.                     }
  186.                 }
  187.             }
  188.            
  189.             foreach (Stylesheet importedStylesheet in stylesheet.Imports) {
  190.                 MirgeAttributeSets(importedStylesheet);
  191.             }
  192.         }
  193.        
  194.         private void CheckAttributeSets_RecurceInList(Hashtable markTable, ICollection setQNames)
  195.         {
  196.             const string PROCESSING = "P";
  197.             const string DONE = "D";
  198.            
  199.             foreach (XmlQualifiedName qname in setQNames) {
  200.                 object mark = markTable[qname];
  201.                 if (mark == (object)PROCESSING) {
  202.                     throw XsltException.Create(Res.Xslt_CircularAttributeSet, qname.ToString());
  203.                 }
  204.                 else if (mark == (object)DONE) {
  205.                     continue;
  206.                     // optimization: we already investigated this attribute-set.
  207.                 }
  208.                 else {
  209.                     Debug.Assert(mark == null);
  210.                    
  211.                     markTable[qname] = (object)PROCESSING;
  212.                     CheckAttributeSets_RecurceInContainer(markTable, GetAttributeSet(qname));
  213.                     markTable[qname] = (object)DONE;
  214.                 }
  215.             }
  216.         }
  217.        
  218.         private void CheckAttributeSets_RecurceInContainer(Hashtable markTable, ContainerAction container)
  219.         {
  220.             if (container.containedActions == null) {
  221.                 return;
  222.             }
  223.             foreach (Action action in container.containedActions) {
  224.                 if (action is UseAttributeSetsAction) {
  225.                     CheckAttributeSets_RecurceInList(markTable, ((UseAttributeSetsAction)action).UsedSets);
  226.                 }
  227.                 else if (action is ContainerAction) {
  228.                     CheckAttributeSets_RecurceInContainer(markTable, (ContainerAction)action);
  229.                 }
  230.             }
  231.         }
  232.        
  233.         internal void AddDecimalFormat(XmlQualifiedName name, DecimalFormat formatinfo)
  234.         {
  235.             DecimalFormat exist = (DecimalFormat)this.decimalFormatTable[name];
  236.             if (exist != null) {
  237.                 NumberFormatInfo info = exist.info;
  238.                 NumberFormatInfo newinfo = formatinfo.info;
  239.                 if (info.NumberDecimalSeparator != newinfo.NumberDecimalSeparator || info.NumberGroupSeparator != newinfo.NumberGroupSeparator || info.PositiveInfinitySymbol != newinfo.PositiveInfinitySymbol || info.NegativeSign != newinfo.NegativeSign || info.NaNSymbol != newinfo.NaNSymbol || info.PercentSymbol != newinfo.PercentSymbol || info.PerMilleSymbol != newinfo.PerMilleSymbol || exist.zeroDigit != formatinfo.zeroDigit || exist.digit != formatinfo.digit || exist.patternSeparator != formatinfo.patternSeparator) {
  240.                     throw XsltException.Create(Res.Xslt_DupDecimalFormat, name.ToString());
  241.                 }
  242.             }
  243.             this.decimalFormatTable[name] = formatinfo;
  244.         }
  245.        
  246.         internal DecimalFormat GetDecimalFormat(XmlQualifiedName name)
  247.         {
  248.             return this.decimalFormatTable[name] as DecimalFormat;
  249.         }
  250.        
  251.         internal List<Key> KeyList {
  252.             get { return this.keyList; }
  253.         }
  254.        
  255.         internal override void Execute(Processor processor, ActionFrame frame)
  256.         {
  257.             Debug.Assert(processor != null && frame != null);
  258.            
  259.             switch (frame.State) {
  260.                 case Initialized:
  261.                     frame.AllocateVariables(variableCount);
  262.                     XPathNavigator root = processor.Document.Clone();
  263.                     root.MoveToRoot();
  264.                     frame.InitNodeSet(new XPathSingletonIterator(root));
  265.                    
  266.                     if (this.containedActions != null && this.containedActions.Count > 0) {
  267.                         processor.PushActionFrame(frame);
  268.                     }
  269.                     frame.State = QueryInitialized;
  270.                     break;
  271.                 case QueryInitialized:
  272.                     Debug.Assert(frame.State == QueryInitialized);
  273.                     frame.NextNode(processor);
  274.                     Debug.Assert(Processor.IsRoot(frame.Node));
  275.                     if (processor.Debugger != null) {
  276.                         // this is like apply-templates, but we don't have it on stack.
  277.                         // Pop the stack, otherwise last instruction will be on it.
  278.                         processor.PopDebuggerStack();
  279.                     }
  280.                         /*mode:*/                        /*importsOf:*/                    processor.PushTemplateLookup(frame.NodeSet, null, null);
  281.                    
  282.                     frame.State = RootProcessed;
  283.                     break;
  284.                 case RootProcessed:
  285.                    
  286.                     Debug.Assert(frame.State == RootProcessed);
  287.                     frame.Finished();
  288.                     break;
  289.                 default:
  290.                     Debug.Fail("Invalid RootAction execution state");
  291.                     break;
  292.             }
  293.         }
  294.     }
  295. }

Developer Fusion